In this tutorial, we will learn how to bootstrap a project to use Docker. I have loved to dockerize my application from the start because it gives me freedom from using a virtual environment. It saves you a lot if you are a DevOps person. You don’t have to install many dependencies every time for any programming language you are working on.
Before you can start any project, we need to create the following files, if you are looking to dockerize your environment.
- Dockerfile
- Docker-compose file
- Makefile
- Script to run WSGI processes.
Dockerfile
A Dockerfile is a text document that contains all the commands a user could call on a command line to assemble an image. Examples of commands to use are FROM, RUN, CMD, WORKDIR, and COPY. I am using an example for a Django application.
# python base image. Get this from dockerhub
FROM python:3.11-slim
#set environment variables
ENV PYTHONUNBUFFERED=1
#set your working directory
WORKDIR /usr/src/app
# install dependencies required by the image you pulled above
RUN apt update && apt install -y g++ libpq-dev gcc musl-dev
#allow docker to cache installed dependencies between builds
COPY requirements.txt .
RUN python3 -m pip install -r requirements.txt --no-cache-dir
# copy and mount the project to the working directory
COPY . .
# Script to run given instruction eg running production server.
CMD ["./run.sh"]
Docker-compose file
A compose is a YAML file defining services, networks, configs,, secrets and volumes for the Docker applications.
An example of a docker compose file for Django application. Make sure you are saving with .yaml or yml
extensions.
version: "3.9"
services:
app:
image: <image_name>/myproject:latest
working_dir: /usr/src/app
ports:
- 8000:8000
depends_on:
- db
volumes:
- .:/usr/src/app
environment:
- Env=local
- DEBUG=1
- ALLOWED_HOSTS=*
- SECRET_KEY=
- APP_PATH=/var/www/myproject
- DATABASE_DB=dbname
- DATABASE_USER=dbuser
- DATABASE_PASSWORD=password
- DATABASE_HOST=db
- DATABASE_PORT=5432
networks:
- myproject_net
#specify database settings here
db:
image: postgres:14.5-alpine
ports:
- 5432:5432
volumes:
- myproject_pg:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=engineer
- POSTGRES_USER=engineer
- POSTGRES_DB=engineer
networks:
- myproject_net
volumes:
myproject_pg:# databse volume
myproject_app: #app volume
networks:
myproject_net: #connection string
Database settings
After you have specified your PostgreSQL seetttings on the compose file, make sure you go to settings to specify which db you are using. NB, this is for Django applications.
#settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ.get('DATABASE_DB'),
'USER': os.environ.get('DATABASE_USER'),
'PASSWORD': os.environ.get('DATABASE_PASSWORD'),
'HOST': os.environ.get('DATABASE_HOST'),
'PORT': os.environ.get('DATABASE_PORT'),
}
}
Makefile
Makefile defines sets of commands to run and a make utility runs them. An example of a Makefile for running a Django application.
IMAGE=<image_name> # specify how you want to save your image with a tag #name
build:
docker build -t $(IMAGE) .
up:
docker-compose up -d
ps:
docker-compose ps
migrate:
docker-compose exec app python manage.py migrate
makemigrations:
docker-compose exec app python manage.py makemigrations
collectstatic:
docker-compose exec app python manage.py collectstatic --noinput
createsuperuser:
docker-compose exec app python manage.py createsuperuser
logs:
docker-compose logs -f
rm: stop
docker-compose rm -f
stop:
docker-compose stop
Running script
The last item is to specify the script to run your project in production. The script looks like this for a Django application. Make sure to give the permission to the run.sh
. Run this command chmod +x run.sh
# run.sh
#!/bin/bash
# collect static because of the heavy state of static files in production
python manage.py collectstatic --no-input
# gunicorn for WSGI communication
exec gunicorn --bind 0.0.0.0:8000 project.wsgi:application -w 2
Building the Application
To start using the application run the following commands.
#build from a makefile
$ make
#bring up the container
$ docker-compose up
# running a container in the background
$ docker-compose up -d
# running django application tasks
$ docker-compose run --rm app sh -c "python manage.py runserver"
Conclusion
From the above makefile, dockerfile and docker compose, you are now in a position to run your application anywhere, thanks to the Docker containers.