Search code examples
pythondjangodockeramazon-elastic-beanstalk

Run migrations on Dockerfile deploying on Elastic Beanstalk


I have a problems making migrations (Django App 4.0.6) on Elastic beanstalk.

This is my Dockerfile:

FROM python:3.8

ENV PROJECT_DIR=/usr/src/app/
 
ENV PYTHONIOENCODING=utf-8
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PIPENV_USE_SYSTEM=1

WORKDIR ${PROJECT_DIR}

COPY .  ./

RUN pip install -r requirements.txt

EXPOSE 8000
    
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Until here, all works well, but if I try to add RUN python manage.py migrate before to EXPOSE 8000 and make the deploy, I have an 504 error.

I tried to add .ebextensions and config file like this:

container_commands:
  01_migrate:
    command: "source /var/app/venv/*/bin/activate && python3 manage.py migrate"
    leader_only: true

But I don't sure how to activate my env in a Docker, I have an error when I try to make the deploy

2022-08-01 03:10:23,328 P28507 [INFO] Command 01_migrate
2022-08-01 03:10:23,331 P28507 [INFO] -----------------------Command Output-----------------------
2022-08-01 03:10:23,331 P28507 [INFO]   /bin/sh: /var/app/venv/*/bin/activate: No such file or directory
2022-08-01 03:10:23,331 P28507 [INFO] ------------------------------------------------------------
2022-08-01 03:10:23,331 P28507 [ERROR] Exited with error code 1

¿What is the best solution for my case?

Thanks for your help! :)


Solution

  • If you are not using docker compose to deploy, then you can add an entrypoint file and run your migrations and the server command there.

    # Dockerfile
    
    ...
    
    RUN pip install -r requirements.txt
    
    EXPOSE 8000
        
    ENTRYPOINT ["bin/production-entrypoint.sh"]
    

    where your bin/production-entrypoint.sh file looks something like:

    #!/bin/bash
    
    source /var/app/venv/*/bin/activate
    python3 manage.py migrate
    python manage.py runserver 0.0.0.0:8000
    

    Or, if you are using docker compose to deploy, then you can run the commands in the docker-compose.yml file:

    # Dockerfile
    
    ...
    
    RUN pip install -r requirements.txt
    
    EXPOSE 8000
    
    # docker-compose.yml
    
    version: "3"
    
    services:
      web:
        build: .
        ports:
          - "8000:8000"
        env_file:
          - .env
        volumes:
          - /var/app/current:/usr/src/app
        command: >
          bash -c "source /var/app/venv/*/bin/activate
          && python3 manage.py migrate
          && python manage.py runserver 0.0.0.0:8000"
    
    ...