Let's containerize the Django app.
Start by ensuring that you have Docker and Docker Compose:
$ docker -v Docker version 19.03.5, build 633a0ea $ docker-compose -v docker-compose version 1.24.1, build 4667896b
Make sure to install or upgrade them if necessary.
Add a Dockerfile to the "app" directory, making sure to review the code comments:
# pull official base image FROM python:3.8.1-alpine # set work directory WORKDIR /usr/src/app # set environment variables ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # install dependencies RUN pip install --upgrade pip COPY ./requirements.txt /usr/src/app/requirements.txt RUN pip install -r requirements.txt # copy project COPY . /usr/src/app/
Here, we used an Alpine-based, Python image to keep our final image slim. Alpine Linux is a lightweight Linux distro. It's a good practice to use Alpine-based images, whenever possible, as your base images in your Dockerfiles.
Benefits of using Alpine:
- Decreased hosting costs since less disk space is used
- Quicker build, download, and run times
- More secure (since less packages and libraries are available)
- Faster deployments
Take note of the following environment variables:
PYTHONDONTWRITEBYTECODE: Prevents Python from writing pyc files to disc (equivalent to
PYTHONUNBUFFERED: Prevents Python from buffering stdout and stderr (equivalent to
Finally, we updated Pip, copied over the requirements.txt file, installed the dependencies, and copied over the Django project itself.
Depending on your environment, you may need to add
RUN mkdir -p /usr/src/appjust before you set the working directory:# set working directory RUN mkdir -p /usr/src/app WORKDIR /usr/src/app
Add a .dockerignore file to the "app" directory as well:
env .dockerignore Dockerfile Dockerfile.prod
Like the .gitignore file, the .dockerignore file lets you exclude specific files and folders from being copied over to the image.
Review Docker for Python Developers for more on structuring Dockerfiles as well as some best practices for configuring Docker for Python-based development.
Then add a docker-compose.yml file to the project root:
version: '3.7' services: movies: build: ./app command: python manage.py runserver 0.0.0.0:8000 volumes: - ./app/:/usr/src/app/ ports: - 8000:8000 env_file: - ./app/.env.dev
This config will create a service called
movies from the Dockerfile.
volume is used to mount the code into the container. This is a must for a development environment in order to update the container whenever a change to the source code is made. Without this, you would have to re-build the image each time you make a change to the code.
Take note of the Docker compose file version used --
3.7. Keep in mind that this version does not directly relate back to the version of Docker Compose installed; it simply specifies the file format that you want to use.
Review the Compose file reference for info on how this file works.
ALLOWED_HOSTS variables in settings.py:
# app/drf_project/settings.py SECRET_KEY = os.environ.get("SECRET_KEY") DEBUG = int(os.environ.get("DEBUG", default=0)) # 'DJANGO_ALLOWED_HOSTS' should be a single string of hosts with a space between each. # For example: 'DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]' ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ")
Then, create a .env.dev file in the "app" directory to store environment variables for development:
DEBUG=1 SECRET_KEY=foo DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
Build the image:
$ docker-compose build
This will take a few minutes the first time. Subsequent builds will be much faster since Docker caches the results. If you'd like to learn more about Docker caching, review the Order Dockerfile commands slide.
Once the build is done, fire up the container in detached mode:
$ docker-compose up -d
Navigate to http://localhost:8000/ to again view the welcome screen. Check for errors in the logs if this doesn't work via
docker-compose logs -f.
If you run into problems with the volume mounting correctly, you may want to remove it altogether by deleting the volume config from the Docker Compose file. You can still go through the course without it; you'll just have to re-build the image after you make changes to the source code.
Windows Users: Having problems getting the volume to work properly? Review the following resources:
You also may need to add
environmentportion of your Docker Compose file. Review Declare default environment variables in file for more info.
Bring down the development containers (and the associated volumes with the
$ docker-compose down -v
Since we'll be moving to Postgres, go ahead and remove the db.sqlite3 file from the "app" directory.
├── .gitignore ├── app │ ├── .dockerignore │ ├── .env.dev │ ├── Dockerfile │ ├── drf_project │ │ ├── __init__.py │ │ ├── asgi.py │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py │ ├── manage.py │ ├── movies │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ └── requirements.txt └── docker-compose.yml
✓ Mark as Completed