[#5] 修改web页面;更新镜像打包

This commit is contained in:
xiuting.xu
2025-10-10 15:03:10 +08:00
parent 54f99b854c
commit ade9dd7d62
38 changed files with 1180 additions and 417 deletions

View File

@@ -0,0 +1,89 @@
# ========== 构建阶段 ==========
FROM node:20 AS builder
# 设置工作目录
WORKDIR /app/src/web
# 复制依赖文件并安装
COPY src/web/package*.json ./
RUN npm install
# 复制源码并打包
COPY src/web ./
RUN npm run build
# ========== 运行阶段 ==========
FROM ubuntu:24.04
USER root
# 安装 nginx 和 supervisor
RUN apt-get update && \
apt-get install -y nginx supervisor curl vim net-tools inetutils-ping ca-certificates passwd && \
apt-get clean && rm -rf /var/lib/apt/lists/*
ENV FRONTEND_BASE_PATH=/private/argus/web/frontend
RUN mkdir -p ${FRONTEND_BASE_PATH} && \
mkdir -p /private/argus/etc
# 创建 web 用户(可自定义 UID/GID)
# 创建 web 用户组
RUN groupadd -g 2015 web
# 创建 web 用户并指定组
RUN useradd -M -s /usr/sbin/nologin -u 2133 -g 2015 web
RUN chown -R web:web ${FRONTEND_BASE_PATH} && \
chown -R web:web /private/argus/etc && \
chown -R web:web /usr/local/bin
# 配置内网 apt 源 (如果指定了内网选项)
RUN if [ "$USE_INTRANET" = "true" ]; then \
echo "Configuring intranet apt sources..." && \
cp /etc/apt/sources.list /etc/apt/sources.list.bak && \
echo "deb [trusted=yes] http://10.68.64.1/ubuntu2204/ jammy main" > /etc/apt/sources.list && \
echo 'Acquire::https::Verify-Peer "false";' > /etc/apt/apt.conf.d/99disable-ssl-check && \
echo 'Acquire::https::Verify-Host "false";' >> /etc/apt/apt.conf.d/99disable-ssl-check; \
fi
# 配置部署时使用的 apt 源
RUN if [ "$USE_INTRANET" = "true" ]; then \
echo "deb [trusted=yes] https://10.92.132.52/mirrors/ubuntu2204/ jammy main" > /etc/apt/sources.list; \
fi
# 前端编译产物放到 nginx 目录
COPY --from=builder /app/src/web/dist /usr/share/nginx/html
# 复制 nginx 配置(保证 React 前端路由兼容)
COPY src/web/build_tools/frontend/nginx.conf /etc/nginx/nginx.conf
# COPY src/web/build_tools/frontend/conf.d/ /etc/nginx/conf.d/
# 复制 supervisor 配置
COPY src/web/build_tools/frontend/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# 创建 supervisor 日志目录
RUN mkdir -p /var/log/supervisor
# 复制启动脚本
COPY src/web/build_tools/frontend/start-web-supervised.sh /usr/local/bin/start-web-supervised.sh
RUN chmod +x /usr/local/bin/start-web-supervised.sh
# 复制 DNS 监控脚本
COPY src/web/build_tools/frontend/dns-monitor.sh /usr/local/bin/dns-monitor.sh
RUN chmod +x /usr/local/bin/dns-monitor.sh
# 复制健康检查脚本
COPY src/web/build_tools/frontend/health-check.sh /usr/local/bin/health-check.sh
RUN chmod +x /usr/local/bin/health-check.sh
# 暴露端口
EXPOSE 80
# 保持 root 用户,由 supervisor 控制 user 切换
USER root
# 以 supervisor 为入口
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

View File

@@ -0,0 +1,4 @@
docker pull node:20
docker pull ubuntu:24.04
docker build -f src/web/build_tools/frontend/Dockerfile -t argus-web:0.1.1 .
rm -f argus-web-0.1.1.tar && sudo docker image save argus-web:0.1.1 > argus-web-0.1.1.tar

View File

@@ -0,0 +1,68 @@
#!/bin/bash
# DNS监控脚本 - 每10秒检查dns.conf是否有变化
# 如果有变化则执行update-dns.sh脚本
DNS_CONF="/private/argus/etc/dns.conf"
DNS_BACKUP="/tmp/dns.conf.backup"
UPDATE_SCRIPT="/private/argus/etc/update-dns.sh"
LOG_FILE="/var/log/supervisor/dns-monitor.log"
# 确保日志文件存在
touch "$LOG_FILE"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') [DNS-Monitor] $1" >> "$LOG_FILE"
}
log_message "DNS监控脚本启动"
while true; do
if [ -f "$DNS_CONF" ]; then
if [ -f "$DNS_BACKUP" ]; then
# 比较文件内容
if ! cmp -s "$DNS_CONF" "$DNS_BACKUP"; then
log_message "检测到DNS配置变化"
# 更新备份文件
cp "$DNS_CONF" "$DNS_BACKUP"
# 执行更新脚本
if [ -x "$UPDATE_SCRIPT" ]; then
log_message "执行DNS更新脚本: $UPDATE_SCRIPT"
"$UPDATE_SCRIPT" >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log_message "DNS更新脚本执行成功"
else
log_message "DNS更新脚本执行失败"
fi
else
log_message "警告: 更新脚本不存在或不可执行: $UPDATE_SCRIPT"
fi
fi
else
# 第一次检测到配置文件,执行更新脚本
if [ -x "$UPDATE_SCRIPT" ]; then
log_message "执行DNS更新脚本: $UPDATE_SCRIPT"
"$UPDATE_SCRIPT" >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log_message "DNS更新脚本执行成功"
# 第一次运行,创建备份并执行更新
cp "$DNS_CONF" "$DNS_BACKUP"
log_message "创建DNS配置备份文件"
else
log_message "DNS更新脚本执行失败"
fi
else
log_message "警告: 更新脚本不存在或不可执行: $UPDATE_SCRIPT"
fi
fi
else
log_message "警告: DNS配置文件不存在: $DNS_CONF"
fi
sleep 10
done

View File

@@ -0,0 +1,16 @@
#!/bin/bash
set -euo pipefail
URL="http://127.0.0.1:80"
echo "[INFO] Starting frontend health check loop for $URL..."
while true; do
if curl -s --max-time 5 "$URL" > /dev/null; then
echo "[OK] $(date '+%Y-%m-%d %H:%M:%S') Frontend is healthy"
else
echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') Frontend health check failed"
exit 1
fi
sleep 10
done

View File

@@ -0,0 +1,56 @@
user web;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
# React 前端服务
server {
listen 80;
server_name web.argus.com;
root /usr/share/nginx/html;
index index.html;
# React 前端路由兼容
location / {
try_files $uri /index.html;
}
}
# Master 服务,需要增加 CORS 支持
server {
listen 80;
server_name master.argus.com;
location / {
proxy_pass http://master.argus.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# CORS 支持
add_header 'Access-Control-Allow-Origin' 'http://web.argus.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' 'http://web.argus.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Origin, Content-Type, Accept, Authorization' always;
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain';
return 204;
}
}
}
}

View File

@@ -0,0 +1,39 @@
#!/bin/bash
set -euo pipefail
echo "[INFO] Starting React frontend under supervisor..."
DNS_DIR="/private/argus/etc"
DNS_SCRIPT="${DNS_DIR}/update-dns.sh"
DOMAIN=web.argus.com
WEB_DOMAIN_FILE="${DNS_DIR}/${DOMAIN}"
RUNTIME_USER="${ARGUS_RUNTIME_USER:-argus}"
RUNTIME_UID="${ARGUS_BUILD_UID:-2133}"
RUNTIME_GID="${ARGUS_BUILD_GID:-2015}"
mkdir -p "$DNS_DIR"
chown -R "$RUNTIME_UID:$RUNTIME_GID" "$DNS_DIR" 2>/dev/null || true
if [[ -x "$DNS_SCRIPT" ]]; then
echo "[INFO] Running update-dns.sh before master starts"
# 若脚本存在则执行,保证容器使用 bind 作为 DNS
"$DNS_SCRIPT" || echo "[WARN] update-dns.sh execution failed"
else
echo "[WARN] DNS update script not found or not executable: $DNS_SCRIPT"
fi
# 记录容器 IP
IP=$(ifconfig | grep -A 1 eth0 | grep inet | awk '{print $2}' || true)
if [[ -n "${IP}" ]]; then
echo "current IP: ${IP}"
echo "${IP}" > "$WEB_DOMAIN_FILE"
chown "$RUNTIME_UID:$RUNTIME_GID" "$WEB_DOMAIN_FILE" 2>/dev/null || true
else
echo "[WARN] Failed to detect web IP via ifconfig"
fi
echo "[INFO] Launching nginx..."
# 启动 nginx 前台模式
exec /usr/sbin/nginx -g "daemon off;"

View File

@@ -0,0 +1,39 @@
[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
user=root
[program:web]
command=/usr/local/bin/start-web-supervised.sh
user=root
stdout_logfile=/var/log/supervisor/web.log
stderr_logfile=/var/log/supervisor/web_error.log
autorestart=true
startretries=3
startsecs=5
stopwaitsecs=10
killasgroup=true
stopasgroup=true
[program:web-health]
command=/usr/local/bin/health-check.sh
user=web
stdout_logfile=/var/log/supervisor/web-health.log
stderr_logfile=/var/log/supervisor/web-health_error.log
autorestart=true
startretries=3
startsecs=5
stopwaitsecs=10
killasgroup=true
stopasgroup=true
[unix_http_server]
file=/var/run/supervisor.sock
chmod=0700
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface