Почему мой том docker-compose не обновляется с добавлением локальных файлов? - PullRequest
2 голосов
/ 02 июня 2019

Вот мой docker-compose.yml, он содержит веб-сервис, который монтирует папку локально, так что при любом изменении кода watchmedo перезапускает сервер webapp django.Это обратный прокси с nginx.

version: '3'
services:
  webapp:
    build:
      context: .
      dockerfile: ./web/Dockerfile
    volumes:
      - ./web/:/usr/src/app/
      - staticfile_volume:/usr/src/app/public
    entrypoint: >
      watchmedo auto-restart --recursive 
        --pattern="*.py" --directory="." 
          gunicorn myapp.wsgi:application -- --bind 0.0.0.0:9000
  nginx:
    build:
      context: .
      dockerfile: ./nginx/Dockerfile
    depends_on:
      - webapp
    volumes:
      - staticfile_volume:/usr/src/app/public
volumes:
  staticfile_volume:

Моя локальная настройка файла выглядит следующим образом:

$ tree -L 2
.
├── docker-compose.yml
├── nginx
│   ├── Dockerfile
│   └── nginx.conf
└── web
   ├── Dockerfile
   ├── manage.py
   ├── myapp
   ├── public
   └── static

Но когда я создаю новый файл в web/public (та же папка, смонтированная как общий том между webapp иnginx сервисы), я не вижу его внутри работающего контейнера webapp.

Тем не менее, если я создаю новый файл где-нибудь еще в папке web/ (которая также монтируется как отдельный том), я вижу изменения внутри работающего контейнера webapp.

Что вызывает это?И как мне изменить это поведение?

(мне нужно иметь возможность запускать python manage.py collectstatic изнутри работающего контейнера, но выводить на web/public моего локального жесткого диска, чтобы я мог создавать производственные образы Docker для развертывания.)

Ответы [ 2 ]

1 голос
/ 02 июня 2019

Вы сказали Docker, что staticfile_volume содержит критические данные приложения, которые должны быть сохранены при каждом запуске контейнера.При первом запуске контейнера и только при первом запуске Docker заполняет его из образа.Если вы обновите образ позже, так как том содержит важные данные приложения, Docker не изменит его.

Самый простой краткосрочный обходной путь - удалить том.Попробуйте docker-compose down -v; docker-compose up --build.Это необходимо делать всякий раз, когда вы изменяете статический контент.

В долгосрочной перспективе было бы немного проще настроить внутреннее приложение для обслуживания его собственных файлов.Для этого в Django есть модуль django.contrib.staticfiles.Тогда ваш прокси-сервер nginx может безоговорочно перенаправить в бэкэнд-контейнер, и вам не нужно беспокоиться о проблеме с совместным доступом к файлам.

(Чтобы увидеть это лучше, возьмите рецепт воспроизведения @ ChrisMcKinnel и запустите его один раз. Затем выполнитеweb/Dockerfile оттуда и COPY файл в /usr/src/app/public и повторный запуск docker-compose up --build. Файл не появится, если вы не docker-compose down -v.)

1 голос
/ 02 июня 2019

Я не вижу проблемы с тем, что у вас здесь.Я скопировал ваш docker-compose.yml и удалил только часть entrypoint:, и он работал для меня.

docker-compose.yml

version: '3'
services:
  webapp:
    build:
      context: .
      dockerfile: ./web/Dockerfile
    volumes:
      - ./web/:/usr/src/app/
      - staticfile_volume:/usr/src/app/public
  nginx:
    build:
      context: .
      dockerfile: ./nginx/Dockerfile
    depends_on:
      - webapp
    volumes:
      - staticfile_volume:/usr/src/app/public
volumes:
  staticfile_volume:

web / Dockerfile

FROM ubuntu:18.04

CMD tail -f /dev/null

nginx / Dockerfile

FROM nginx:latest

CMD tail -f /dev/null

Демонстрация:

docker-volumes

Чтобы пояснить комментарий DannyB выше, убедитесь, что вы не создаете файл на хосте в web/public, так как эта папка монтируется при запуске контейнеров.Том Docker работает аналогично стандартному монтированию Linux - Docker просто монтирует новый том поверх существующего каталога.

Если вы хотите запустить команду внутри контейнера Docker, который изменяет файлы нафайловая система вашего хоста, не используйте док-том - вместо этого используйте bind mount , как вы сделали здесь: - ./web/:/usr/src/app/.

Разница между bind mount и том докера - это то, что устройство bind монтирует файлы с вашего хоста внутри вашего контейнера и будет полагаться на те папки / файлы, которые находятся в вашей файловой системе хоста, а том докера будет полностью управлятьсяdocker и может использоваться совместно только контейнерами, но не хостом (хотя эти файлы где-то живут на хосте, их нецелесообразно отследить и попытаться использовать).

Вы можете простоудалите том докера из вашего docker-compose файла и добавьте привязку для nginx, и вы начнете видеть поведение, которое вы 'после:

docker-compose.yml

version: '3'
services:
  webapp:
    build:
      context: .
      dockerfile: ./web/Dockerfile
    volumes:
      - ./web/:/usr/src/app/
  nginx:
    build:
      context: .
      dockerfile: ./nginx/Dockerfile
    depends_on:
      - webapp
    volumes:
      - ./web/public:/usr/src/app/public

Демо:

enter image description here

...