部署前后端为独立的 Docker 节点
在『服务器部署 Vue 和 Django 项目的全记录』一文中,介绍了在服务器中使用 Nginx 部署前后端项目的过程。然而,当 Web 应用流量增多时,需要考虑负载均衡、流量分发、容灾等情况,原生的部署方式通常难以满足需求。此时,引入 Docker 部署多节点,能够在单台高性能服务器或服务器集群中搭建更完善的部署架构。
本文主要以 Vue 和 Django 项目为例介绍 Docker 部署的流程,稍带 Docker 简介和基础的 Nginx 负载均衡配置。
Docker 简介与安装
简单介绍 Docker 相关概念,具体需要读者另外学一学,推荐『Docker-从入门到实践』
Docker 是什么
Docker 是一个开源的应用容器引擎,可以让开发者打包应用和依赖到一个轻量级、可移植的容器中,并发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器使用沙箱机制,相互之间不存在接口,其与宿主机通过端口转发进行通信,性能开销低。
Docker 部署 Web 应用有以下优点:
- 容器适合持续集成和持续交付(CI/CD)流程
- 响应式部署和扩展,其可移植性和轻量级的特性支持实时扩展或拆除服务
- Docker 轻巧快速,支持开发者在同一机器上运行更多工作负载
Docker 工作流程
Docker 包括三个概念:
- 镜像(Image):相当于一个 root 文件系统。
- 容器(Container):镜像和容器的关系类似于对象程序设计中的类和实例,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker 的工作流程通常为:
- 从仓库中拉取(pull)官方或基准镜像
- 在 Dockerfile 中描述应用和安装依赖的指令,构建镜像
- 由镜像创建和运行容器
Docker 安装
部署架构
在不考虑多节点负载均衡时,本文的部署架构如下:
前后端项目分离部署,分别部署在两个 Nginx 节点,对应两个域名或两个端口。

