Dockerfile Python Django + uWSGI + Nginx

作者: Ju4t

架构 Django + uWSGI (http方式),如使用socket方式需要Nginx转发;

注释掉了 nginx 和 uwsgi 部署在同一容器内的配置;

docker-compose 为推荐架构,如果您了解 Nginx+ 更推荐 ^_^;

django静态文件、数据库等操作,建议单独处理;

目录结构

├── Dockerfile
├── README.md
├── db.sqlite3
├── djangoProject
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── docker-compose.yml
├── docker-entrypoint.sh
├── manage.py
├── nginx.conf
├── requirements.txt
├── templates
├── uwsgi.ini

关键文件

Dockerfile

FROM python:3.9-alpine

LABEL maintainer="ju4t@qq.com"
LABEL org.opencontainers.image.title="labdoc"
LABEL org.opencontainers.image.authors="ju4t@qq.com"

ENV PYTHONUNBUFFERED 1
ENV MIRRORS https://mirrors.aliyun.com
ENV WORKDIR /app
ENV PRODUCT 1
ENV DEBUG 0
ENV ALLOWED_HOSTS labdoc.cc
ENV SECRET_KEY ''
ENV DB_HOST ''
ENV DB_NAME ''
ENV DB_USER ''
ENV DB_PASS ''
ENV KV_HOST ''
ENV KV_USER ''
ENV KV_PASS ''

# Alpine Linux 源 指向最新的稳定版本
RUN echo $MIRRORS/alpine/latest-stable/main > /etc/apk/repositories; \
    echo $MIRRORS/alpine/latest-stable/community >> /etc/apk/repositories

RUN apk --no-cache add \
    # 基础依赖
    gcc libgcc musl-dev \
    # mysqlclient 依赖
    mariadb-connector-c-dev \
    # Pillow 自测依赖,官方推荐依赖 > https://pillow.readthedocs.io/en/latest/installation.html#external-libraries
    libxml2-dev libxslt-dev libffi-dev jpeg-dev zlib-dev

# Nginx
#RUN apk --update add nginx
#ADD deployment/nginx.conf /etc/nginx/http.d/default.conf

# 根据结构自行调整,包含 requirements.txt
WORKDIR $WORKDIR
COPY ./ $WORKDIR

# 安装包
RUN pip install --upgrade pip -i $MIRRORS/pypi/simple && \
    pip install --no-cache-dir -r requirements.txt -i $MIRRORS/pypi/simple && \
    # uWSGI 部署
    pip install --no-cache-dir uWSGI -i $MIRRORS/pypi/simple
    # apk del gcc

# 如果 nginx 和 uwsgi 部署在同一docker里,不能使用 uwsgi账号,而是通过root 启动 nginx 和 uwsgi
RUN adduser --disabled-password --no-create-home uwsgi && \
    chown -R uwsgi:uwsgi $WORKDIR
USER uwsgi

# 调试
#ENTRYPOINT ["python manage.py runserver 0.0.0.0:8000"]

# entrypoint 文件启动
ENTRYPOINT ["sh", "./docker-entrypoint.sh"]

EXPOSE 80 443 3031 8000

docker-entrypoint.sh

#!/bin/sh

echo "*** 启动 uWSGI 服务 ***"
# 1、nginx + socket 2、http-socket
# http-socket > http
#nohup uwsgi --master --enable-threads --processes 4 --threads 2 --gid uwsgi --uid uwsgi --module djangoProject.wsgi --http-socket :8000 --socket :3031
nohup uwsgi --ini /app/uwsgi.ini

#echo "*** 启动 Nginx 服务 ***"
#nginx -g "daemon off;"

exec "$@"

requirements.txt

Django>=3.0,<4.0
mysqlclient  # 官方推荐 https://pypi.org/project/mysqlclient/
djangorestframework
djangorestframework-jwt
drf-extensions
django-filter
django-redis
django-mditor # 编辑器
Markdown  # 前端渲染
pygments  # 脚本高亮css生成
# oss
# 默认使用阿里云镜像无法安装,用 清华的可以 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple oss2
oss2 # https://help.aliyun.com/document_detail/85288.html
django_oss_storage

Pillow # 图片

uwsgi.ini

[uwsgi]
chdir           = /app
module          = djangoProject.wsgi

# 根据cpu核心自动计算 processes、threads
master          = true
enable-threads  = true
processes       = %(%k * 2)
threads         = %(%k * 20)

