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 许可协议。转载请注明出处!
相关文章
比Django官方实现更好的分页组件+Bootstrap整合
前言 Django全家桶自带的分页组件只能说能满足分页这个功能,但是没那么好用就是了 Django的分页效果 django-pure-pagination分页效果 使用方法 首先安装: pip install django-pure-pagination 添加到App INSTALLED_APPS = ( ... 'pure_pagination', ) 配置一下,配置说明如图 P
2021-12-18 · Django · 约 1 分钟
关于uwsgi服务器的管理
前言 使用Django开发项目好是好,就是部署的时候太麻烦,使用Uwsgi服务器的话,每次修改了代码,都需要重新启动服务器才可以生效。然后uwsgi服务器的重启也挺麻烦。 看了一下官网的文档,最好是把uwsgi安装到venv虚拟环境里面,这样的话在 ps aux 的时候容易区分啦。 查看uwsgi进程 ps -aux | grep uwsgi 结束原uwsgi进程 kill -9 27543 结论
2025-10-27 · Django · 约 1 分钟
性能提升4倍!使用Granian作为Django项目的ASGI服务器
Granian是Rust写的ASGI服务器,性能比Daphne强点,但离uWSGI还差着远?静态文件支持倒是省事。开发环境够用,生产环境还是得看情况。
2025-11-22 · Django · 约 1 分钟
Django更换数据库和迁移数据方案
前言 双十一光顾着买东西都没怎么写文章,现在笔记里还有十几篇半成品文章没写完… 今天来分享一下 Django 项目切换数据库和迁移数据的方案,网络上找到的文章方法不一,且使用中容易遇到各类报错,本文根据 Django 官方文档和工作中的经验,稳定可靠,在博客中长期更新~ 如果你遇到同样的问题,阅读本文应该能得到比较好的解决方案。 基本步骤 Django 默认使用 SQLite 数据库方便开发,同时
2022-11-12 · Django · 约 1 分钟
讨论
共 0 条加载评论中…