chore: devops web

This commit is contained in:
liulujian 2026-05-03 17:49:17 +08:00
parent 404f0d9710
commit bcadef7868
8 changed files with 234 additions and 15 deletions

1
.gitignore vendored
View File

@ -7,7 +7,6 @@ classes
prd
devops/images
devops/nacos
devops/web
# Log file
*.log

View File

@ -109,35 +109,46 @@ pack_image() {
MD5_FILE="${PACKAGE_FILE}.md5"
echo ""
echo ">>> [1/3] 打包镜像 -> ${PACKAGE_FILE}"
echo ">>> [1/4] 打包镜像 -> ${PACKAGE_FILE}"
docker save -o "${PACKAGE_FILE}" "${IMAGE_NAME}"
echo ""
echo ">>> [2/3] 生成校验文件"
echo ">>> [2/4] gzip 压缩 (最高压缩级别)"
GZIP_FILE="${PACKAGE_FILE}.gz"
gzip -9 -f "${PACKAGE_FILE}"
echo ""
echo ">>> [3/4] 生成校验文件"
md5sum "${GZIP_FILE}" > "${GZIP_FILE}.md5"
md5sum "${PACKAGE_FILE}" > "${MD5_FILE}"
echo ""
echo ">>> [3/3] 打包完成"
ls -lh "${PACKAGE_FILE}" "${MD5_FILE}"
echo ">>> [4/4] 打包完成"
ls -lh "${GZIP_FILE}" "${GZIP_FILE}.md5" "${MD5_FILE}"
echo ""
echo "============================================"
echo " 下一步操作提示"
echo "============================================"
echo ""
echo ">>> 1. 传输镜像到服务器"
echo ">>> 1. 传输镜像到服务器 (推荐使用 .tar.gz 压缩包,体积更小)"
echo ""
echo " # 方式一: scp 传输"
echo " # 方式一: scp 传输压缩包"
echo " scp ${GZIP_FILE} ${SERVER_USER}@${SERVER_HOST}:/opt/txw/images/"
echo " scp ${GZIP_FILE}.md5 ${SERVER_USER}@${SERVER_HOST}:/opt/txw/images/"
echo ""
echo " # 方式二: scp 传输原始 tar 包 (不压缩)"
echo " scp ${PACKAGE_FILE} ${SERVER_USER}@${SERVER_HOST}:/opt/txw/images/"
echo " scp ${MD5_FILE} ${SERVER_USER}@${SERVER_HOST}:/opt/txw/images/"
echo ""
echo " # 方式二: 手动复制后执行 (推荐生产环境先上传再解压)"
echo ""
echo ">>> 2. SSH 到服务器后,执行以下命令:"
echo ""
echo " # 创建目录"
echo " ssh ${SERVER_USER}@${SERVER_HOST} 'mkdir -p /opt/txw/images'"
echo ""
echo " # 解压 (如果上传的是 .tar.gz)"
echo " ssh ${SERVER_USER}@${SERVER_HOST} 'gunzip /opt/txw/images/${IMAGE_TYPE}-${VERSION}-${TIMESTAMP}.tar.gz'"
echo ""
echo " # 加载镜像"
echo " ssh ${SERVER_USER}@${SERVER_HOST} 'docker load -i /opt/txw/images/${IMAGE_TYPE}-${VERSION}-${TIMESTAMP}.tar'"
echo ""
@ -156,14 +167,17 @@ pack_image() {
echo " -p 8080:8080 \\"
echo " ${IMAGE_NAME}'"
echo ""
echo ">>> 4. 一键执行脚本 (上传后ssh内执行)"
echo ">>> 4. 一键执行脚本 (上传 .tar.gz ssh 内执行)"
echo ""
echo " ssh ${SERVER_USER}@${SERVER_HOST} << 'EOF'"
echo " #!/bin/bash"
echo " IMAGE_PATH=\"/opt/txw/images/${IMAGE_TYPE}-${VERSION}-${TIMESTAMP}.tar\""
echo " GZIP_PATH=\"/opt/txw/images/${IMAGE_TYPE}-${VERSION}-${TIMESTAMP}.tar.gz\""
echo " "
echo " # 解压"
echo " gunzip \${GZIP_PATH}"
echo " "
echo " # 加载镜像"
echo " docker load -i \${IMAGE_PATH}"
echo " docker load -i \${GZIP_PATH%.gz}"
echo " "
echo " # 停止并移除旧容器"
echo " docker stop ${SERVICE_NAME} 2>/dev/null || true"
@ -179,8 +193,9 @@ pack_image() {
echo ""
echo "============================================"
echo ""
echo "[*] 打包文件: ${PACKAGE_FILE}"
echo "[*] 校验文件: ${MD5_FILE}"
echo "[*] 打包文件: ${GZIP_FILE} (压缩后,推荐传输)"
echo "[*] 原始文件: ${PACKAGE_FILE} (未压缩)"
echo "[*] 校验文件: ${GZIP_FILE}.md5 ${MD5_FILE}"
echo ""
}

24
devops/web/Dockerfile Normal file
View File

@ -0,0 +1,24 @@
## ============================================================
## 碳信网 - 前端镜像
## 前提:本地先执行 npm run build 构建前端
## 构建:
## cd txw-mhzc-web && npm install && npm run build
## cd txw-yygl-web && npm install && npm run build
## ============================================================
FROM nginx:alpine
# 复制 nginx 配置
COPY devops/web/nginx.conf /etc/nginx/nginx.conf
COPY devops/web/default.json /etc/nginx/oem/default.json
COPY devops/web/baidu_verify_codeva-5rH3psCeMQ.html /etc/nginx/verify/baidu_verify_codeva-5rH3psCeMQ.html
COPY devops/web/proxy-common.conf /etc/nginx/proxy-common.conf
# 复制预构建的前端产物
COPY txw-mhzc-web/dist /usr/share/nginx/html/txw-mhzc-web
COPY txw-yygl-web/dist /usr/share/nginx/html/txw-yygl-web
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1 @@
9d0cb82eb62e06082bc752dd7cc6e4cb

6
devops/web/default.json Normal file
View File

@ -0,0 +1,6 @@
{
"code": 1,
"data": {
"MH_REGISTRATION_ENABLED": true
}
}

164
devops/web/nginx.conf Normal file
View File

@ -0,0 +1,164 @@
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 8192;
use epoll;
multi_accept on;
}
http {
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 基础配置
client_max_body_size 100m;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip 压缩http 级别)
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/x-javascript
text/xml application/xml application/xml+rss
application/javascript text/javascript
application/vnd.ms-fontobject application/x-font-ttf
font/opentype image/svg+xml image/x-icon;
# 代理超时配置
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
send_timeout 300s;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# =============================================
# Server
# =============================================
server {
listen 80 default_server;
absolute_redirect off;
server_name _;
# Gzip 压缩server 级别,微调)
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript
application/x-javascript text/xml application/xml
application/xml+rss text/javascript image/svg+xml;
# 健康检查
location /healthcheck {
access_log off;
return 200 'OK';
add_header Content-Type text/plain;
}
# Ping 接口
location /ping {
return 200 "ok";
}
# API 代理(网关)
location ~ ^/(mhzc|gxzx|sso|yygl) {
include proxy-common.conf;
proxy_pass http://txw-gateway:9300;
}
# 百度验证
location = /baidu_verify_codeva-5rH3psCeMQ.html {
alias /etc/nginx/verify/baidu_verify_codeva-5rH3psCeMQ.html;
}
location = /baidu_verify_codeva-eE1giHswVL.html {
return 200 "2c7cc0bcf0ecd060ab8f7fe919acc078";
add_header Content-Type text/html;
}
# --------------------------------------------------------
# 运营支撑前端mhzc
# --------------------------------------------------------
location /view/mhzc {
return 301 /view/mhzc/;
}
location /view/mhzc/ {
alias /usr/share/nginx/html/txw-mhzc-web/;
# 静态资源90天缓存
location ~* \.(gif|jpg|jpeg|png|css|js|ico|eot|svg|ttf|woff|woff2)$ {
expires 90d;
add_header Cache-Control "public";
try_files $uri =404;
}
# 非静态资源1小时缓存
expires 1h;
add_header Cache-Control "public";
try_files $uri $uri/ /view/mhzc/index.html;
}
# --------------------------------------------------------
# 运营管理前端yygl
# --------------------------------------------------------
location /view/yygl {
return 301 /view/yygl/;
}
location /view/yygl/ {
alias /usr/share/nginx/html/txw-yygl-web/;
# 静态资源90天缓存
location ~* \.(gif|jpg|jpeg|png|css|js|ico|eot|svg|ttf|woff|woff2)$ {
expires 90d;
add_header Cache-Control "public";
try_files $uri =404;
}
# 非静态资源1小时缓存
expires 1h;
add_header Cache-Control "public";
try_files $uri $uri/ /view/yygl/index.html;
}
# --------------------------------------------------------
# 默认首页重定向
# --------------------------------------------------------
location / {
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires 0;
return 301 /view/mhzc/;
}
# 错误页面
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# 引入其他 location 配置
include ./location.d/*.conf;
}

View File

@ -0,0 +1,10 @@
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 超时控制
proxy_connect_timeout 20s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;

View File

@ -429,7 +429,7 @@ export default {
handleContact(card) {
this.contactData = {
lxr: card.lxr || '',
lxdh: card.lxrdh || '',
lxdh: card.lxdh || '',
email: card.email || '',
};
this.contactVisible = true;