Nginx + Docker 部署前端
首先,Vue 项目打包为 dist 文件夹,同目录下新建 Dockerfile、vhosts.conf 文件和 logs 文件夹,作用见下列代码块中的注释。
.
├── dist # Vue 项目打包用以部署的文件夹
├── Dockerfile # 用于建立 Docker 镜像
├── vhosts.conf # 容器中启动 Nginx 服务的配置文件
└── logs # 映射容器中的 Nginx 日志目录,以便在宿主机查看日志
Dockerfile 文件内容:
# 设置基础镜像
FROM nginx:latest
#设置CTS时区
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
# 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面
COPY ./dist /usr/share/nginx/html/
#用本地的 vhosts.conf 配置来替换 nginx 镜像里的默认配置
COPY vhosts.conf /etc/nginx/conf.d/vhosts.conf
vhosts.conf 文件内容:
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/host.access.log main;
error_log /var/log/nginx/error.log error;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
构建 Docker 镜像
在终端中输入以下命令,根据 Dockerfile 构建镜像。
docker build -f Dockerfile -t nginx/hsheng-mall:v1.0.0 .
# 镜像名称:nginx/hsheng-mall
# 版本号:v1.0.0
运行 Docker 容器
依据创建的镜像 nginx/hsheng-mall:v1.0.0 运行容器。
docker run -d -p 8081:80 --name=hsheng-mall -v /home/hsheng/www/hsheng-mall/logs:/var/log/nginx nginx/hsheng-mall:v1.0.0
# 宿主机 8081 端口映射容器 80 端口
# 容器名称:hsheng-mall
# 宿主机 /home/hsheng/www/hsheng-mall/logs 目录映射容器 /var/log/nginx 目录
# 镜像名称:nginx/hsheng-mall:v1.0.0
宿主机 Nginx 转发
与原生 Nginx 部署类似,在 /etc/nginx/conf.d 目录下创建配置文件 hsheng-mall.conf,内容如下:
server {
listen 443 ssl; # 端口,若部署 https 域名则为 443
server_name aaa.abc.com; # 域名或 IP
location / {
proxy_pass http://127.0.0.1:8081; # 转发本机(宿主机) 8081 端口,已与 Docker 端口建立映射
proxy_redirect default;
}
ssl_certificate /home/hsheng/www/hsheng-mall/ssl_certs/aaa.abc.com_bundle.crt; # ssl证书绝对路径
ssl_certificate_key /home/hsheng/www/hsheng-mall/ssl_certs/aaa.abc.com.key; # ssl证书私钥绝对路径
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
}
server {
listen 80;
server_name aaa.abc.com;
# 把http的域名请求转成https
return 301 https://$host$request_uri;
}
而后重启 Nginx 服务,即可通过 server_name 访问 Docker 的应用服务。
sudo nginx -s reload
Nginx + Docker 部署 uWSGI 后端
项目部署目录结构如下:
.
├── src # Django 项目源码
│ ├── manage.py
│ ├── requirements.txt # Python 项目依赖包
│ ├── uwsgi.ini # uWSGI 配置文件
│ ├── start.sh # Django 服务启动脚本
| └── ...
├── Dockerfile # 用于建立 Docker 镜像
└── logs # 映射容器中的 uWSGI 日志目录,以便在宿主机查看日志
Dockerfile 文件内容:
FROM python:3.8
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
RUN mkdir -p /var/www/html/backend
COPY ./src /var/www/html/backend/
WORKDIR /var/www/html/backend
RUN pip install -i https://pypi.doubanio.com/simple uwsgi
RUN pip install -i https://pypi.doubanio.com/simple/ -r requirements.txt
# Windows环境下编写的start.sh每行命令结尾有多余的\r字符,需移除
RUN sed -i 's/\r//' ./start.sh
RUN chmod +x ./start.sh
uwsgi.ini 文件内容:
[uwsgi]
socket = 0.0.0.0:8000 # 容器内 uWSGI 服务须为 0.0.0.0,以便与宿主机建立正常连接
project = backend
base = /var/www/html
base-app = hshengmall
chdir = %(base)/%(project)
wsgi-file = %(base)/%(project)/%(base-app)/wsgi.py
master = true
processes = 8
threads = 4
enable-threads = true
buffer-size = 65536
post-buffering = 32768
vacuum = true
pidfile = %(base)/uwsgi/%(project)-master.pid
daemonize = %(base)/uwsgi/uwsgi.log
chmod-socket = 664
# 设置一个请求的超时时间(秒),如果一个请求超过了这个时间,则请求被丢弃
harakiri = 300
# 当一个请求被harakiri杀掉会,会输出一条日志
harakiri-verbose = true
start.sh 文件内容:
python manage.py makemigrations&&
python manage.py migrate&&
uwsgi --ini /var/www/html/backend/uwsgi.ini
构建 Docker 镜像
在终端中输入以下命令,根据 Dockerfile 构建镜像。
docker build -f Dockerfile -t python/hsheng-mall-backend:v1.0.0 .
运行 Docker 容器
依据创建的镜像 python/hsheng-mall-backend:v1.0.0 运行容器。
docker run -it -p 8001:8000 --name=hsheng-mall-backend -v /home/hsheng/www/hsheng-mall-backend/logs:/var/www/html/uwsgi -d python/hsheng-mall-backend:v1.0.0
启动服务
进入容器:
docker exec -it <container_id> /bin/bash
运行启动脚本:
./start.sh
这样即成功启动了一个后端服务容器,若想做多节点负载均衡,可以修改端口映射关系,按上述步骤多创建和启动几个容器。
宿主机 Nginx 转发
在 /etc/nginx/conf.d 目录下创建配置文件 hsheng-mall-backend.conf,内容如下:
server {
listen 443 ssl;
server_name api-aaa.abc.com;
location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass 127.0.0.1:8001; # 转发本机(宿主机) 8001 端口,已与 Docker 端口建立映射
}
ssl_certificate /home/hsheng/www/hsheng-mall-backend/ssl_certs/api-aaa.abc.com_bundle.crt;
ssl_certificate_key /home/hsheng/www/hsheng-mall-backend/ssl_certs/api-aaa.abc.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
}
server {
listen 80;
server_name api-aaa.abc.com;
return 301 https://$host$request_uri;
}
而后重启 Nginx 服务,即可通过 server_name 请求后端服务。
sudo nginx -s reload
*Nginx 负载均衡
简略描述一个负载均衡的结构:Nginx + Docker 多节点部署架构。
前端节点为静态节点,通常只需要单个节点即可,可使用 CDN 加速优化访问。因此,当请求流量大时,主要通过增多后端 Docker+uWSGI 节点进行负载均衡。

