[ Django部署 ]


部署docker compose

docker-compose.yml

version: "3"
services:
  dvadmin-web:
    container_name: dvadmin-web
    ports:
      - "8080:8080"
    build:
      context: ./
      dockerfile: ./docker_env/web/Dockerfile
    environment:
      TZ: Asia/Shanghai
    volumes:
      - ./docker_env/nginx/my.conf:/etc/nginx/conf.d/my.conf
    expose:
      - "8080"
    networks:
      network:
        ipv4_address: 177.8.0.11

  dvadmin-django:
    build:
      context: .
      dockerfile: ./docker_env/django/Dockerfile
    container_name: dvadmin-django
    working_dir: /backend
# 打开mysql 时,打开此选项
#    depends_on:
#      - dvadmin-mysql
    environment:
      PYTHONUNBUFFERED: 1
      DATABASE_HOST: dvadmin-mysql
      TZ: Asia/Shanghai
    volumes:
      - ./backend:/backend
      - ./logs/log:/var/log
    ports:
      - "8000:8000"
    expose:
      - "8000"
    restart: always
    networks:
      network:
        ipv4_address: 177.8.0.12

#  dvadmin-mysql:
#    image: mysql:5.7
#    container_name: dvadmin-mysql
#    #使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限
#    #设置为true,不然数据卷可能挂载不了,启动不起
##    privileged: true
#    restart: always
#    ports:
#      - "3306:3306"
#    environment:
#      MYSQL_ROOT_PASSWORD: "123456"
#      MYSQL_DATABASE: "dvadmin_pro"
#      TZ: Asia/Shanghai
#    command:
#      --wait_timeout=31536000
#      --interactive_timeout=31536000
#      --max_connections=1000
#      --default-authentication-plugin=mysql_native_password
#    volumes:
#      - "./docker_env/mysql/data:/var/lib/mysql"
#      - "./docker_env/mysql/conf.d:/etc/mysql/conf.d"
#      - "./docker_env/mysql/logs:/logs"
#    networks:
#      network:
#        ipv4_address: 177.8.0.13


# 如果使用celery 插件,请自行打开此注释
#  dvadmin-celery:
#    build:
#      context: .
#      dockerfile: ./docker_env/celery/Dockerfile
#    # image: django:2.2
#    container_name: dvadmin-celery
#    working_dir: /backend
#    depends_on:
#      - dvadmin-mysql
#    environment:
#      PYTHONUNBUFFERED: 1
#      DATABASE_HOST: dvadmin-mysql
#      TZ: Asia/Shanghai
#    volumes:
#      - ./backend:/backend
#      - ./logs/log:/var/log
#    restart: always
#    networks:
#      network:
#        ipv4_address: 177.8.0.14


# dvadmin-redis:
#   image: redis:6.2.6-alpine # 指定服务镜像,最好是与之前下载的redis配置文件保持一致
#   container_name: dvadmin-redis # 容器名称
#   restart: on-failure # 重启方式
#   environment:
#     - TZ=Asia/Shanghai # 设置时区
#   volumes: # 配置数据卷
#     - ./docker_env/redis/data:/data
#     - ./docker_env/redis/redis.conf:/etc/redis/redis.conf
#   ports: # 映射端口
#     - "6379:6379"
#   sysctls: # 设置容器中的内核参数
#     - net.core.somaxconn=1024
#   command: /bin/sh -c "echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf && redis-server /etc/redis/redis.conf --appendonly yes" # 指定配置文件并开启持久化
#   privileged: true # 使用该参数,container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限
#   networks:
#     network:
#       ipv4_address: 177.8.0.15


networks:
  network:
    ipam:
      driver: default
      config:
        - subnet: '177.8.0.0/16'

dockerfile

  • cmd="cp -i ./conf/env.example.py ./conf/env.py ":此行将字符串赋值给变量cmd,字符串内容是要执行的cp命令,即复制文件。
  • print "n" |cmd:这一行使用管道符|将字符串"n"传递给变量cmd中的命令。这里的目的是模拟用户输入n,以回答复制文件时的覆盖提示。
FROM registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/python38-base-backend:latest
WORKDIR /backend
COPY ./backend/ .
RUN awk 'BEGIN { cmd="cp -i ./conf/env.example.py   ./conf/env.py "; print "n" |cmd; }'
RUN python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ -r requirements.txt
CMD ["/backend/docker_start.sh"]

dockerfileBuild

FROM python:3.8-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk update && apk add bash bash-doc bash-completion git freetds-dev jpeg-dev linux-headers mysql-client mariadb-dev build-base libffi-dev openssl-dev zlib-dev bzip2-dev pcre-dev ncurses-dev readline-dev tk-dev postgresql-dev
WORKDIR /backend
COPY ./backend/requirements.txt .
COPY ./docker_env/requirements-all.txt .
RUN python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ -r ./requirements.txt
RUN python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ -r ./requirements-all.txt

backend/docker_start.sh

