Django Set up
Previously
Previously, we have set up the front-end, which includes configuring server, domain and Nginx.
This article will talk about setting up API powered by Django and DRF(Django Rest Framework).
API is deployed by docker compose
. I will present how to create docker-compose.yml
and DockerFile
.
docker-compose.yml
API contains, at least, 2 parts, database and web application.
I choose MySQL
as database and create a django application. So, docker-compose.yml
is as followed.
version: "3.9"
services:
db:
image: mysql
django_app:
depends_on:
- db
I use offical MySQL
docker image. To initialize a mysql database, we need.
-
create
root
password and databaseIt's required by the offical image.
-
create a database and expose the port
3306
The database is connected and used by web application
-
mount the data and the configuration
Once the docker container is destroyed, all the data inside will be cleared. We need to mount the data and the configuration on the host machine using
volumes
.
So, docker-compose.yml
becomes:
version: "3.9"
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: my-password
MYSQL_DATABASE: my-database
volumes:
- mysql_data:/var/lib/mysql
- mysql_config:/etc/mysql
django_app:
depends_on:
- db
volumes:
mysql_data:
mysql_config:
Now, let's set up web application. We assume that the image of application is saved in the docker hub, called repo/my-api
. As setting the database, we use the docker hub image.
Next, we copy all the codes, which is under the folder django_app
, into the container with bind mounting.
Finally, we expose a port for nginx.
django_app:
image: repo/my-api
volumes:
- ./django_app:/code
ports:
- 8000:8000
depends_on:
- db
The full docker-compose.yml
is as followed.
version: "3.9"
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: my-password
MYSQL_DATABASE: my-database
volumes:
- mysql_data:/var/lib/mysql
- mysql_config:/etc/mysql
django_app:
image: repo/my-image
volumes:
- ./django_app:/code
ports:
- 8000:8000
depends_on:
- db
volumes:
mysql_data:
mysql_config:
Since we use Django as the web application, there are some difference between dev
mode and production
mode.
I use docker-compose.override.yml
to override the configuration for dev
mode, and docker-compose.prod.yml
for production
.
In dev
mode, we build the image locally and push it to the docker hub. Besides, we use runsever
to start the application.
# docker-compose.override.yml
version: "3.9"
# dev config
services:
django_app:
build: "./django_app"
command: python manage.py runserver 0.0.0.0:8000 --settings=core.settings.local
To build the image, run docker-compose build
.
To run the application in the dev
mode, launch docker-compose up
.
In production
mode, we do NOT build the image, and we use gunicorn
to start the application.
# docker-compose.prod.yml
version: "3.9"
# prod config
services:
django_app:
command: gunicorn core.wsgi:application --bind 0.0.0.0:8000
To run the application at background, launch:
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
DockerFile
DockerFile
describes how the image is built. We can followed the offical example.
I use python
as the base image. It's big, but it contains all the tools I need. We can choose slim
version. Then, we need add extra package by ourselves.
Since I use opencv
in the project, I need to install its c++
codes. This DockerFile presents all the packages needed.
FROM python:3.9
ENV PYTHONUNBUFFERED=1
WORKDIR /opt/build
# set extra env variable
# ENV OPENCV_VERSION="4.5.1"
# install extra packages
# RUN apt-get -qq update \
# && apt-get -qq install -y --no-install-recommends ...
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/
Now, run docker-compose build
to build the image. Once the image is built, we can push it to the docker hub. Before that, we should create a repo.
docker tag <container> repo/my-api
docker push repo/my-api
Initialize Django Application
Creating a django application is simple. We should move under the django_app
and run the CLI.
cd django_app
docker-compose run django_app django-admin startproject core
Now, in the core
folder, there is a settings.py
. Remove it and create a folder called settings
. Inside settings
, create 3 files:
base.py
local.py
production.py
Replace
core.settings
bycore.setting.base
in other files, such asmanage.py
.
In
wsgi.py
, replacecore.settings
bycore.setting.production
As we discussed before, it's slightly different between dev
mode and production
mode. local.py
and production.py
are for these 2 modes. Both of them extends base.py
.
DO NOT commit
local.py
andproduction.py
in git.
Django can't server static files in production
mode. A commmon difference is, in dev
mode, the static files are served by runserver
, while, in production
mode, they are served by the third party, such as S3 of AWS.