从零开始 - Docker部署前后端分离项目(三)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: **此django项目部署采用的方案****nginx+gunicorn**容器环境及需要启动的服务:1. python3.8的 (使用的是小型的3.8-alpine)2. celery worker3. celery beate server4. gunicorn

一、 项目框架图

img

此django项目部署采用的方案nginx+gunicorn

容器环境及需要启动的服务:

  1. python3.8的 (使用的是小型的3.8-alpine)
  2. celery worker
  3. celery beate server
  4. gunicorn

二、文件最终目录

AndroidPlatform
  |- nginx_docker
    |-- dist
    |-- static
    |-- default.conf
    |-- Dockerfile
    
  |- XZAndroidPlatform
    |-- logs
    |-- scripts
    |-- xiaozai_app
    |-- XZAndroidPlatform
    |-- Dockerfile
    |-- entrypoint.sh
    |-- gunicorn.conf.py
    |-- manage.py
    |-- requirements.txt
    |-- supervisord.conf
    
  |- docker-compose.yml
  |- start.sh

三、项目文件介绍

1.AndroidPlatform

整个项目文件,里面有两个文件夹,nginx_docker用于存放前后端静态文件,XZAndroidPlatform是整个django项目文件。

包含两个文件,docker-compose.yml、start.sh(可有可无)

2.XZAndroidPlatform后端文件

整个django项目拿过来即可。

需生成的文件为:requirements.txt

需编写的文件为:Dockerfile、entrypoint.sh、gunicorn.conf.py、supervisord.conf

3.nginx_docker静态文件

需生成的文件为:包含前端vue打包的dist文件,django后端的static静态资源文件。

需编写的文件为:default.conf、Dockerfile

四、django后端环境准备

1、django后端项目依赖导出

pip freeze > requirements.txt

img

在requirements文件中增加相关部署依赖:

mysqlclient==2.1.0
gunicorn==20.1.0
supervisor==4.2.4

完整requirements.txt文件如下

BeautifulReport==0.1.3
certifi==2021.10.8
charset-normalizer==2.0.12
Django==2.2
django-cors-headers==3.11.0
idna==3.3
lxml==4.8.0
python-docx==0.8.11
pytz==2021.3
requests==2.27.1
sqlparse==0.4.2
urllib3==1.26.9
mysqlclient==2.1.0
gunicorn==20.1.0
supervisor==4.2.4

2、django后端项目配置修改

setting.py 文件

DEBUG = False

ALLOWED_HOSTS = ['127.0.0.1', '填你所部署服务所在的IP']  # 运行主机,或域名,可以填['*']代表允许所有

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware', #第三方解决跨域头问题的中间件
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'xiaozai',
        'HOST': 'mariadb',  # 以mariadb的容器名为host
        'USER': 'root',
        'PASSWORD': 'xiaozai123'

    }
}

# 方案一:允许跨域的域名列表
CORS_ALLOWED_ORIGINS = [

    'http://198.162.111.111:8080'  # 修改为你的前端部署的项目地址
]

# 方案二:我采用的
CORS_ORIGIN_ALLOW_ALL = True #加上允许所有跨域

3、收集django项目中的静态文件

在配置文件中配置STATIC_ROOT

STATIC_ROOT = BASE_DIR / 'static' #如果运行报错,则用下面的
STATIC_ROOT = = os.path.join(BASE_DIR,'static')

然后运行命令:

python manage.py collectstatic

会将所有的静态收集到STATIC_ROOT目录中。

img

这个static文件夹后续需要复制到nginx_docker文件夹中。

4、配置文件

django项目目录下新建logs文件夹,存放后续配置运行的日志。

(1)gunicorn.conf.py

bind = '0.0.0.0:8000'                 # 监听主机和端口
pidfile = 'logs/gunicorn.pid'         # pid文件
accesslog = 'logs/gunicorn_access.log'    # 通过的日志
errorlog = 'logs/gunicorn_error.log'      # 错误日志

(2)supervisord.conf

把XZAndroidPlatform.wsgi修改为你django的项目名.wsgi

[unix_http_server]
file=/tmp/supervisor.sock   ; the path to the socket file

[supervisord]
logfile=logs/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=logs/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=true               ; start in foreground if true; default false
silent=false                 ; no logs to stdout if true; default false
minfds=1024                  ; min. avail startup file descriptors; default 1024
minprocs=200                 ; min. avail process descriptors;default 200

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket

[program:gunicorn]
command=gunicorn -c gunicorn.conf.py XZAndroidPlatform.wsgi

(3)entrypoint.sh

小知识

/dev/null 文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:

$ command > /dev/null

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

创建的超级用户账号密码,可以自己自行更改。

#! /bin/sh
# 1. 数据库迁移
python manage.py makemigrations
python manage.py migrate
# 因为后使用脚本部署时,可能数据库还没有准备好,这里连接会失败
if [ $? -ne 0 ];then
    echo '数据库连接失败重启'
    exit 1
