1

I'm very new to docker, am trying to use it with Django, here is my DockerFile :

FROM python:3.6

RUN mkdir /app
WORKDIR /app

ADD . /app/


ENV PYTHONUNBUFFERED 1
ENV LANG C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive


ENV PORT=8000


RUN apt-get update && apt-get install -y --no-install-recommends \
        tzdata \
        python3-setuptools \
        python3-pip \
        python3-dev \
        python3-venv \
        git \
        && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*




RUN pip3 install --upgrade pip
RUN pip3 install pipenv


RUN pip install -r requirements.txt && python manage.py migrate



EXPOSE 8888
CMD gunicorn g_attend.wsgi:application --bind 0.0.0.0:$PORT

it works normally but it never does the migrations, any help?

Note Pardon me if the question is a beginner question, it is my 1st time with docker and can't find clear documentation for Docker/Django

Ahmed Wagdi
  • 3,913
  • 10
  • 50
  • 116

2 Answers2

4

First of all you should not run migrations in your custom Dockerfile. A good practice is creating entrypoint.sh.

This is example entrypoint file:

#!/bin/bash

set -e

echo "${0}: running migrations."
python manage.py makemigrations --merge
python manage.py migrate --noinput

echo "${0}: collecting statics."

python manage.py collectstatic --noinput

cp -rv static/* static_shared/

gunicorn yourapp.wsgi:application \
    --env DJANGO_SETTINGS_MODULE=yourapp.production_settings \
    --name yourapp \
    --bind 0.0.0.0:8000 \
    --timeout 600 \
    --workers 4 \
    --log-level=info \
    --reload

Additionally I recommend using docker-compose, which helps to organize your deployment in one place.

Example:

version: '3'
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command:
      - /bin/sh
      - '-c'
      - '/code/entrypoint.sh'
    ports:
      - '8000:8000'
    volumes:
      - '.:/code'
      - 'media_volume:/media'

And example Dockerfile

FROM python:3.6.8

RUN apt-get update;

ENV PYTHONUNBUFFERED 1
RUN mkdir /code

ADD requirements.txt /code
ADD entrypoint.sh /code

WORKDIR /code

RUN chmod +x *.sh

RUN pip install --upgrade pip
RUN pip install -r requirements.txt
ADD . /code
sebb
  • 1,956
  • 1
  • 16
  • 28
  • it keeps giving me this error `/bin/sh: 1: /code/entrypoint.sh: not found` – Ahmed Wagdi Jan 02 '20 at 20:31
  • 1
    Did you update your Dockerfile ? Did you rebuild your docker image ? – sebb Jan 02 '20 at 20:34
  • Updated DockerFile, created docker-compose based on your answer, and ten trying to run `docker-compose up --build` – Ahmed Wagdi Jan 02 '20 at 20:35
  • 1
    Do you have your entrypoint.sh and Dockerfile in main app folder ? In the same folder as manage.py ? – sebb Jan 02 '20 at 20:43
  • I just didn't write the line `-'/code/entrypoint.sh'` as a string now it is over this part, and I have the error `standard_init_linux.go:211: exec user process caused "no such file or directory"` and I have no idea where it comes from. – Ahmed Wagdi Jan 02 '20 at 20:50
  • Hmm thats strange. Are you running on windows or linux ? – sebb Jan 02 '20 at 21:10
  • I found similar error https://stackoverflow.com/questions/51508150/standard-init-linux-go190-exec-user-process-caused-no-such-file-or-directory – sebb Jan 02 '20 at 21:11
  • 1
    The Dockerfile should end with `CMD ["/code/entrypoint.sh"]` so the image knows what to run by default; it shouldn't be an override in `docker-compose.yml` and doesn't need an `sh -c` wrapper. You should also avoid overwriting all of the code in the image (including the entrypoint script) with a `volumes:` bind mount if that's at all an option. – David Maze Jan 02 '20 at 23:24
  • "First of all you should not run migrations in your custom Dockerfile." Why? – AlxVallejo Aug 06 '20 at 13:21
  • Your Dockerfile is supposed to specify system dependencies, such as base docker image, files included, steps to execute etc. Then on this built image you can run three commands: RUN executes command(s) in a new layer and creates a new image. E.g., it is often used for installing software packages. CMD sets default command and/or parameters, which can be overwritten from command line when docker container runs. ENTRYPOINT configures a container that will run as an executable - migrations, collecting static, running gunicorn etc – sebb Aug 06 '20 at 13:27
-1

Based on @sebb answer, I've created a docker-compose.yml file but the entrypoint.sh didn't work as expected, after some searches, I've added the migration line to the docker-compose file, so here is how files looked at the end :

Dockerfile

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
COPY entrypoint.sh /code/
RUN pip install -r requirements.txt
COPY . /code/

docker-compose.yml

version: '3'

services:
  db:
    image: postgres
  web:
    build: .
    command: bash -c "python manage.py makemigrations && python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

And Finally, it worked.

Ahmed Wagdi
  • 3,913
  • 10
  • 50
  • 116
  • 1
    You should not do it like this. It's hard to manage. Additionally don't use `makemigrations` - you should have them already generated in your code before building. Additionally use gunicorn for production – sebb Jan 02 '20 at 21:21