docker 安装 django uwsgi nginx



本例中我们将使用docker-compose编排并启动2个容器,这更接近于实际生成环境下的部署。

  1. Django + Uwsgi容器:核心应用程序,处理动态请求
  2. Nginx容器:反向代理服务并处理静态资源请求

Nginx 容器依赖Django+Uwsgi容器

我们使用docker-compose时可以给每个容器取个别名,这样访问容器时就可以直接使用别名访问,而不使用Docker临时给容器分配的IP了。

这两个容器的别名及通信端口如下图所示:


image


Docker-compose部署Django项目布局树形图

我们新建了一个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文件

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命名构建镜像并启动容器组了。

 # 进入docker-compose.yml所在文件夹,输入以下命令构建镜像
docker-compose build
 # 查看已生成的镜像
docker images
 # 启动容器组服务
docker-compose up
 # 查看运行中的容器
docker ps


主要参考:
https://zhuanlan.zhihu.com/p/145364353

posted on 2020-07-02 11:32  katago  阅读(582)  评论(0编辑  收藏  举报