fi
# 2.创建管理员用户
echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('xiaozai', '13888888888', 'xiaozai123') " | python manage.py shell &> /dev/null
# 3. 启动supervisor

supervisord -c supervisord.conf

(4)Dockerfile

FROM python:3.8-alpine
LABEL maintainer='xiaozai'
LABEL description='Django project'

# 创建/app目录并切换进目录下
# 第一个WORKDIR要用绝对路径
WORKDIR /app
# 把dockerfile当前目录下的所有文件拷贝进镜像的/app目录下
COPY . .

# 安装必要的库
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && \
    apk update && \
    apk upgrade && \
    apk add --no-cache tzdata mariadb-dev gcc libc-dev && \
    cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo "Asia/Shanghai" > /etc/timezone && \
    python -m pip install -i https://pypi.douban.com/simple --upgrade pip && \
    pip install --no-cache-dir -i https://pypi.douban.com/simple -r requirements.txt && \
    chmod 777 ./entrypoint.sh

# 创建一个日志挂载点避免容器越来越大
VOLUME /app/logs/

# 挂载端口,它并不会做端口映射,只是告诉用户,该镜像的挂载端口
EXPOSE 8000

# 容器的默认执行命令
# CMD 'supervisord -c supervisord.conf'
ENTRYPOINT ["./entrypoint.sh"]

五、nginx_docker静态资源准备

讲上文中django打包好的static文件夹复制到nginx_docker文件夹中。

1、前端部署-前端vue项目

前端中所有用到后端的接口,都需要改成对应部署所在的服务器地址,如上文的192.168.111.111

打包前端项目打包的时候一定要修改host,打包完成之后,将dist文件夹拷贝到nginx_docker文件夹中。

打包命令

npm run build

2、部署静态文件default.conf

nginx_docker文件夹中创建default.conf文件,编写如下内容:

域名记得改成自己的

upstream app_server {
    server XZAndroidPlatform:8000;    # 配置gunicorn服务器主机和端口
}


server {
   listen       8001;  # 配置后端服务的监听端口
   server_name  192.168.111.111;  # 配置域名
    # http://106.14.168.21:8000/static/rest_framework/css/bootstrap.min.css
    # /usr/share/nginx/html/static/rest_framework/css/bootstrap.min.css
   location /static/ {
      alias /usr/share/nginx/html/static/;  # 配置静态文件路径
   }
   
   location / {
      # 检查静态文件,如果不是代理到应用
      try_files $uri @proxy_to_app;
   }

   location @proxy_to_app {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://app_server;
   } 

   
   #error_page  404              /404.html;

     # redirect server error pages to the static page /50x.html
     #
     error_page   500 502 503 504  /50x.html;
     location = /50x.html {
        root   /usr/share/nginx/html;
     }

  }

  server {
    listen 80;  # 配置前端项目服务的监听端口
    server_name   192.168.111.111;  # 配置域名主机
    root /usr/share/nginx/html/dist;       # 配置文件根路径

    location / {
       try_files $uri $uri/ @router; #需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
       index index.html;
    }

    #对应上面的@router,主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件
    #因此需要rewrite到index.html中,然后交给路由在处理请求资源
    location @router {
             rewrite ^.*$ /index.html last;
    }

}

3、Dockerfile

FROM nginx:alpine

COPY ./static/ /usr/share/nginx/html/static/
COPY ./dist/ /usr/share/nginx/html/dist/
COPY ./default.conf /etc/nginx/conf.d/

VOLUME /var/log/
EXPOSE 8001 80

六、docker-compose.yml

下载docker-compose

pip install docker-compose

检测是否安装成功

docker-compoese --version

不论是Dockerfile还是docker-compose.yml脚本的编写都依赖上下文,所以需要明确部署文件夹的项目结构。

项目结构在本节开篇已经详细说明了,这里再写一个大致的目录

AndroidPlatform
  |- nginx_docker
    |-- dist
    |-- static
    |-- default.conf
    |-- Dockerfile
    
  |- XZAndroidPlatform
    |-- 其他项目文件和文件夹
    |-- Dockerfile
    |-- entrypoint.sh
    
  |- docker-compose.yml

1、编写docker-compose.yml文件

version: "3"
services:  # 要启动的 容器服务
    redis:  # 容器名称
        image: redis:alpine   # 指定构建的镜像
        restart: always      # 重启策略
        volumes:             # 指定数据卷
            - redis_data:/data
    mariadb:
        image: mariadb
        restart: always 
        environment:        # 设置环境变量
            MARIADB_ROOT_PASSWORD: xiaozai123
            MARIADB_DATABASE: xiaozai
        volumes:
            - mariadb_data:/var/lib/mysql
    XZAndroidPlatform:
        depends_on:    # 指定依赖服务,等依赖的容器启动后再启动
            - redis
            - mariadb
        build: ./XZAndroidPlatform/   # 指定Dockerfile的路径
        image: mwj_XZAndroidPlatform  # 给镜像取个tag
        volumes:
            - app_logs:/app/logs/
        restart: always
    nginx:
        depends_on:
            - XZAndroidPlatform
        build: ./nginx_docker/
        image: mwj_nginx
        restart: always
        ports:
            - "80:80"
            - "8001:8001"
        volumes:
            - nginx_logs:/var/log/
