使用Nginx+Gunicorn在Docker上构建Django生产环境

通过Django的runserver命令运行的服务器仅仅是一个简易开发服务器。如果要进行生产运营,需要单独建立Web服务器(反向代理)和应用服务器(WSGI服务器)以确保安全性和性能。本次将使用Nginx作为Web服务器,使用Gunicorn作为应用服务器,在Docker上进行搭建。

环境

ソフトバージョンOSMacOS Catalina 10.15.7docker engine20.10.5docker compose1.29.0Django3.2.5Gruncorn20.1.0Nginx1.17.7

目录结构

.
├── app           # Djangoアプリ
├── config        # Django設定関係
│   ├── local_settings.py
│   ├── settings.py
│ 
├── Dockerfile
├── docker-compose.yml
├── docker.env
├── gunicorn.conf
├── manage.py
└── requirements.txt

Django配置文件

为了开发环境,创建一个 local_settings.py 文件,将 ‘SECRET_KEY’、’DEBUG’ 和 ‘ALLOWED_HOSTS’ 的默认设置迁移到该文件中。
在启动开发用服务器时,使用 settings 选项指定 ‘local_settings.py’ 文件。

from .settings import *

SECRET_KEY = 'XXXXX'
DEBUG = True
ALLOWED_HOSTS = []

# 開発用サーバ起動コマンド
# python manage.py runserver --settings config.local_settings

在settings.py文件中,记录生产环境的设置。’SECRET_KEY’和’ALLOWED_HOSTS’是从环境变量中引用的值,并将’DEBUG’设置为False。

SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')
DEBUG = False
ALLOWED_HOSTS = list(os.environ.get('ALLOWED_HOSTS','localhost').split(' '))

STATIC_URL = '/static/'
STATICFILES_DIRS = [str(BASE_DIR / 'static')]
STATIC_ROOT = str(BASE_DIR / 'static_root')

Docker容器的配置文件设置

在Docker容器中搭建Python环境,并安装requirements.txt中定义的Django和Gunicorn。
使用gunicorn命令启动Gunicorn,并加载config/wisg.py文件,绑定UNIX域套接字。

FROM python:3.9.6-alpine

WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN pip install --upgrade pip
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip install -r requirements.txt
RUN mkdir -p /var/run/gunicorn

CMD ["gunicorn", "config.wsgi", "--bind=unix:/var/run/gunicorn/gunicorn.sock"]
Django==3.2.5
gunicorn==20.1.0

Docker Compose文件的配置

使用Docker文件构建gunicorn镜像,并从Docker Hub下载nginx镜像。
在gunicorn容器和nginx容器中都将gunicorn卷挂载,并进行UNIX套接字通信。
将容器内的nginx配置文件(default.conf)挂载到主机上创建的gunicorn.conf文件。
将Django应用程序的’DJANGO_SECRET_KEY’和’ALLOWED_HOSTS’设置为环境变量。

version: '3'

services:
  gunicorn:
    build: .
    image: gunicorn:20.1.0
    container_name: gunicorn
    volumes:
      - .:/usr/src/app/
      - gunicorn:/var/run/gunicorn
    env_file: docker.env
    stdin_open: true
    tty: true

  nginx:
    image: nginx:1.17.7
    container_name: nginx
    depends_on:
      - gunicorn
    ports:
      - "80:80"
    volumes:
      - ./gunicorn.conf:/etc/nginx/conf.d/default.conf
      - ./static_root:/var/www/mysite/static
      - gunicorn:/var/run/gunicorn
volumes:
  gunicorn:
    driver: local
upstream gunicorn-django {
    server unix:///var/run/gunicorn/gunicorn.sock;
}
server {
    listen 80;
    server_name localhost;
    location / {
        try_files $uri @gunicorn;
    }
    location /static/ {
        root /var/www/mysite;
    }
    location @gunicorn {
        proxy_pass http://gunicorn-django;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
DJANGO_SECRET_KEY='XXXXX'
ALLOWED_HOSTS='example.com'
# 開発環境の場合は、ALLOWED_HOSTS='localhost 127.0.0.1'

启动命令

使用docker-compose up命令以生成和启动容器。
如果可以通过localhost访问并显示页面,就表示一切正常。

$ docker-compose up -d
スクリーンショット 2021-07-24 9.02.23.png

请参考

    DockerでPythonのWebアプリケーションをNginx + Gunicorn で起動する
广告
将在 10 秒后关闭
bannerAds