前端项目容器化部署看似简单,但实际操作中往往会遇到各种"坑"。最近在接手一个遗留项目时,发现前任工程师的部署方案存在不少值得商榷的地方。最典型的就是Nginx配置中硬编码了upstream服务器地址,导致镜像可移植性极差。这种配置方式在开发环境可能运行良好,但一旦需要迁移到其他环境(如测试、生产),就必须重新构建镜像,完全违背了容器化"一次构建,随处运行"的理念。
在当前的Nginx配置中,upstream被硬编码在nginx.conf文件中:
nginx复制upstream proxyServer{
server 10.101.10.6:31350 weight=1;
server 10.101.10.7:31350 weight=1;
server 10.101.10.8:31350 weight=1;
}
这种配置方式存在几个明显问题:
更优雅的做法是通过环境变量动态配置upstream。修改后的Nginx配置如下:
nginx复制upstream proxyServer{
server ${PROXY_SERVER_1} weight=1;
server ${PROXY_SERVER_2} weight=1;
server ${PROXY_SERVER_3} weight=1;
}
然后在Docker启动时注入环境变量:
bash复制docker run -e PROXY_SERVER_1=10.101.10.6:31350 \
-e PROXY_SERVER_2=10.101.10.7:31350 \
-e PROXY_SERVER_3=10.101.10.8:31350 \
my-nginx-image
对于更复杂的场景,可以使用envsubst或gomplate等工具在容器启动时动态生成配置文件:
dockerfile复制FROM nginx:alpine
COPY nginx.conf.template /etc/nginx/templates/
CMD ["/bin/sh", "-c", "envsubst < /etc/nginx/templates/nginx.conf.template > /etc/nginx/nginx.conf && nginx -g 'daemon off;'"]
Jenkins作为CI/CD的核心工具,其容器化部署需要注意以下几点:
bash复制docker run -tid --restart=always -d --user root --privileged=true \
-v /etc/localtime:/etc/localtime \
-p 8080:8080 -p 50000:50000 \
-v /home/jenkins/:/var/jenkins_home \
-v $(which docker):/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/lib/jvm:/usr/lib/jvm:ro \
-v /home/maven:/usr/local/maven \
--name jenkins jenkins/jenkins:2.346.1-lts
关键配置说明:
在Jenkins容器内配置Git访问权限:
bash复制ssh-keygen -t rsa -b 4096 -C "eayc@jenkins"
cat /root/.ssh/id_rsa.pub
将生成的公钥添加到Git服务器,测试连接:
bash复制git ls-remote -h git@10.101.10.3:/eayc/acc/micro/acc-voucher.git
对于Git Parameter插件安装失败的问题,可以采用离线安装方式:
注意:某些插件可能有依赖关系,需要同时安装依赖插件
微服务间通信失败常见原因是容器网络隔离:
bash复制docker inspect eayc-user-server | grep -A 15 "Networks"
docker inspect acc-mbms-server | grep -A 15 "Networks"
输出显示两个服务位于不同网络:
创建共享网络并修改docker-compose.yml:
bash复制docker network create eayc-network
修改后的docker-compose.yml:
yaml复制version: '3.8'
networks:
eayc-network:
external: true
services:
acc-mbms-server:
image: 10.101.10.9:8081/eayc/acc-mbms-server:3.0.0-2026.3.22-3
networks:
- eayc-network
environment:
- SPRING_APPLICATION_JSON={"nacos":{"server-addr":"10.101.10.19:8848"}}
ports:
- "30508:8368"
确保宿主机开放必要的端口:
bash复制firewall-cmd --permanent --zone=public --add-port=28220-28250/tcp
firewall-cmd --reload
nginx复制location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
nginx复制upstream backend {
server backend1.example.com max_fails=3 fail_timeout=30s;
server backend2.example.com max_fails=3 fail_timeout=30s;
}
nginx复制proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
dockerfile复制FROM node:18 as builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
code复制node_modules
.git
.DS_Store
dist
dockerfile复制RUN addgroup -g 1001 appuser && \
adduser -u 1001 -G appuser -D appuser
USER appuser
groovy复制pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'npm install'
sh 'npm run build'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
}
groovy复制parameters {
gitParameter branchFilter: 'origin/(.*)',
defaultValue: 'main',
name: 'BRANCH',
type: 'PT_BRANCH'
}
groovy复制agent {
docker {
image 'node:18'
args '-v $HOME/.npm:/root/.npm'
}
}
在实际部署过程中,我发现最容易被忽视的是日志收集和监控配置。建议在初期就规划好日志收集方案,可以使用ELK栈或直接配置日志驱动:
bash复制docker run --log-driver=syslog --log-opt syslog-address=udp://1.2.3.4:514 my-app
另一个经验是,对于前端项目,合理配置健康检查可以大幅提高可用性:
nginx复制location = /health {
access_log off;
add_header 'Content-Type' 'application/json';
return 200 '{"status":"UP"}';
}