volumes:  # 定义的数据卷
    redis_data:
    mariadb_data:
    app_logs:
    nginx_logs:

然后再XZAndroidPlatform目录下运行命令docker-compose -p mwj up -d --build,即可以部署项目。

2、部署完成

img

下篇内容:

1、start.sh一键自动化部署脚本的编写。

2、如何删除已构建的docker项目,再次快速部署。

相关文章
|
1月前
|
数据采集 存储 Docker
深入理解Docker:为你的爬虫项目提供隔离环境
本教程介绍如何使用Docker构建隔离环境,运行Python爬虫项目,采集小红书视频页面的简介和评论。主要内容包括: 1. **Docker隔离环境**:通过Docker容器化爬虫,确保环境独立、易于部署。 2. **代理IP技术**:利用亿牛云爬虫代理突破反爬限制。 3. **Cookie与User-Agent设置**:伪装请求头,模拟真实用户访问。 4. **多线程采集**:提高数据采集效率。 前置知识要求:Python基础、Docker基本操作及HTML解析(可选)。教程还涵盖常见错误解决方法和延伸练习,帮助你优化爬虫代码并避免陷阱。
深入理解Docker:为你的爬虫项目提供隔离环境
|
26天前
|
消息中间件 监控 RocketMQ
Docker部署RocketMQ5.2.0集群
本文详细介绍了如何使用Docker和Docker Compose部署RocketMQ 5.2.0集群。通过创建配置文件、启动集群和验证容器状态,您可以快速搭建起一个RocketMQ集群环境。希望本文能够帮助您更好地理解和应用RocketMQ,提高消息中间件的部署和管理效率。
218 91
|
27天前
|
存储 NoSQL Redis
Docker 部署 Redis
在使用 Docker 部署 Redis 时,为实现数据持久化,需正确挂载容器内的数据目录到宿主机。推荐命令如下: ``` docker run -d --name redis -v /mnt/data/redis:/data -p 6379:6379 redis ``` 该命令将宿主机的 `/mnt/data/redis` 目录挂载到容器的 `/data` 目录,确保 Redis 数据持久化。此路径更通用,适合大多数场景。避免使用不匹配的挂载路径,如 `/var/lib/redis` 或 `/mnt/data/redis` 到非默认目录,以防止数据无法正确持久化。
|
17天前
|
人工智能 文字识别 安全
Stirling-PDF:51.4K Star!用Docker部署私有PDF工作站,支持50多种PDF操作,从此告别在线工具
Stirling-PDF 是一款基于 Docker 的本地化 PDF 编辑工具,支持 50 多种 PDF 操作,包括合并、拆分、转换、压缩等,同时提供多语言支持和企业级功能,满足个人和企业用户的多样化需求。
72 6
Stirling-PDF:51.4K Star!用Docker部署私有PDF工作站,支持50多种PDF操作,从此告别在线工具
|
1月前
|
JavaScript 前端开发 Docker
如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
通过这些步骤,可以确保您的Next.js应用在多核服务器上高效运行,并且在Docker环境中实现高效的容器化管理。
142 44
|
14天前
|
中间件 关系型数据库 数据库
docker快速部署OS web中间件 数据库 编程应用
通过Docker,可以轻松地部署操作系统、Web中间件、数据库和编程应用。本文详细介绍了使用Docker部署这些组件的基本步骤和命令,展示了如何通过Docker Compose编排多容器应用。希望本文能帮助开发者更高效地使用Docker进行应用部署和管理。
44 19
|
5天前
|
Linux 虚拟化 Docker
Linux服务器部署docker windows
在当今软件开发中,Docker成为流行的虚拟化技术,支持在Linux服务器上运行Windows容器。流程包括:1) 安装Docker;2) 配置支持Windows容器;3) 获取Windows镜像;4) 运行Windows容器;5) 验证容器状态。通过这些步骤,你可以在Linux环境中顺利部署和管理Windows应用,提高开发和运维效率。
42 1
|
Java 应用服务中间件 Linux
使用docker部署springboot项目小白教程
使用docker部署springboot项目小白教程
650 0
|
10月前
|
NoSQL Java Redis
利用Docker部署一个简单的springboot项目
利用Docker部署一个简单的springboot项目
238 2
|
10月前
|
Java 关系型数据库 MySQL
docker 部署springboot项目,连接mysql容器
docker 部署springboot项目,连接mysql容器
383 0