为实现上图架构,首先根据本文第四章节「Docker 部署 uWSGI 后端节点」创建和启动 3 个 Docker 后端服务节点,分别映射至宿主机 8001 ~ 8003 端口。
而后,修改宿主机用于部署后端的 Nginx 配置文件,例如本文的 hsheng-mall-backend.conf,添加 upstream。修改后文件内容应为:
upstream uwsgicluster {
server 127.0.0.1:8001;
server 127.0.0.1:8002;
server 127.0.0.1:8003;
}
server {
listen 443 ssl;
server_name api-aaa.abc.com;
location / {
include /etc/nginx/uwsgi_params;
uwsgi_pass uwsgicluster # 转发上游集群
}
ssl_certificate /home/hsheng/www/hsheng-mall-backend/ssl_certs/api-aaa.abc.com_bundle.crt;
ssl_certificate_key /home/hsheng/www/hsheng-mall-backend/ssl_certs/api-aaa.abc.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
}
server {
listen 80;
server_name api-aaa.abc.com;
return 301 https://$host$request_uri;
}
可以看到,与单节点不同之处在于,新增了 upstream 定义,并将 uwsgi_pass 修改为定义的 upstream 名称。
在配置文件中,还能设置各个节点的权重分配等,此处不展开介绍,默认为轮询方式,请求随机派发到各节点。
部署前后端为独立的 Docker 节点的更多相关文章
- Docker 部署前后端项目
Docker 部署前后端项目 平生不会相思,才会相思,便害相思. 简介:都是被逼的,从零开始一个Docker 部署九个微服务和三个前端项目.其中,这些服务需要用到Nacos.MySQL.Nginx.E ...
- Docker Compose 部署前后端分离应用
部署前后端分离应用 容器化 Abp 应用 关于 Abp 应用的容器化,其实和普通的 ASP.NET Core 应用差不多,大家可以参考我此前的文章. 唯一需要注意的是:因为 Abp 解决方案中有多个项 ...
- 使用 Nginx 部署前后端分离项目,解决跨域问题
前后端分离这个问题其实松哥和大家聊过很多了,上周松哥把自己的两个开源项目部署在服务器上以帮助大家可以快速在线预览(喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了 ...
- Nginx部署前后端分离服务
飘过... 一,安装Nginx 二,配置nginx 一般nginx配置文件在etc目录下 另,如何找nginx.conf配置文件: 在前后端分离端项目里,前端的代码会被打包成为纯静态文件.使用 Ngi ...
- linux --- 部署前后端分离项目
vue + uwsgi +nginx 部署前后端分离项目 准备项目 1.将前端vue项目包和后端django项目包上传服务器,通过lrzsz,直接从windows拖进linux中 2.解压缩操作 前端 ...
- centos7部署前后端分离项目的过程
概述 本文主要讲解在安装了centos7的Linux主机中部署前后端分离项目的过程. 前端项目名为:vue_project:后端项目名为:django_project. 将这两个项目放在/opt/wh ...
- 在centos7.6上部署前后端分离项目Nginx反向代理vue.js2.6+Tornado5.1.1,使用supervisor统一管理服务
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_102 这一次使用vue.js+tornado的组合来部署前后端分离的web项目,vue.js不用说了,前端当红炸子鸡,泛用性非常广 ...
- docker+nginx+redis部署前后端分离项目!!!
介绍本文用的经典的前后端分离开源项目.项目的拉取这些在另一篇博客!!! 其中所需要的前后端打包本篇就不做操作了!!不明白的去看另一篇博客!!! 地址:http://www.cnblogs.com/ps ...
- 海纳百川无所不容,Win10环境下使用Docker容器式部署前后端分离项目Django+Vue.js
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_179 随着现代化产品研发的不断推进,我们会发现,几乎每个产品线都会包含功能各异的服务,而且服务与服务之间存在也会存在着错综复杂的依 ...
随机推荐
- [BZOJ5449] 序列
题目链接:序列 Description 给定一个\(1\)~\(n\)的排列x,每次你可以将 \(x_1, x_2, ..., x_i\) 翻转. 你需要求出将序列变为升序的最小操作次数. 多组数据. ...
- 什么是Netty编解码,Netty编解码器有哪些?Protostuff怎么使用?
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,昨天下雨没怎么上街上 ...
- Spring框架系列(2) - Spring简单例子引入Spring要点
上文中我们简单介绍了Spring和Spring Framework的组件,那么这些Spring Framework组件是如何配合工作的呢?本文主要承接上文,向你展示Spring Framework组件 ...
- 针对elementUI 中InfiniteScroll按需引入的一点注意事项
大家为了节省空间,常常进行按需引入来节省空间,这里我给大家来介绍一下element中按需引入无限滚动指令注意的事项. 针对前面element 按需引入的一些配置这里就不再详细介绍了. 那么这里讲的是在 ...
- Prometheus安装教程
Prometheus安装教程 欢迎关注H寻梦人公众号 参考目录 docker安装Prometheus 基于docker 搭建Prometheus+Grafana prometheus官方文档 dock ...
- RPA应用场景-银行回单查询
场景概述银行回单查询 所涉系统名称银行网银 人工操作(时间/次) 5 分钟 所涉人工数量 4 操作频率不定时 场景流程 1.收到外派业务员申请查询收入银行回单的邮件: 2.依据邮件中提供的客户信息进入 ...
- 实践GoF的23种设计模式:装饰者模式
摘要:装饰者模式通过组合的方式,提供了能够动态地给对象/模块扩展新功能的能力.理论上,只要没有限制,它可以一直把功能叠加下去,具有很高的灵活性. 本文分享自华为云社区<[Go实现]实践GoF的2 ...
- 体验SRCNN和FSRCNN两种图像超分网络应用
摘要:图像超分即超分辨率,将图像从模糊的状态变清晰. 本文分享自华为云社区<图像超分实验:SRCNN/FSRCNN>,作者:zstar. 图像超分即超分辨率,将图像从模糊的状态变清晰.本文 ...
- 浏览器js调试
经常忘记,还是需要记录一下啊 右键,检查元素 在元素DOM节点右击,复制CSS选择器 function sleep (time) { return new Promise((resolve) => ...
- Hash 哈希表和算法思路详解
概述 哈希表是一种可以满足快速查找数据结构,时间复杂度接近O(1). 哈希函数是无限集到有限集的映射. 处理数据量大,查找效率要求高时推荐使用hash容器. 问题: 什么情况下考虑使用哈希容器? 常用 ...