Django Application Deployment: Docker Containerization Practice
Before this, I had always deployed applications using uwsgi+virtualenv+nginx, which was rather cumbersome to operate and depended on the Python version on the server. For service management, plain uwsgi + pid wasn't particularly troublesome, but it was never as convenient as docker compose. Unfortunately the original server was a 32-bit system so I couldn't use docker. Now I've added a new server, so I quickly got docker set up~ I have to say it's really too simple and convenient, completely foolproof, and I basically didn't like the previous u
目录10 个章节
Before this, I had always deployed applications using uwsgi+virtualenv+nginx, which was rather cumbersome to operate and depended on the Python version on the server. For service management, plain uwsgi + pid wasn't particularly troublesome, but it was never as convenient as docker compose. Unfortunately the original server was a 32-bit system so I couldn't use docker. Now I've added a new server, so I quickly got docker set up~ I have to say it's really too simple and convenient, completely foolproof, and I basically didn't run into the kinds of pitfalls I had with the previous uwsgi deployment. Awesome!
Installation
It's best to install docker and compose on your development machine for local testing. For installation methods, just refer to the official site; this article won't go into details.
Reference: https://docs.docker.com/
Writing the Dockerfile
First, you need to write a Dockerfile for the Django application to build the service image.
My Dockerfile is as follows, with comments on every line for your reference:
FROM python:3.7
# 设置 python 环境变量
ENV PYTHONUNBUFFERED 1
# 创建 code 文件夹并将其设置为工作目录
RUN mkdir /code
WORKDIR /code
# 更新 pip
RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip -U
# 设置清华源
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 将 requirements.txt 复制到容器的 code 目录
ADD requirements.txt /code/
# 安装库
RUN pip install -r requirements.txt
# 将当前目录复制到容器的 code 目录
ADD . /code/
After writing it, you can directly run docker run to build the image, then enter the container's command line and execute python manage.py runserver 0.0.0.0 8000 to test whether the server starts normally (of course you won't be able to access it before exposing the port)
Orchestrating Services with Compose
Docker Compose is a Docker tool for defining and running complex applications. An application that uses Docker containers typically consists of multiple containers. With Docker Compose, you no longer need to use shell scripts to start containers. Compose manages multiple Docker containers through a configuration file. In the configuration file, all containers are defined via services, then you use the docker-compose script to start, stop, and restart the application, as well as the services in the application and all dependent service containers. It is very suitable for development scenarios that combine multiple containers.
Official docs: https://docs.docker.com/compose/overview/
Note that the compose version needs to correctly correspond to the docker version to run properly. Docker updates quickly, so it's best to install from the latest version on the official site~
Below is my docker-compose.yml file; I'll introduce the configuration items afterward
version: "3"
services:
mongo:
image: mongo
expose:
- 27017
restart: on-failure # 退出代码指示出现故障错误时重启
postgres:
image: postgres
expose:
- 5432
restart: on-failure
environment:
- POSTGRES_PASSWORD=password
web:
restart: always # 除正常工作外,容器会在任何时候重启,比如遭遇 bug、进程崩溃、docker 重启等情况。
build: .
environment:
- ENVIRONMENT=docker
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "9000:8000"
depends_on:
- postgres
- mongo
As you can see, this project uses PostgreSQL and MongoDB. I use compose to integrate them together and expose ports for web (that is, the Django application) to use.
After writing the docker-compose.yml file, run docker-compose up and it will automatically build each image and run the services—very convenient.
If you need to run in the background, use: docker-compose up -d
To rebuild images, use: docker-compose up --build
To delete, use: docker-compose down
Start and stop: docker-compose start, docker-compose stop
Compose Configuration
The official site has very detailed configuration documentation. In this article I'll only introduce a few configuration items I commonly use.
build
build can specify the path containing the build context, for example in the docker-compose.yml above:
web:
build: .
volumes Configuration
Note that under the web node there is a volumes configuration.
As you can see from the Dockerfile earlier, the Django application code is statically copied into the container at build time, i.e., via the ADD . /code/ command in the Dockerfile, which copies the source code from the physical host into the container, so subsequent code changes in the src directory on the physical host will not be reflected in the container.
You can use the volumes keyword to mount a physical host directory into the container (at this point you can delete the ADD . /code/ command in the Dockerfile; there's no need to pack the code into the image when creating it, but instead dynamically mount via volumes, so the container and the physical host share a data volume, which still enables hot-reloading of the program)
links and depends_on
These two are actually pretty similar, but the official docs say the former is no longer recommended, so just use depends_on. Its purpose is to link containers across multiple services. For example in this article, my Django application needs to use a postgresql database and MongoDB, so I link them together and expose ports (but note that in docker, each image is a separate host, so these three services are equivalent to three different VMs and cannot be accessed via localhost:port). Thus in the Django service you need to use a form like postgres:5432.
Here postgres is the service name we wrote in depends_on. Of course you can set an alias, for example postgres:db, then you'd access it via db:5432~
The principle of accessing the server via this name is equivalent to local DNS, or rather the hosts file~
Database Migration
After the Django application is deployed on the server, there's still the issue of database migration. It's actually easy to solve—either go directly into the docker environment to run commands, or use docker-compose run to execute them, as follows:
docker-compose run web python3 manage.py makemigrations
docker-compose run web python3 manage.py migrate
Other commands you need to run work the same way~
command
This command is the command to execute after a service's image has been built and started. Generally you can only execute one, though you can also execute multiple (not recommended)
I glanced at Stack Overflow; there are roughly two methods:
The first:
web:
command: python a.py && python b.py
The second, using a pipe:
web:
command:
- /bin/sh
- -c
- |
python a.py
python b.py
That's about all I'll cover, because it's really just that simple. For more operations, refer to the official docs~
References
_EOF_
Django Application Deployment: Docker Containerization Practice
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
性能提升4倍!使用Granian作为Django项目的ASGI服务器
Granian是Rust写的ASGI服务器,性能比Daphne强点,但离uWSGI还差着远?静态文件支持倒是省事。开发环境够用,生产环境还是得看情况。
2025-11-22 · Django · 约 1 分钟
Django快速开发实践:Drf框架和xadmin配置指北
步骤 既然是快速开发,那废话不多说,直接说步骤: 安装Djagno 安装Django Rest Framework 定义models 定义Rest framework的serializers 定义Rest framework的viewsets 配置Rest framework的router 配置管理后台admin 根据需要写template和对应的view 经过这些步骤就能得到一个具备完整的后端接
2022-09-06 · Django · 约 1 分钟
Django过时了吗?从ASGI到AI时代的思考
Django过时?技术趋势变了而已,异步支持短板在AI时代更明显。生态工程化再稳,也挡不住轻量框架和ASGI的冲击。独立开发者该考虑新选择了?
2025-09-12 · Django · 约 1 分钟
给Django-Admin添加验证码和多次登录尝试限制
Django自带的Admin很好用,但是放到生产环境总还差了点什么= = 看看admin的介绍: Django奉行Python的内置电池哲学。它自带了一系列在Web开发中用于解决常见问题或需求的额外的、可选工具。这些工具和插件,例如django.contrib.redirects都必须在settings中的INSTALLED_APPS处进行注册,有的还需要执行manage.py migrate命令
2021-12-18 · Django · 约 1 分钟
讨论
共 0 条加载评论中…