Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dockerize existing Django project

I can't wrap my head around how to dockerize existing Django app. I've read this official manual by Docker explaining how to create Django project during the creation of Docker image, but what I need is to dockerize existing project using the same method.

The main purpose of this approach is that I have no need to build docker images locally all the time, instead what I want to achieve is to push my code to a remote repository which has docker-hub watcher attached to it and as soon as the code base is updated it's being built automatically on the server.

For now my Dockerfile looks like:

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install Django
RUN pip install djangorestframework
RUN pip install PyQRCode
ADD . /code/

Can anyone please explain how should I compose Dockerfile and do I need to use docker-compose.yml (if yes: how?) to achieve functionality I've described?

Solution for this question:

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
RUN pip install *name of package*
RUN pip install *name of another package*
ADD . /code/
EXPOSE 8000
CMD python3 manage.py runserver 0.0.0.0:8000

OR

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
EXPOSE 8000
CMD python3 manage.py runserver 0.0.0.0:8000

requirements.txt should be a plain list of packages, for example:

Django==1.11
djangorestframework
pyqrcode
pypng
like image 249
Stan Redoute Avatar asked Nov 13 '17 17:11

Stan Redoute


3 Answers

This question is too broad. What happens with the Dockerfile you've created?

You don't need docker compose unless you have multiple containers that need to interact.

Some general observations from your current Dockerfile:

  • It would be better to collapse the pip install commands into a single statement. In docker, each statement creates a file system layer, and the layers in between the pip install commmands probably serve no useful purpose.
  • It's better to declare dependencies in setup.py or a requirements.txt file (pip install -r requirements.txt), with fixed version numbers (foopackage==0.0.1) to ensure a repeatable build.
  • I'd recommend packaging your Django app into a python package and installing it with pip (cd /code/; pip install .) rather than directly adding the code directory.
  • You're missing a statement (CMD or ENTRYPOINT) to execute the app. See https://docs.docker.com/engine/reference/builder/#cmd
like image 99
Alex Forbes Avatar answered Nov 01 '22 13:11

Alex Forbes


Warning: -onbuild images have been deprecated.

@AlexForbes raised very good points. But if you want a super simple Dockerfile for Django, you can probably just do:

FROM python:3-onbuild
RUN python manage.py collectstatic
CMD ["python", "manage.py"]

You then run your container with:

docker run myimagename runserver

The little -onbuild modifier does most of what you need. It creates /usr/src/app, sets it as the working directory, copies all your source code inside, and runs pip install -r requirements.txt (which you forgot to run). Finally we collect statics (might not be required in your case if statics are hosted somewhere), and set the default command to manage.py so everything is easy to run.

You would need docker-compose if you had to run other containers like Celery, Redis or any other background task or server not supplied by your environment.

like image 21
kichik Avatar answered Nov 01 '22 12:11

kichik


I actually wrote an article about this in https://rehalcon.blogspot.mx/2018/03/dockerize-your-django-app-for-local.html

My case is very similar, but it adds a MySQL db service and environment variables for code secrets, as well as the use of docker-compose (needed in macOS). I also use the python:2.7-slim docker parten image instead, to make the image much maller (under 150MB).

like image 33
Jorge Orpinel Pérez Avatar answered Nov 01 '22 12:11

Jorge Orpinel Pérez