# 使用 nginx 服务中的用户,uwsgi.sock
gid             = uwsgi
uid             = uwsgi
lazy-apps       = true
chmod-socket    = 777

# http 暴露端口,直接访问
http-socket     = :8000

# socket文件,配合nginx时候使用
socket          = :3031
;socket          = uwsgi.sock
# status文件,可以查看uwsgi的运行状态,uwsgitop uwsgi.status
;stats           = uwsgi.status
# pid文件,通过该文件可以控制uwsgi的重启和停止
pidfile         = uwsgi.pid
# 日志文件存放位置
# daemonize       = uwsgi.log
# 退出uwsgi是否清理中间文件,包含pid、sock和status文件
vacuum          = true

# 调优wsgi-file

# 处理过多少个请求后重启进程,目的是防止内存泄露
max-requests    = 5000
# 每个进程排队的请求数量,默认:100 并发数 = procsses * threads * listen
# 使用时需要修改系统
# listen          = 65535
# header 的 buffer 大小 默认:4k
buffer-size     = 65536
# 所有进程在 30s 没有响应后傻屌
harakiri        = 30
# 记录慢于 3000 毫秒的请求
log-slow        = 3000

# 关闭log,提升性能
disable-logging = true

# 单独开一个线程进行 log 写入工作,这样有更好的性能
threaded-log    = true

# uWSGI 配置参数 https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/ThingsToKnow.html

nginx.conf

upstream django {
    # server unix:///app/uwsgi.sock; # for a file socket
    server djangoproject-app-1:3031 weight=100;
    server djangoproject-app-2:3031 weight=100;
}

server {
    listen      80;
    listen      [::]:80;
    # listen      443 ssl http2;
    # listen      [::]:443 ssl http2;
    server_name localhost;
    # charset     utf-8;

    gzip on;

    # ssl_certificate /app/blog/ssl/server.pem;
    # ssl_certificate_key /app/blog/ssl/server.key;
    # ssl_session_cache shared:SSL:1m;
    # ssl_session_timeout  10m;
    # ssl_ciphers HIGH:!aNULL:!MD5;
    # ssl_prefer_server_ciphers on;

    client_max_body_size 75M;

    location /media {
        alias /app/media;
    }
    location /static {
        alias /app/static;
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        include                       /etc/nginx/uwsgi_params;
        uwsgi_pass                    django; # 127.0.0.1:3031; unix:///app/uwsgi.sock;
        uwsgi_param Host              $host;
        uwsgi_param X-Real-IP         $remote_addr;
        uwsgi_param X-Forwarded-For   $proxy_add_x_forwarded_for;
        uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
    }
}

docker-compose.yml

version: "3.8"
services:
  app:
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
      resources:
        limits:
          cpus: '0.50'
          memory: '512M'
        reservations:
          cpus: '0.25'
          memory: '128M'
    build:
      context: .
      dockerfile: Dockerfile
#    command: python manage.py runserver 0.0.0.0:8000
#    ports:
#      - 80:80 # NGINX
#      - 8000:8000 # HTTP
#      - 8080:8080 # socket
#    networks:
#      - vlan100
    volumes:
      - ./:/app
    #    env_file: .env
    restart: always

  nginx:
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: '512M'
        reservations:
          cpus: '0.25'
          memory: '128M'
    image: nginx
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app
    restart: always

#networks:
#  vlan100:
#    driver: bridge


构建起来~~

$ docker build -t djangoproject ./

# 拉起日志
(djangoProject) ju4t@Mac djangoProject % docker compose up
[+] Building 53.8s (12/12) FINISHED                                                                                                                                                                            
 => [internal] load build definition from Dockerfile                                                                                                                                                      0.0s
 => => transferring dockerfile: 1.54kB                                                                                                                                                                    0.0s
 => [internal] load .dockerignore                                                                                                                                                                         0.0s
 => => transferring context: 2B                                                                                                                                                                           0.0s
 => [internal] load metadata for docker.io/library/python:3.9-alpine                                                                                                                                      0.0s
 => [1/7] FROM docker.io/library/python:3.9-alpine                                                                                                                                                        0.0s
 => [internal] load build context                                                                                                                                                                         0.0s
 => => transferring context: 12.84kB                                                                                                                                                                      0.0s
 => CACHED [2/7] RUN echo https://mirrors.aliyun.com/alpine/latest-stable/main > /etc/apk/repositories;     echo https://mirrors.aliyun.com/alpine/latest-stable/community >> /etc/apk/repositories       0.0s
 => CACHED [3/7] RUN apk update &&  apk --update add gcc     libgcc     musl-dev     libxml2-dev     libxslt-dev     libffi-dev     jpeg-dev     zlib-dev                                                 0.0s
 => CACHED [4/7] WORKDIR /app                                                                                                                                                                             0.0s
 => [5/7] COPY ./ /app                                                                                                                                                                                    0.0s
 => [6/7] RUN pip install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple &&     pip install --no-cache-dir uWSGI -i https://mirrors.aliyun.com/pypi/simple &&     pip install --no-cache-dir -  52.1s
 => [7/7] RUN adduser --disabled-password --no-create-home uwsgi                                                                                                                                          0.3s
 => exporting to image                                                                                                                                                                                    1.3s
 => => exporting layers                                                                                                                                                                                   1.3s
 => => writing image sha256:4ece610667ea966a17002442a53ac24e7f33e777b4e7a606e7e672410ce72825                                                                                                              0.0s
 => => naming to docker.io/library/djangoproject_app                                                                                                                                                      0.0s
