Aquí está mi docker-compose.yml , contiene un servicio web, que monta una carpeta localmente para que, ante cualquier cambio de código, watchmedo reinicie el servidor django de la aplicación webapp . Es un proxy inverso con 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:La configuración de mi archivo local es como:
$ tree -L 2 . ├── docker-compose.yml ├── nginx │ ├── Dockerfile │ └── nginx.conf └── web ├── Dockerfile ├── manage.py ├── myapp ├── public └── static Pero cuando creo un nuevo archivo en web/public (la misma carpeta montada como un volumen compartido entre la webapp y los servicios nginx ), no lo veo desde dentro del contenedor de la webapp en ejecución.
Sin embargo, si creo un nuevo archivo en cualquier otro lugar de la carpeta web/ (que también está montado como un volumen separado), veo el cambio desde dentro del contenedor de la aplicación webapp en ejecución.
¿Qué está causando esto? ¿Y cómo cambio este comportamiento?
(Necesito poder ejecutar python manage.py collectstatic desde dentro del contenedor en ejecución, pero enviarlo a la web/public de mi disco duro local para poder crear las imágenes de Docker de producción para implementar).
No puedo ver un problema con lo que tienes aquí. Copié su docker-compose.yml y eliminé solo el punto de entrypoint: parte de él y funcionó para mí.
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/nullnginx/Dockerfile
FROM nginx:latest CMD tail -f /dev/nullManifestación:
Para profundizar en el comentario anterior de DannyB, asegúrese de no crear el archivo en el host en web/public , ya que esta carpeta se monta cuando se inician los contenedores. Un volumen docker funciona de manera similar a un montaje estándar de Linux: docker simplemente montará el nuevo volumen sobre la parte superior del directorio existente.
Si desea ejecutar un comando dentro de un contenedor Docker que cambia archivos en su sistema de archivos host, no use un volumen docker; en su lugar, use un montaje de enlace como lo ha hecho aquí: - ./web/:/usr/src/app/ .
La diferencia entre un montaje de enlace y un volumen docker es que un montaje de enlace montará archivos desde su host dentro de su contenedor, y dependerá de que esas carpetas/archivos estén en su sistema de archivos host, y un volumen docker será completamente administrado por docker y solo se puede compartir entre contenedores, no con el host también (aunque estos archivos viven en algún lugar del host, no es práctico rastrearlos e intentar usarlos).
En realidad, puede eliminar el volumen de su docker de su archivo docker-compose y agregar un montaje de enlace para nginx y comenzará a ver el comportamiento que está buscando:
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/publicManifestación:
Le ha dicho a Docker que staticfile_volume contiene datos críticos de la aplicación que deben conservarse en todas las ejecuciones del contenedor. La primera vez que se inicia el contenedor, y solo la primera vez, Docker lo completará a partir de la imagen. Si actualiza la imagen más tarde, dado que el volumen contiene datos críticos de la aplicación, Docker no la cambiará.
La solución a corto plazo más fácil es eliminar el volumen. Prueba docker-compose down -v; docker-compose up --build . Deberá hacer esto cada vez que cambie el contenido estático.
Sería un poco más fácil a largo plazo configurar la aplicación de back-end para servir sus propios archivos. Django tiene un módulodjango.contrib.staticfiles para hacer esto. Luego, su proxy nginx puede redirigir incondicionalmente al contenedor back-end, y no tiene que preocuparse por el problema de compartir archivos.
(Para ver esto mejor, tome la receta de reproducción de @ChrisMcKinnel y ejecútela una vez. Luego tome web/Dockerfile desde allí y COPY un archivo en /usr/src/app/public y vuelva a ejecutar docker-compose up --build . no verá aparecer el archivo a menos que docker-compose down -v ).