Search code examples
pythondjangodockerdocker-composedjango-migrations

Missing Environment Vars in docker python:3 with docker-compose


Though my configuration looks good, my python:3 image does not seem to have the expected DJANGO_SECRET_KEY set, at least at the point that the Dockerfile attempts to run migrations

$ docker-compose config
services:
  api:
    build:
      context: /Users/ben/Projects/falcon/falcon-backend
      dockerfile: Dockerfile
    depends_on:
    - db
    - redis
    environment:
      DJANGO_SECRET_KEY: 'some-secret-that-works-elsewhere'
$
$ docker-compose up --build api
[...]
 Step 6/7 : RUN echo `$DJANGO_SECRET_KEY`
 ---> Running in fbfb569c0191

[...]
django.core.exceptions.ImproperlyConfigured: Set the DJANGO_SECRET_KEY env variable
ERROR: Service 'api' failed to build: The command '/bin/sh -c python manage.py migrate' returned a non-zero code: 1

however, the final line, CMD python manage.py runserver 0.0.0.0:8001 --settings=falcon.settings.dev-microservice does start up as desired, with the necessary env vars set.

# Dockerfile -- api

FROM python:3

RUN pip3 -q install -r requirements.txt
RUN echo `$DJANGO_SECRET_KEY`
RUN python manage.py migrate --settings=falcon.settings.dev-microservice # <-- why does this not work
CMD python manage.py runserver 0.0.0.0:8001 --settings=falcon.settings.dev-microservice

Why does the penultimate line of the Dockerfile fail due to an unset environment variable while the final one works as expected?


Solution

  • The RUN is used only when building image. The CMD is the command that is started when you start container from your image. If you run migrate when building image it is wrong, migrate is building your database and you want to run it each time before runserver

    # Dockerfile -- api
    
    FROM python:3
    
    RUN pip3 -q install -r requirements.txt
    RUN echo `$DJANGO_SECRET_KEY`
    CMD /bin/bash -c "python manage.py migrate --settings=falcon.settings.dev-microservice && python manage.py runserver 0.0.0.0:8001 --settings=falcon.settings.dev-microservice"
    

    This is the proper way how to start django in docker, because you want to run the migrations on production when starting server. Not on your PC when building image...