[+] Running 4/4
 ⠿ Network djangoproject_default    Created                                                                                                                                                               0.1s
 ⠿ Container djangoproject-app-2    Created                                                                                                                                                               0.1s
 ⠿ Container djangoproject-app-1    Created                                                                                                                                                               0.1s
 ⠿ Container djangoproject-nginx-1  Created                                                                                                                                                               0.2s
Attaching to djangoproject-app-1, djangoproject-app-2, djangoproject-nginx-1
djangoproject-app-1    | *** 启动 uWSGI 服务 ***
djangoproject-app-1    | [uWSGI] getting INI configuration from /app/uwsgi.ini
djangoproject-app-1    | *** Starting uWSGI 2.0.20 (64bit) on [Tue Oct 25 03:42:19 2022] ***
djangoproject-app-1    | compiled with version: 11.2.1 20220219 on 25 October 2022 03:41:40
djangoproject-app-1    | os: Linux-5.10.76-linuxkit #1 SMP Mon Nov 8 10:21:19 UTC 2021
djangoproject-app-1    | nodename: a030e669cce6
djangoproject-app-1    | machine: x86_64
djangoproject-app-1    | clock source: unix
djangoproject-app-1    | detected number of CPU cores: 4
djangoproject-app-1    | current working directory: /app
djangoproject-app-1    | writing pidfile to uwsgi.pid
djangoproject-app-1    | detected binary path: /usr/local/bin/uwsgi
djangoproject-app-1    | !!! no internal routing support, rebuild with pcre support !!!
djangoproject-app-1    | chdir() to /app
djangoproject-app-1    | your memory page size is 4096 bytes
djangoproject-app-1    |  *** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers *** 
djangoproject-app-1    | detected max file descriptor number: 1048576
djangoproject-app-1    | lock engine: pthread robust mutexes
djangoproject-app-1    | thunder lock: disabled (you can enable it with --thunder-lock)
djangoproject-app-1    | uwsgi socket 0 bound to TCP address :8000 fd 3
djangoproject-app-1    | uwsgi socket 1 bound to TCP address :3031 fd 4
djangoproject-app-1    | Python version: 3.9.9 (main, Nov 30 2021, 03:30:22)  [GCC 10.3.1 20211027]
djangoproject-app-1    | Python main interpreter initialized at 0x7fceadc66ac0
djangoproject-app-1    | python threads support enabled
djangoproject-app-1    | your server socket listen backlog is limited to 100 connections
djangoproject-app-1    | your mercy for graceful operations on workers is 60 seconds
djangoproject-app-1    | mapped 52315056 bytes (51088 KB) for 640 cores
djangoproject-app-1    | *** Operational MODE: preforking+threaded ***
djangoproject-app-2    | *** 启动 uWSGI 服务 ***
djangoproject-app-2    | [uWSGI] getting INI configuration from /app/uwsgi.ini
djangoproject-app-2    | *** Starting uWSGI 2.0.20 (64bit) on [Tue Oct 25 03:42:19 2022] ***
djangoproject-app-2    | compiled with version: 11.2.1 20220219 on 25 October 2022 03:41:40
djangoproject-app-2    | os: Linux-5.10.76-linuxkit #1 SMP Mon Nov 8 10:21:19 UTC 2021
djangoproject-app-2    | nodename: 928321472d8a
djangoproject-app-2    | machine: x86_64
djangoproject-app-2    | clock source: unix
djangoproject-app-2    | detected number of CPU cores: 4
djangoproject-app-2    | current working directory: /app
djangoproject-app-2    | writing pidfile to uwsgi.pid
djangoproject-app-1    | *** uWSGI is running in multiple interpreter mode ***
djangoproject-app-1    | spawned uWSGI master process (pid: 8)
djangoproject-app-1    | spawned uWSGI worker 1 (pid: 9, cores: 80)
djangoproject-app-1    | spawned uWSGI worker 2 (pid: 10, cores: 80)
djangoproject-app-1    | spawned uWSGI worker 3 (pid: 11, cores: 80)
djangoproject-app-1    | spawned uWSGI worker 4 (pid: 12, cores: 80)
djangoproject-app-2    | detected binary path: /usr/local/bin/uwsgi
djangoproject-app-2    | !!! no internal routing support, rebuild with pcre support !!!
djangoproject-app-2    | chdir() to /app
djangoproject-app-2    | your memory page size is 4096 bytes
djangoproject-app-2    |  *** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers *** 
djangoproject-app-2    | detected max file descriptor number: 1048576
djangoproject-app-2    | lock engine: pthread robust mutexes
djangoproject-app-2    | thunder lock: disabled (you can enable it with --thunder-lock)
djangoproject-app-2    | uwsgi socket 0 bound to TCP address :8000 fd 3
djangoproject-app-2    | uwsgi socket 1 bound to TCP address :3031 fd 4
djangoproject-app-2    | Python version: 3.9.9 (main, Nov 30 2021, 03:30:22)  [GCC 10.3.1 20211027]
djangoproject-app-1    | spawned uWSGI worker 5 (pid: 13, cores: 80)
djangoproject-app-1    | spawned uWSGI worker 6 (pid: 14, cores: 80)
djangoproject-app-1    | spawned uWSGI worker 7 (pid: 15, cores: 80)
djangoproject-app-1    | spawned uWSGI worker 8 (pid: 16, cores: 80)
djangoproject-app-2    | Python main interpreter initialized at 0x7f31087cdac0
djangoproject-app-2    | python threads support enabled
djangoproject-app-2    | your server socket listen backlog is limited to 100 connections
djangoproject-app-2    | your mercy for graceful operations on workers is 60 seconds
djangoproject-app-2    | mapped 52315056 bytes (51088 KB) for 640 cores
djangoproject-app-2    | *** Operational MODE: preforking+threaded ***
djangoproject-app-2    | *** uWSGI is running in multiple interpreter mode ***
djangoproject-app-2    | spawned uWSGI master process (pid: 9)
djangoproject-app-2    | spawned uWSGI worker 1 (pid: 10, cores: 80)
djangoproject-app-2    | spawned uWSGI worker 2 (pid: 11, cores: 80)
djangoproject-app-2    | spawned uWSGI worker 3 (pid: 12, cores: 80)
djangoproject-app-2    | spawned uWSGI worker 4 (pid: 13, cores: 80)
djangoproject-app-2    | spawned uWSGI worker 5 (pid: 14, cores: 80)
djangoproject-app-2    | spawned uWSGI worker 6 (pid: 15, cores: 80)
djangoproject-app-2    | spawned uWSGI worker 7 (pid: 16, cores: 80)
djangoproject-app-2    | spawned uWSGI worker 8 (pid: 17, cores: 80)
djangoproject-nginx-1  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
djangoproject-nginx-1  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
djangoproject-nginx-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
djangoproject-nginx-1  | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
djangoproject-nginx-1  | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
djangoproject-nginx-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
djangoproject-nginx-1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
djangoproject-nginx-1  | /docker-entrypoint.sh: Configuration complete; ready for start up
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: using the "epoll" event method
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: nginx/1.21.5
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: OS: Linux 5.10.76-linuxkit
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: start worker processes
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: start worker process 31
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: start worker process 32
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: start worker process 33
djangoproject-nginx-1  | 2022/10/25 03:42:21 [notice] 1#1: start worker process 34
djangoproject-app-1    | WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x7fceadc66ac0 pid: 9 (default app)
djangoproject-app-2    | WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x7f31087cdac0 pid: 12 (default app)
djangoproject-app-1    | WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x7fceadc66ac0 pid: 10 (default app)
djangoproject-app-2    | WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x7f31087cdac0 pid: 14 (default app)
djangoproject-app-2    | WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x7f31087cdac0 pid: 13 (default app)
djangoproject-app-1    | WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x7fceadc66ac0 pid: 11 (default app)
djangoproject-app-1    | WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x7fceadc66ac0 pid: 15 (default app)
djangoproject-app-1    | WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x7fceadc66ac0 pid: 13 (default app)
djangoproject-app-1    | WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x7fceadc66ac0 pid: 14 (default app)
djangoproject-app-2    | WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x7f31087cdac0 pid: 11 (default app)
djangoproject-app-1    | WSGI app 0 (mountpoint='') ready in 3 seconds on interpreter 0x7fceadc66ac0 pid: 12 (default app)
djangoproject-app-2    | WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x7f31087cdac0 pid: 10 (default app)
djangoproject-app-1    | WSGI app 0 (mountpoint='') ready in 3 seconds on interpreter 0x7fceadc66ac0 pid: 16 (default app)
djangoproject-app-2    | WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x7f31087cdac0 pid: 16 (default app)
djangoproject-app-2    | WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x7f31087cdac0 pid: 15 (default app)
djangoproject-app-2    | WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x7f31087cdac0 pid: 17 (default app)
(djangoProject) ju4t@Mac djangoProject % docker images | grep django                
djangoproject_app                                         latest                                                  4ece610667ea   3 minutes ago   228MB

