本例中我们将使用docker-compose编排并启动2个容器,这更接近于实际生成环境下的部署。
Nginx 容器依赖Django+Uwsgi容器
我们使用docker-compose时可以给每个容器取个别名,这样访问容器时就可以直接使用别名访问,而不使用Docker临时给容器分配的IP了。
这两个容器的别名及通信端口如下图所示:
我们新建了一个compose文件夹,专门存放用于构建其它容器镜像的Dockerfile及配置文件。compose文件夹与django项目的根目录mysite同级。这样做的好处是不同的django项目可以共享compose文件夹。
新建learn-docker 目录,拷贝mysite到该目录
另外新建compose目录,用于存放docker-compose相关配置文件
目录结构如下:
learn_docker/
├── compose # 存放各项容器服务的Dockerfile和配置文件
│ ├── nginx
│ │ ├── Dockerfile # 构建nginx镜像的Dockerfile
│ │ ├── log # nginx 日志挂载目录
│ │ ├── nginx.conf # nginx配置
│ │ └── ssl
│ └── uwsgi # 挂载保存web容器中uwsgi的日志
│ ├── mysite-master.pid
│ └── mysite-uwsgi.log
├── docker-compose.yml # 核心compose文件
└── mysite # 常规django项目
├── cookies
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ ├── models.py
│ ├── __pycache__
│ ├── serializers.py
│ ├── templates
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── db.sqlite3
├── Dockerfile # 构建web镜像
├── manage.py
├── mysite
│ ├── GeoLite2-City.mmdb
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── pip.conf # pypi源设置成国内,加速pip安装
├── requirements.txt #项目依赖
├── start.sh # 启动Django+Uwsgi容器后要执行的脚本
├── static # django静态文件
│ ├── admin
│ ├── css
│ ├── js
│ └── rest_framework
└── uwsgi.ini # uwsgi配置文件
docker-compose.yml
version: "3"
services:
web:
build: ./mysite # 使用mysite目录下的Dockerfile
expose:
- "8000" # uwsgi 暴露给其他容器的端口
volumes:
- ./mysite:/var/www/html/mysite # 挂载项目代码
- ./compose/uwsgi:/tmp # 挂载uwsgi日志
environment:
- DEBUG=False
restart: always
tty: true
stdin_open: true
command: ./start.sh #容器启动后运行脚本,主要要保持前台运行,否则容器会退出
nginx:
build: ./compose/nginx
ports:
- "28000:80" # 主机可访问的端口
volumes:
- ./mysite/static:/usr/share/nginx/html/static # 挂载django静态文件
- ./compose/nginx/ssl:/usr/share/nginx/ssl # 挂载ssl证书目录
- ./compose/nginx/log:/var/log/nginx # 挂载日志
links:
- web
depends_on:
- web
restart: always
第二步:编写Web (Django+Uwsgi)镜像和容器所需文件
构建Web镜像(Django+Uwsgi)的所使用的Dockerfile如下所示:
# 建立 python3.7 环境
FROM python:3.7
# 镜像作者
MAINTAINER LZM
# 设置 python 环境变量
ENV PYTHONUNBUFFERED 1
# 设置pypi源头为国内源
COPY pip.conf /root/.pip/pip.conf
# 在容器内/var/www/html/下创建 mysite2 文件夹
RUN mkdir -p /var/www/html/mysite
# 设置容器内工作目录
WORKDIR /var/www/html/mysite
# 将当前目录文件拷贝一份到工作目录中(. 表示当前目录)
ADD . /var/www/html/mysite
# 利用 pip 安装依赖
RUN pip install -r requirements.txt
# 设置start.sh文件可执行权限
RUN chmod +x ./start.sh
requirements.txt 内容如下所示
# django
django==3.0.6
# uwsgi
uwsgi==2.0.18
start.sh 本文件内容如下所示。最重要的是最后一句,使用uwsgi.ini配置文件启动Django服务。
#!/bin/bash
# 从第一行到最后一行分别表示:
# 1. 收集静态文件到根目录
# 2. 生产数据库迁移文件
# 3. 根据数据库迁移文件来修改数据库
# 4. 用 uwsgi启动 django 服务, 不再使用python manage.py runserver
python manage.py collectstatic --noinput&&
python manage.py makemigrations&&
python manage.py migrate&&
uwsgi --ini /var/www/html/mysite/uwsgi.ini
uwsgi.ini 本文件内容如下所示。最重要的是最后一句,使用logto 写日志, 而不用daemonize, daemonize会让服务后台运行,导致容器退出。
[uwsgi]
project=mysite
base=/var/www/html
chdir=%(base)/%(project)
module=%(project).wsgi:application
master=True
processes=4
# respawn processes taking more than 20 seconds
harakiri=20
# reload workers after the specified amount of managed requests
max-requests=5000
# 当服务器退出的时候自动删除unix socket文件和pid文件
vacuum=True
socket=0.0.0.0:8000
pidfile=/tmp/%(project)-master.pid
#daemonize=/tmp/%(project)-uwsgi.log
logto=/tmp/%(project)-uwsgi.log
第三步:编写Nginx镜像和容器所需文件
构建Nginx镜像所使用的Dockerfile如下所示:
# nginx镜像compose/nginx/Dockerfile
FROM nginx:latest
# 删除原有配置文件,创建静态资源文件夹和ssl证书保存文件夹
RUN rm /etc/nginx/conf.d/default.conf \
&& mkdir -p /usr/share/nginx/html/static \
&& mkdir -p /usr/share/nginx/html/media \
&& mkdir -p /usr/share/nginx/ssl
# 添加配置文件
COPY ./nginx.conf /etc/nginx/conf.d/
# 关闭守护模式
CMD ["nginx", "-g", "daemon off;"]
# nginx配置文件
# compose/nginx/nginx.conf
upstream django {
ip_hash;
server web:8000; # Docker-compose web服务端口
}
server {
listen 80; # 监听80端口
server_name localhost; # 可以是nginx容器所在ip地址或127.0.0.1,不能写宿主机外网ip地址
charset utf-8;
client_max_body_size 10M; # 限制用户上传文件大小
location /static {
alias /usr/share/nginx/html/static; # 静态资源路径
}
location /media {
alias /usr/share/nginx/html/media; # 媒体资源,用户上传文件路径
}
location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass django;
uwsgi_read_timeout 600;
uwsgi_connect_timeout 600;
uwsgi_send_timeout 600;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
# proxy_pass http://django; # 使用uwsgi通信,而不是http,所以不使用proxy_pass。
}
}
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
server_tokens off;
现在我们可以使用docker-compose命名构建镜像并启动容器组了。
# 进入docker-compose.yml所在文件夹,输入以下命令构建镜像
docker-compose build
# 查看已生成的镜像
docker images
# 启动容器组服务
docker-compose up
# 查看运行中的容器
docker ps
主要参考:
https://zhuanlan.zhihu.com/p/145364353
原文:https://www.cnblogs.com/cute/p/13223775.html