完善架构,修改很多地方
This commit is contained in:
21
front-end/app-product/docker/Dockerfile
Normal file
21
front-end/app-product/docker/Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
||||
FROM node:24-alpine AS builder
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json ./
|
||||
|
||||
# 直接使用 npm install 并解决依赖问题
|
||||
RUN npm install --no-audit --no-fund --legacy-peer-deps
|
||||
|
||||
# 拷贝源码并构建
|
||||
COPY . .
|
||||
|
||||
# 【前端修改】如果要以子路径 /app-product/ 部署,请用 base 指定前缀,同 .env中VITE_SERVER_NAME
|
||||
RUN npx vite build --base=/app-product/
|
||||
|
||||
FROM nginx:alpine
|
||||
# 构建产物放到 /usr/share/nginx/html/app-product
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html/app-product
|
||||
# 覆盖 Nginx 配置,支持 SPA 子路径
|
||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
39
front-end/app-product/docker/app-product.yml
Normal file
39
front-end/app-product/docker/app-product.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
version: "3.8" # Docker Compose 文件版本,3.8 支持 Swarm 模式的所有功能
|
||||
|
||||
services:
|
||||
app-product:
|
||||
image: app-product:latest
|
||||
ports:
|
||||
- target: 80 # 容器内部端口
|
||||
published: 1301 # 宿主机对外暴露端口
|
||||
protocol: tcp # 协议类型
|
||||
mode: ingress # 模式:使用路由网格
|
||||
deploy:
|
||||
replicas: 3 # 副本数量,在集群中运行 3 个容器实例
|
||||
placement:
|
||||
max_replicas_per_node: 1 # 每个 Swarm 节点最多运行 1 个副本,确保高可用性
|
||||
restart_policy:
|
||||
condition: any # 重启条件:任何情况下容器退出都重启
|
||||
delay: 5s # 重启延迟 5 秒
|
||||
max_attempts: 3 # 最大重启尝试次数
|
||||
update_config: # 滚动更新配置
|
||||
parallelism: 1 # 并行更新数量:一次只更新 1 个容器
|
||||
delay: 10s # 更新间隔:每个容器更新后等待 10 秒再更新下一个
|
||||
failure_action: rollback # 更新失败时自动回滚到上一版本
|
||||
order: start-first # 更新顺序:先启动新容器,确认健康后再停止旧容器
|
||||
rollback_config: # 回滚配置
|
||||
parallelism: 1 # 回滚时并行数量
|
||||
delay: 5s # 回滚延迟
|
||||
resources: # 资源限制
|
||||
limits: # 资源上限
|
||||
cpus: "0.50" # 最多使用 0.5 个 CPU 核心
|
||||
memory: "256M" # 最多使用 256MB 内存
|
||||
reservations: # 资源预留
|
||||
cpus: "0.25" # 预留 0.25 个 CPU 核心
|
||||
memory: "128M" # 预留 128MB 内存
|
||||
networks:
|
||||
- frontend # 连接到 frontend 网络
|
||||
|
||||
networks:
|
||||
frontend: # 定义 frontend 网络
|
||||
driver: overlay # 使用 overlay 网络驱动,支持跨主机通信
|
||||
100
front-end/app-product/docker/deploy-swarm.sh
Executable file
100
front-end/app-product/docker/deploy-swarm.sh
Executable file
@@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
# deploy-swarm.sh
|
||||
|
||||
set -e
|
||||
|
||||
# 仓库用户名
|
||||
USER_NAME="bmy"
|
||||
# 仓库密码
|
||||
USER_PASSWORD="lb714500."
|
||||
# 仓库地址
|
||||
REGISTRY="registry.bmycode.help"
|
||||
# 镜像名称
|
||||
IMAGE_NAME="${REGISTRY}/app-product"
|
||||
# tag 标签
|
||||
TAG="v$(date +%Y%m%d-%H%M%S)"
|
||||
# 完整路径
|
||||
FULL_IMAGE="${IMAGE_NAME}:${TAG}"
|
||||
# 工作服务器列表(多个服务器)
|
||||
WORKER_HOSTS=("192.168.139.120" "192.168.139.242")
|
||||
WORKER_USER="root"
|
||||
WORKER_PASSWORD="lb714500."
|
||||
|
||||
echo "=== 1 登录私有镜像仓库 ==="
|
||||
if ! echo "${USER_PASSWORD}" | docker login ${REGISTRY} -u ${USER_NAME} --password-stdin; then
|
||||
echo "错误: 无法登录到私有仓库 ${REGISTRY}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== 2 构建 app-product 镜像 ==="
|
||||
docker build \
|
||||
-f docker/Dockerfile \
|
||||
-t ${FULL_IMAGE} \
|
||||
-t ${IMAGE_NAME}:latest \
|
||||
.
|
||||
|
||||
echo "=== 3 推送镜像到私有仓库 ==="
|
||||
docker push ${FULL_IMAGE}
|
||||
docker push ${IMAGE_NAME}:latest
|
||||
|
||||
echo "=== 4 在工作服务器上拉取最新镜像 ==="
|
||||
for WORKER_HOST in "${WORKER_HOSTS[@]}"; do
|
||||
echo ""
|
||||
echo "正在连接到工作服务器: ${WORKER_HOST}"
|
||||
|
||||
if sshpass -p "${WORKER_PASSWORD}" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${WORKER_USER}@${WORKER_HOST} "
|
||||
echo '在工作服务器 ${WORKER_HOST} 上登录私有仓库...'
|
||||
if echo '${USER_PASSWORD}' | docker login ${REGISTRY} -u ${USER_NAME} --password-stdin; then
|
||||
echo '拉取最新镜像...'
|
||||
docker pull ${FULL_IMAGE}
|
||||
docker pull ${IMAGE_NAME}:latest
|
||||
echo '镜像拉取完成'
|
||||
|
||||
|
||||
echo '清理旧的 app-product 镜像...'
|
||||
# 删除除了本次 FULL_IMAGE 和 latest 之外的所有 app-product 镜像
|
||||
docker images ${IMAGE_NAME} --format 'table {{.Repository}}:{{.Tag}}' | \
|
||||
grep -v '${FULL_IMAGE}' | \
|
||||
grep -v '${IMAGE_NAME}:latest' | \
|
||||
grep '${IMAGE_NAME}' | \
|
||||
xargs -r docker rmi -f || true
|
||||
|
||||
else
|
||||
echo '错误: 无法在工作服务器上登录私有仓库'
|
||||
exit 1
|
||||
fi
|
||||
"; then
|
||||
echo "✓ 服务器 ${WORKER_HOST} 镜像拉取成功"
|
||||
else
|
||||
echo "✗ 服务器 ${WORKER_HOST} 镜像拉取失败"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "=== 5 更新 docker-compose 文件中的镜像标签 ==="
|
||||
sed "s|image: app-product:latest|image: ${FULL_IMAGE}|g" docker/app-product.yml > docker/app-product-deploy.yml
|
||||
|
||||
echo "=== 6 部署到 Swarm 集群 ==="
|
||||
docker stack deploy -c docker/app-product-deploy.yml app-product
|
||||
|
||||
echo "=== 7 恢复原始配置文件 ==="
|
||||
rm -f docker/app-product-deploy.yml
|
||||
|
||||
echo "=== 8 清理本地多余镜像 ==="
|
||||
# 清理本地:删除除了本次 FULL_IMAGE 和 latest 之外的所有 app-product 镜像
|
||||
echo "清理本地旧的 app-product 镜像..."
|
||||
docker images ${IMAGE_NAME} --format 'table {{.Repository}}:{{.Tag}}' | \
|
||||
grep -v "${FULL_IMAGE}" | \
|
||||
grep -v "${IMAGE_NAME}:latest" | \
|
||||
grep "${IMAGE_NAME}" | \
|
||||
xargs -r docker rmi -f || true
|
||||
|
||||
# 清理悬空镜像
|
||||
docker image prune -f
|
||||
|
||||
|
||||
|
||||
echo "=== 9 验证部署状态 ==="
|
||||
docker stack ps app-product
|
||||
|
||||
echo "=== 部署完成 ==="
|
||||
13
front-end/app-product/docker/docker-compose.yml
Normal file
13
front-end/app-product/docker/docker-compose.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
app-product:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile
|
||||
|
||||
image: app-product:1.0.0
|
||||
container_name: app-product
|
||||
ports:
|
||||
- "1301:80"
|
||||
restart: unless-stopped
|
||||
13
front-end/app-product/docker/nginx.conf
Normal file
13
front-end/app-product/docker/nginx.conf
Normal file
@@ -0,0 +1,13 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name *.ddd.com;
|
||||
|
||||
location /app-product/ {
|
||||
alias /usr/share/nginx/html/app-product/;
|
||||
try_files $uri $uri/ /app-product/index.html;
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user