Volume changes not persistent after “docker-compos

2019-05-10 07:57发布

问题:

I have a Django environment that I create with Docker Compose, and I'm trying to use manage.py collectstatic to copy my site's static files to a directory in the container. This directory (/usr/src/app/static) is also a Docker Volume.

After building my docker containers (docker-compose build), I run docker-compose run web python manage.py collectstatic, which works as expected, but my web server (Nginx) is not finding the files, nor are there any files when I run docker-compose run web ls -la /usr/src/app/static.

Any ideas on what I'm doing wrong?

(Note: I don't have manage.py collectstatic in my Dockerfile because my setup needs my ".env" file loaded, and I didn't see a way to load this in the Dockerfile. In either case, I would like to know why Docker Compose doesn't work as I'm expecting it to.)

Here are my config files:

## docker-compose.yml:
web:
  restart: always
  build: .
  expose:
    - "8000"
  links:
    - postgres:postgres
  volumes:
    - /usr/src/app/static
    - .:/code
  env_file: .env
  command: /usr/local/bin/gunicorn myapp.wsgi:application -w 2 -b :8000 --reload

nginx:
  restart: always
  build: ./config/nginx
  ports:
    - "80:80"
  volumes:
    - /www/static
  volumes_from:
    - web
  links:
    - web:web

postgres:
  restart: always
  image: postgres:latest
  volumes:
    - /var/lib/postgresql
  ports:
    - "5432:5432"


## Dockerfile:
FROM python:3.4.3
RUN mkdir /code
WORKDIR /code
ADD . /requirements/ /code/requirements/
RUN pip install -r /code/requirements/docker.txt
ADD . /code/

回答1:

Running docker-compose run ... starts a new container and executes the command in there. then when you run docker-compose up it creates ANOTHER new container... which doesn't have the changes from your previous command.

What you want to do is start up a data container to hold your static files. Add another container to your compose file like this...

web-static:
  build: .
  volumes:
    - /usr/src/app/static
  env_file: .env
  command: manage.py collectstatic

and add web-static to the 'volumes-from' list on your nginx container



回答2:

There are a couple of other ways to do this in addition to Paul Becotte's method:

A. With the release of docker-compose v 1.6 (not available at the time of Paul's answer) you can now use docker-compose file version 2 for specifying volumes

version: '2'
volumes:
  django-static:
    driver: local

django:
  ...
  volumes:
    - django-static:/usr/src/app/static

then you can collect static files in a separate container and they will persist

docker-compose run django ./manage.py collectstatic

Using this method should involve less system overhead then Pauls' method because you are running one less container.

B. Slight hack - you can collect static files in the container command

django:
  command: bash -c "./manage.py collectstatic --noinput;
  /usr/local/bin/gunicorn myapp.wsgi:application -w 2 -b :8000 --reload"

Downside of this is that it's inflexible if you are calling a different command from docker-compose command line then collectstatic will not get run. Also you are running collectstatic files at times when you probably don't need to.