#!/bin/bash
# python manage.py makemigrations
# python manage.py migrate
# python manage.py init -y
#gunicorn -c gunicorn_conf.py application.asgi:application
uvicorn application.asgi:application --port 8000 --host 0.0.0.0 --workers 4

backend/gunicorn_conf.py

# gunicorn.conf
# coding:utf-8
# 启动命令:gunicorn -c gunicorn.py application.asgi:application
import multiprocessing
# 并行工作进程数, int,cpu数量*2+1 推荐进程数
workers = multiprocessing.cpu_count() * 2 + 1
# 指定每个进程开启的线程数
threads = 3
# 绑定的ip与端口
bind = '0.0.0.0:8000'
# 设置守护进程,将进程交给第三方管理
daemon = 'false'
# 工作模式协程,默认的是sync模式,推荐使用 gevent,此处使用与uvicorn配合使用 uvicorn.workers.UvicornWorker
worker_class = 'uvicorn.workers.UvicornWorker'
# 设置最大并发量(每个worker处理请求的工作线程数,正整数,默认为1)
worker_connections = 10000
# 最大客户端并发数量,默认情况下这个值为1000。此设置将影响gevent和eventlet工作模式
# 每个工作进程将在处理max_requests请求后自动重新启动该进程
max_requests = 10000
max_requests_jitter = 200
# 设置进程文件目录
pidfile = './gunicorn.pid'
# 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
loglevel = 'info'
# 设置gunicorn访问日志格式,错误日志无法设置
access_log_format = '' # worker_class 为 uvicorn.workers.UvicornWorker 时,日志格式为Django的loggers
# 监听队列
backlog = 512
#进程名
proc_name = 'gunicorn_process'
# 设置超时时间120s,默认为30s。按自己的需求进行设置timeout = 120
timeout = 120
# 超时重启
graceful_timeout = 300
# 在keep-alive连接上等待请求的秒数,默认情况下值为2。一般设定在1~5秒之间。
keepalive = 3
# HTTP请求行的最大大小,此参数用于限制HTTP请求行的允许大小,默认情况下,这个值为4094。
# 值是0~8190的数字。此参数可以防止任何DDOS攻击
limit_request_line = 5120
# 限制HTTP请求中请求头字段的数量。
#  此字段用于限制请求头字段的数量以防止DDOS攻击,与limit-request-field-size一起使用可以提高安全性。
# 默认情况下,这个值为100,这个值不能超过32768
limit_request_fields = 101
# 限制HTTP请求中请求头的大小,默认情况下这个值为8190。
# 值是一个整数或者0,当该值为0时,表示将对请求头大小不做限制
limit_request_field_size = 0
# 记录到标准输出
accesslog = '-'

backend/conf/env.example.py

import os

from application.settings import BASE_DIR

# ================================================= #
# *************** mysql数据库 配置  *************** #
# ================================================= #
# 数据库 ENGINE ,默认演示使用 sqlite3 数据库,正式环境建议使用 mysql 数据库
# sqlite3 设置
DATABASE_ENGINE = "django.db.backends.sqlite3"
DATABASE_NAME = os.path.join(BASE_DIR, "db.sqlite3")

# 使用mysql时,改为此配置
# DATABASE_ENGINE = "django.db.backends.mysql"
# DATABASE_NAME = 'django-vue-admin' # mysql 时使用

# 数据库地址 改为自己数据库地址
DATABASE_HOST = "127.0.0.1"
# # 数据库端口
DATABASE_PORT = 3306
# # 数据库用户名
DATABASE_USER = "root"
# # 数据库密码
DATABASE_PASSWORD = "123456"

# 表前缀
TABLE_PREFIX = "dvadmin_"
# ================================================= #
# ******** redis配置,无redis 可不进行配置  ******** #
# ================================================= #
# REDIS_PASSWORD = ''
# REDIS_HOST = '127.0.0.1'
# REDIS_URL = f'redis://:{REDIS_PASSWORD or ""}@{REDIS_HOST}:6380'
# ================================================= #
# ****************** 功能 启停  ******************* #
# ================================================= #
DEBUG = True
# 启动登录详细概略获取(通过调用api获取ip详细地址。如果是内网,关闭即可)
ENABLE_LOGIN_ANALYSIS_LOG = True
# 登录接口 /api/token/ 是否需要验证码认证,用于测试,正式环境建议取消
LOGIN_NO_CAPTCHA_AUTH = True
# 是否启动API日志记录
API_LOG_ENABLE = locals().get("API_LOG_ENABLE", True)
# API 日志记录的请求方式
API_LOG_METHODS = locals().get("API_LOG_METHODS", ["POST", "UPDATE", "DELETE", "PUT"])
# API_LOG_METHODS = 'ALL' # ['POST', 'DELETE']
# ================================================= #
# ****************** 其他 配置  ******************* #
# ================================================= #
ENVIRONMENT = "local"  # 环境,test 测试环境;prod线上环境;local本地环境
ALLOWED_HOSTS = ["*"]
# 系统配置存放位置:redis/memory(默认)
DISPATCH_DB_TYPE = 'redis'