WechatIMG692.png

WechatIMG693.png

部署及安全问题

部署

  • http-stock 为原生 http,同时在dockerfile中指定 用户
  • nginx + TCP/IP socket :3031(nginx作负载)

不使用 nginx 代理,http-stock 暴露服务

http 和 http-stock

http 和 nginx/apache同级别,前端不支持uwsgi时使用http-stock
一般地,使用 http-stock

UNIX Socket 还是 TCP/IP Socket

同一台服务器上使用UNIX Socket uwsgi.sock,多台服务器上Nginx转发 使用 TCP/IP Socket :3031

安全性

如果 nginx 和 uwsgi 部署在同一docker里,不能在dockerfile中 USER uwsgi 账号,而是通过 root 启动 nginx 和 uwsgi
uwsgi启动时指定gid/uid

# nginx + uwsgi 在同一docker
/app # ps
PID   USER     TIME  COMMAND
    1 root      0:00 sh ./docker-entrypoint.sh
    8 uwsgi     0:00 uwsgi --master --enable-threads --processes 4 --threads 2 --gid uwsgi --uid uwsgi --module djangoProject.wsgi --http-socket :8080 --socket :3031
    9 root      0:00 nginx: master process nginx -g daemon off;
   10 nginx     0:00 nginx: worker process
   11 nginx     0:00 nginx: worker process
   12 nginx     0:00 nginx: worker process
   13 nginx     0:00 nginx: worker process
   14 uwsgi     0:00 uwsgi --master --enable-threads --processes 4 --threads 2 --gid uwsgi --uid uwsgi --module djangoProject.wsgi --http-socket :8080 --socket :3031
   16 uwsgi     0:00 uwsgi --master --enable-threads --processes 4 --threads 2 --gid uwsgi --uid uwsgi --module djangoProject.wsgi --http-socket :8080 --socket :3031
   17 uwsgi     0:00 uwsgi --master --enable-threads --processes 4 --threads 2 --gid uwsgi --uid uwsgi --module djangoProject.wsgi --http-socket :8080 --socket :3031
   20 uwsgi     0:00 uwsgi --master --enable-threads --processes 4 --threads 2 --gid uwsgi --uid uwsgi --module djangoProject.wsgi --http-socket :8080 --socket :3031
   22 root      0:00 /bin/sh
   30 root      0:00 ps
/app # 

# 独立部署
/app $ ps
PID   USER     TIME  COMMAND
    1 uwsgi     0:00 sh ./docker-entrypoint.sh
    8 uwsgi     0:00 uwsgi --ini /app/uwsgi.ini
    9 uwsgi     0:00 uwsgi --ini /app/uwsgi.ini
   10 uwsgi     0:00 uwsgi --ini /app/uwsgi.ini
   11 uwsgi     0:00 uwsgi --ini /app/uwsgi.ini
   12 uwsgi     0:00 uwsgi --ini /app/uwsgi.ini
   13 uwsgi     0:00 uwsgi --ini /app/uwsgi.ini
   14 uwsgi     0:00 uwsgi --ini /app/uwsgi.ini
   15 uwsgi     0:00 uwsgi --ini /app/uwsgi.ini
   16 uwsgi     0:00 uwsgi --ini /app/uwsgi.ini
  649 uwsgi     0:00 /bin/sh
  655 uwsgi     0:00 ps

更新日志

  • 2022/12/08 Dockerfile 增加 mysqlclient 依赖