提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
背景
公司给一些客户要部署三个前端项目。
最初,每个前端项目都以独立的镜像形式交付并部署。然而,随着客户数量的增加,每个客户都提出了一些自定义需求,后端也进行了对应改造。这导致了部署过程变得复杂且繁琐,因为每个客户都需要单独的配置和镜像,增加了运维的工作量和出错的风险。
为了解决这一问题,团队进行了技术改造,将多个前端项目打包到一个 Nginx 镜像中。通过动态修改 Nginx 的配置文件,实现了每个客户的前端项目能够代理到对应客户的后端服务上。这种改造不仅减少了交付的镜像数量,还减轻了运维同事的工作量。现在,运维团队只需要在构建镜像时传递对应的客户STACK_NAME,即可完成配置,无需再逐一确认和修改配置文件内容,从而提高了部署的效率和准确性,更好地满足了客户需求。
后端服务依然是多个,启动时docker的服务名称上增加了STACK_NAME,通过Nginx去反向代理。
正文
有以下两种方案,因为客户希望是一个固定的域名,所以本文采用第一种
- 基于路径区分服务:通过 URL 路径(如 /service1 和 /service2)区分两个前端服务。
基于子域名区分服务:通过子域名(如 service1.example.com 和 service2.example.com )区分两个前端服务。
DockerFile
- 把项目分别clone到项目路径,切换到打包分支
- 将打包好的静态资源替换到Nginx的html目录
- 替换Nginx的配置模板,并使用shell脚本动态转递参数
# 使用 Node.js 作为构建环境
FROM node:16-alpine as builder
# 安装 Git
RUN apk add --no-cache git
# 克隆项目1并打包
RUN git clone https://github.com/zacks-xdc/project1.git /app/project1 && \
cd /app/project1 && \
git checkout release && \
npm install && \
npm run build
# 克隆项目2并打包
RUN git clone https://github.com/zacks-xdc/project2.git /app/project2 && \
cd /app/project2 && \
git checkout release && \
npm install && \
npm run build
# 使用 Nginx 作为运行环境
FROM nginx:alpine
# 复制静态资源到 Nginx 的 HTML 目录
COPY --from=builder /app/project1/dist /usr/share/nginx/html/project1
COPY --from=builder /app/project2/dist /usr/share/nginx/html/project2
# 复制 Nginx 配置模板和启动脚本
COPY nginx.conf.template /etc/nginx/nginx.conf.template
COPY start.sh /start.sh
# 设置启动脚本权限
RUN chmod +x /start.sh
# 设置环境变量默认值
ENV DOMAIN=localhost
ENV STACK_NAME=default
# 暴露端口
EXPOSE 80
# 启动容器时运行脚本
CMD ["/start.sh"]
Nginx 配置模板接收变量并替换
server {
listen 80;
server_name ${DOMAIN};
location /project1 {
root /usr/share/nginx/html/project1;
index index.html;
try_files $uri $uri/ /index.html;
}
location /project1/api {
proxy_pass http://${STACK_NAME}_sys-api:5000/;
}
location /project2 {
root /usr/share/nginx/html/project2;
index index.html;
try_files $uri $uri/ /index.html;
}
location /project2/api {
proxy_pass http://${STACK_NAME}_knowledge-api:6001;
}
}
Shell 脚本将Nginx配置模板替换成配置文件
#!/bin/sh
# 读取环境变量
STACK_NAME=${STACK_NAME}
DOMAIN=${DOMAIN}
# 替换模板文件中的占位符
envsubst '${STACK_NAME},${DOMAIN}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
# 启动 Nginx
exec nginx -g 'daemon off;'
使用
构建镜像
docker build -t mixed-nginx .
运行容器
docker run -d \
-e DOMAIN=example.com \
-e STACK_NAME=company1 \
-p 80:80 \
mixed-nginx
总结
本次技术改造将多个前端项目整合到一个 Nginx 镜像中,并实现动态配置。有以下好处:
- 简化部署流程:通过将多个前端项目打包到一个 Nginx 镜像中,减少了交付的镜像数量。这使得部署过程更加简化,避免了以往逐一确认和修改配置文件的繁琐操作。
- 提高运维效率,降低出错风险:运维团队现在只需在构建镜像时传递对应的STACK_NAME,即可完成配置,无需再逐一确认和修改配置文件内容,减少手动修改配置文件的步骤,降低了因人为操作失误导致的配置错误风险,提高了部署的准确性和可靠性。
- 增强灵活性:动态修改 Nginx 配置文件的能力,使得每个客户的前端项目能够灵活地代理到对应客户的后端服务上。
- 提升可维护性:集中管理配置文件,使得未来的维护和更新更加方便。只需在 Nginx 镜像中进行统一的配置管理,即可应用于所有前端项目。