refactor(deploy): ?????????? Nginx ????
Made-with: Cursor
This commit is contained in:
@@ -81,34 +81,15 @@ sudo systemctl start nginx
|
|||||||
- **应用内 404**:在 SPA 已正确回退的前提下,未在后台发布的路径会由前端路由进入 **「页面不存在」** 页(`NotFound.vue`),与上述 nginx 404 不同。
|
- **应用内 404**:在 SPA 已正确回退的前提下,未在后台发布的路径会由前端路由进入 **「页面不存在」** 页(`NotFound.vue`),与上述 nginx 404 不同。
|
||||||
- **Compose 部署**:`web` 容器实际加载的是 **`deploy/web/default.conf`**(见 `docker-compose.yml` 挂载)。若线上仍对 `/test` 等返回 **nginx 404**,请把仓库里最新的 `deploy/web/default.conf` 同步到服务器对应路径后,执行 `docker compose restart web`(或重建 `yh_web` 容器)。
|
- **Compose 部署**:`web` 容器实际加载的是 **`deploy/web/default.conf`**(见 `docker-compose.yml` 挂载)。若线上仍对 `/test` 等返回 **nginx 404**,请把仓库里最新的 `deploy/web/default.conf` 同步到服务器对应路径后,执行 `docker compose restart web`(或重建 `yh_web` 容器)。
|
||||||
|
|
||||||
## 6. 单实例:仅宿主机 Nginx(推荐一台机一个 443 入口)
|
## 6. 单实例:宿主机 Nginx 占 443(与 `pull-and-restart.sh` / `restart.sh` 自动切换)
|
||||||
|
|
||||||
不再使用容器 **`yh_nginx`**,由**宿主机 Nginx** 监听 **443**,把流量转到本机回环上的 **`web` / `admin` / `api` 容器**。
|
逻辑由 **`scripts/lib-yh-compose-deploy.sh`** 统一处理(无需单独启动脚本):
|
||||||
|
|
||||||
1. **证书**:同上,放在 `/etc/ssl/yh_web/yuheng.yuxindazhineng.com/`。
|
1. **启动前**:`docker compose … down --remove-orphans`,只停本项目容器,**不**对宿主机 `nginx` 做 `start/stop`。
|
||||||
2. **合并 Compose**(为容器绑定回环端口,并禁用 compose 内 Nginx):
|
2. **`systemctl` 显示宿主机 Nginx 已运行**:只起 `mongo api web admin`,**不起**容器 `yh_nginx`;从 **`nginx/yuheng.host.conf`** 生成 `/etc/nginx/conf.d/<域名>.conf` 并 **`nginx -t` + `reload`**(不重载则无法指向新回环端口)。
|
||||||
|
3. **宿主机 Nginx 未运行**:起完整栈(**`--profile compose-internal-nginx`**,含容器 `yh_nginx` 终止 TLS)。
|
||||||
|
4. **证书**:同上,`/etc/ssl/yh_web/yuheng.yuxindazhineng.com/`;`pull-and-restart.sh` / `restart.sh` 仍会同步仓库内证书到该目录。
|
||||||
|
|
||||||
```bash
|
**回环端口**(与 `nginx/yuheng.host.conf` 一致):API `127.0.0.1:8088`,前台 `9080`,后台 `9081`。
|
||||||
docker compose -f docker-compose.yml -f docker-compose.host-nginx.yml up -d mongo api web admin
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **一键脚本**(启动容器 + 写入宿主机站点配置并重载 Nginx):
|
**与「方式 B(8443)」**:方式 B 是宿主机 → 容器 Nginx → 各服务;本节是宿主机 → 各服务,**一层**。
|
||||||
|
|
||||||
```bash
|
|
||||||
chmod +x scripts/start-with-host-nginx.sh
|
|
||||||
./scripts/start-with-host-nginx.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
脚本会把 `nginx/yuheng.host.conf` 中的 `__VERIFY_ROOT__` 替换为项目下 `verify-root` 绝对路径,并写入 `/etc/nginx/conf.d/yuheng.yuxindazhineng.com.conf`(需 **sudo**)。若不想自动改 Nginx,可 `INSTALL_NGINX_CONF=0 ./scripts/start-with-host-nginx.sh`。
|
|
||||||
|
|
||||||
4. **回环端口约定**(与 `nginx/yuheng.host.conf` 一致):
|
|
||||||
|
|
||||||
| 服务 | 本机地址 |
|
|
||||||
|------|----------|
|
|
||||||
| API | `127.0.0.1:8088` |
|
|
||||||
| 前台静态 | `127.0.0.1:9080` |
|
|
||||||
| 后台静态 | `127.0.0.1:9081` |
|
|
||||||
|
|
||||||
5. **若仍要用容器里的 yh_nginx**(旧方案):`docker compose --profile compose-internal-nginx up -d`,此时会与宿主机抢 **443**,二选一。
|
|
||||||
|
|
||||||
6. **与「方式 B(8443)」的区别**:方式 B 是「宿主机 Nginx → 容器 Nginx → 各服务」两层;本节是「宿主机 Nginx → 各服务」**一层**,不再起 `yh_nginx`。
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# 宿主机 Nginx 单实例:443 终止 TLS,反代到本机回环上的 Docker 服务(见 docker-compose.host-nginx.yml)
|
# 宿主机 Nginx 单实例:443 终止 TLS,反代到本机回环上的 Docker 服务(见 docker-compose.host-nginx.yml)
|
||||||
# 部署:
|
# 部署:
|
||||||
# 1. 证书:/etc/ssl/yh_web/yuheng.yuxindazhineng.com/{fullchain.pem,privkey.pem}
|
# 1. 证书:/etc/ssl/yh_web/yuheng.yuxindazhineng.com/{fullchain.pem,privkey.pem}
|
||||||
# 2. 替换下方 __VERIFY_ROOT__ 为项目内 verify-root 的绝对路径(或由 start-with-host-nginx.sh 生成 .conf)
|
# 2. 替换下方 __VERIFY_ROOT__ 为项目内 verify-root 的绝对路径(或由 pull-and-restart.sh / restart.sh 自动生成)
|
||||||
# 3. sudo cp yuheng.host.conf /etc/nginx/conf.d/yuheng.yuxindazhineng.com.conf
|
# 3. sudo cp yuheng.host.conf /etc/nginx/conf.d/yuheng.yuxindazhineng.com.conf
|
||||||
# 4. sudo nginx -t && sudo systemctl reload nginx
|
# 4. sudo nginx -t && sudo systemctl reload nginx
|
||||||
|
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ bash "$ROOT/scripts/merge-server-env-from-example.sh" "$ROOT" || true
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "[2/3] 重新构建并启动..."
|
echo "[2/3] 重新构建并启动..."
|
||||||
# 宿主机 9527 常被 sshd 占用,compose 必须使用 8088 且 api 不映射宿主机端口
|
# 宿主机 9527 常被 sshd 占用,compose 内 API 须为 8088。若宿主机 Nginx 已运行,docker-compose.host-nginx.yml 会把 api/web/admin 绑到本机回环供反代。
|
||||||
if grep -q '9527' "$ROOT/docker-compose.yml" 2>/dev/null; then
|
if grep -q '9527' "$ROOT/docker-compose.yml" 2>/dev/null; then
|
||||||
echo "错误: 当前 docker-compose.yml 仍含 9527,会与 sshd 冲突导致启动失败。请以 Gitea 为准拉取最新代码后再执行本脚本:" >&2
|
echo "错误: 当前 docker-compose.yml 仍含 9527,会与 sshd 冲突导致启动失败。请以 Gitea 为准拉取最新代码后再执行本脚本:" >&2
|
||||||
echo " git fetch origin && git reset --hard origin/master" >&2
|
echo " git fetch origin && git reset --hard origin/master" >&2
|
||||||
@@ -354,21 +354,18 @@ elif [ -f "$ROOT/nginx/$NGINX_DOMAIN/fullchain.pem" ] && [ -f "$ROOT/nginx/$NGIN
|
|||||||
run_sudo chmod 644 "$NGINX_SSL_DIR/fullchain.pem"
|
run_sudo chmod 644 "$NGINX_SSL_DIR/fullchain.pem"
|
||||||
run_sudo chmod 600 "$NGINX_SSL_DIR/privkey.pem"
|
run_sudo chmod 600 "$NGINX_SSL_DIR/privkey.pem"
|
||||||
fi
|
fi
|
||||||
compose_cmd down 2>/dev/null || true
|
# shellcheck disable=SC1091
|
||||||
compose_cmd up -d --force-recreate
|
. "$ROOT/scripts/lib-yh-compose-deploy.sh"
|
||||||
|
# 先停掉本项目 Compose 栈(不操作宿主机 nginx 服务);再按宿主机 Nginx 是否在线拉起容器
|
||||||
|
yh_compose_down
|
||||||
|
yh_compose_up
|
||||||
|
|
||||||
# 可选:web/promotion/视频发布 -> data/uploads + MongoDB(须 server/.env 中 YH_IMPORT_PROMOTION_SITE_ID)
|
# 可选:web/promotion/视频发布 -> data/uploads + MongoDB(须 server/.env 中 YH_IMPORT_PROMOTION_SITE_ID)
|
||||||
bash "$ROOT/scripts/run-promotion-import-on-deploy.sh" "$ROOT"
|
bash "$ROOT/scripts/run-promotion-import-on-deploy.sh" "$ROOT"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "[3/3] 证书与宿主机 Nginx(可选)..."
|
echo "[3/3] 宿主机 Nginx 站点(仅当 systemctl 显示 Nginx 已运行时写入 yuheng.host.conf 并重载,不执行 start/stop)..."
|
||||||
NGINX_CONF_NAME="${NGINX_DOMAIN}.conf"
|
yh_install_host_nginx_site_conf
|
||||||
if [ -f "$ROOT/nginx/$NGINX_CONF_NAME" ]; then
|
|
||||||
run_sudo cp -f "$ROOT/nginx/$NGINX_CONF_NAME" /etc/nginx/conf.d/ 2>/dev/null || true
|
|
||||||
if run_sudo nginx -t 2>/dev/null; then
|
|
||||||
run_sudo systemctl reload nginx 2>/dev/null && echo "宿主机 Nginx 已重载." || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "完成. 对外仅 443;反代: https://$NGINX_DOMAIN"
|
echo "完成. 对外仅 443;反代: https://$NGINX_DOMAIN"
|
||||||
|
|||||||
15
restart.sh
15
restart.sh
@@ -236,7 +236,6 @@ fi
|
|||||||
|
|
||||||
NGINX_DOMAIN="${NGINX_DOMAIN:-yuheng.yuxindazhineng.com}"
|
NGINX_DOMAIN="${NGINX_DOMAIN:-yuheng.yuxindazhineng.com}"
|
||||||
NGINX_SSL_DIR="/etc/ssl/yh_web/$NGINX_DOMAIN"
|
NGINX_SSL_DIR="/etc/ssl/yh_web/$NGINX_DOMAIN"
|
||||||
NGINX_CONF_NAME="${NGINX_DOMAIN}.conf"
|
|
||||||
run_sudo mkdir -p "$NGINX_SSL_DIR"
|
run_sudo mkdir -p "$NGINX_SSL_DIR"
|
||||||
if [ -f "$ROOT/nginx/$NGINX_DOMAIN.pem" ] && [ -f "$ROOT/nginx/$NGINX_DOMAIN.key" ]; then
|
if [ -f "$ROOT/nginx/$NGINX_DOMAIN.pem" ] && [ -f "$ROOT/nginx/$NGINX_DOMAIN.key" ]; then
|
||||||
run_sudo cp -f "$ROOT/nginx/$NGINX_DOMAIN.pem" "$NGINX_SSL_DIR/fullchain.pem"
|
run_sudo cp -f "$ROOT/nginx/$NGINX_DOMAIN.pem" "$NGINX_SSL_DIR/fullchain.pem"
|
||||||
@@ -252,16 +251,14 @@ elif [ -f "$ROOT/nginx/$NGINX_DOMAIN/fullchain.pem" ] && [ -f "$ROOT/nginx/$NGIN
|
|||||||
run_sudo chmod 644 "$NGINX_SSL_DIR/fullchain.pem"
|
run_sudo chmod 644 "$NGINX_SSL_DIR/fullchain.pem"
|
||||||
run_sudo chmod 600 "$NGINX_SSL_DIR/privkey.pem" 2>/dev/null || true
|
run_sudo chmod 600 "$NGINX_SSL_DIR/privkey.pem" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
compose_cmd down 2>/dev/null || true
|
# shellcheck disable=SC1091
|
||||||
compose_cmd up -d --force-recreate
|
. "$ROOT/scripts/lib-yh-compose-deploy.sh"
|
||||||
|
yh_compose_down
|
||||||
|
yh_compose_up
|
||||||
|
|
||||||
bash "$ROOT/scripts/run-promotion-import-on-deploy.sh" "$ROOT"
|
bash "$ROOT/scripts/run-promotion-import-on-deploy.sh" "$ROOT"
|
||||||
|
|
||||||
if [ -f "$ROOT/nginx/$NGINX_CONF_NAME" ]; then
|
echo "宿主机 Nginx 站点(若 Nginx 已运行则更新并重载)..."
|
||||||
run_sudo cp -f "$ROOT/nginx/$NGINX_CONF_NAME" /etc/nginx/conf.d/ 2>/dev/null || true
|
yh_install_host_nginx_site_conf
|
||||||
if run_sudo nginx -t 2>/dev/null; then
|
|
||||||
run_sudo systemctl reload nginx 2>/dev/null && echo "Nginx 已重载." || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "完成. 对外仅 443,反代: https://$NGINX_DOMAIN"
|
echo "完成. 对外仅 443,反代: https://$NGINX_DOMAIN"
|
||||||
|
|||||||
64
scripts/lib-yh-compose-deploy.sh
Normal file
64
scripts/lib-yh-compose-deploy.sh
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# shellcheck shell=bash
|
||||||
|
# 由 pull-and-restart.sh / restart.sh 在定义好 ROOT、compose_cmd、run_sudo 之后 source。
|
||||||
|
# 依赖:项目根存在 docker-compose.host-nginx.yml(与主 compose 合并使用)。
|
||||||
|
|
||||||
|
YH_COMPOSE_FILES="-f docker-compose.yml -f docker-compose.host-nginx.yml"
|
||||||
|
|
||||||
|
# 宿主机 Nginx(systemd)是否在运行;不检测 443 归属,以免误判。
|
||||||
|
host_nginx_online() {
|
||||||
|
command -v systemctl >/dev/null 2>&1 || return 1
|
||||||
|
systemctl is-active nginx >/dev/null 2>&1 && return 0
|
||||||
|
systemctl is-active nginx.service >/dev/null 2>&1 && return 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 停止本项目的 Compose 栈(含 yh_nginx 等),不操作宿主机 Nginx 服务。
|
||||||
|
yh_compose_down() {
|
||||||
|
if [ ! -f "$ROOT/docker-compose.host-nginx.yml" ]; then
|
||||||
|
compose_cmd down --remove-orphans 2>/dev/null || true
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
compose_cmd $YH_COMPOSE_FILES down --remove-orphans 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# 按宿主机 Nginx 是否在线,选择仅起业务容器或起完整栈(含 yh_nginx)。
|
||||||
|
yh_compose_up() {
|
||||||
|
if [ ! -f "$ROOT/docker-compose.host-nginx.yml" ]; then
|
||||||
|
echo "未找到 docker-compose.host-nginx.yml,使用默认 compose up."
|
||||||
|
compose_cmd up -d --force-recreate
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if host_nginx_online; then
|
||||||
|
echo "检测到宿主机 Nginx 已运行:不启动容器 yh_nginx;mongo/api/web/admin 绑定本机回环(见 nginx/yuheng.host.conf)。"
|
||||||
|
compose_cmd $YH_COMPOSE_FILES up -d --force-recreate mongo api web admin
|
||||||
|
else
|
||||||
|
echo "未检测到宿主机 Nginx 运行:启动完整栈(含容器 yh_nginx 终止 TLS)。"
|
||||||
|
compose_cmd $YH_COMPOSE_FILES --profile compose-internal-nginx up -d --force-recreate
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 仅当宿主机 Nginx 在线时:从模板写入站点配置并重载(不执行 systemctl start/stop nginx)。
|
||||||
|
yh_install_host_nginx_site_conf() {
|
||||||
|
local domain="${NGINX_DOMAIN:-yuheng.yuxindazhineng.com}"
|
||||||
|
local tpl="$ROOT/nginx/yuheng.host.conf"
|
||||||
|
local out="/etc/nginx/conf.d/${domain}.conf"
|
||||||
|
|
||||||
|
host_nginx_online || {
|
||||||
|
echo "宿主机 Nginx 未运行,跳过写入站点配置(由容器 yh_nginx 对外)。"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ ! -f "$tpl" ]; then
|
||||||
|
echo "未找到 $tpl,跳过宿主机站点配置生成。"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$ROOT/verify-root"
|
||||||
|
sed "s|__VERIFY_ROOT__|$ROOT/verify-root|g" "$tpl" | run_sudo tee "$out" >/dev/null
|
||||||
|
|
||||||
|
if run_sudo nginx -t 2>/dev/null; then
|
||||||
|
run_sudo systemctl reload nginx 2>/dev/null && echo "宿主机 Nginx 已重载($out)。" || true
|
||||||
|
else
|
||||||
|
echo "警告: 宿主机 nginx -t 失败,请检查 $out" >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# 宿主机 Nginx 单实例部署:启动 api/web/admin/mongo(不启动容器 yh_nginx),并可选安装站点配置后 reload。
|
|
||||||
# 用法(在项目根目录):
|
|
||||||
# chmod +x scripts/start-with-host-nginx.sh
|
|
||||||
# ./scripts/start-with-host-nginx.sh
|
|
||||||
#
|
|
||||||
# 依赖:已安装 Docker Compose、宿主机 Nginx、证书目录 /etc/ssl/yh_web/yuheng.yuxindazhineng.com/
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
||||||
cd "$ROOT"
|
|
||||||
|
|
||||||
echo "==> 启动容器:mongo api web admin(不启动 compose 内 yh_nginx)"
|
|
||||||
docker compose -f docker-compose.yml -f docker-compose.host-nginx.yml up -d mongo api web admin
|
|
||||||
|
|
||||||
echo "==> 若曾用旧方案启动过 yh_nginx,可手动停止释放 443: docker rm -f yh_nginx 2>/dev/null || true"
|
|
||||||
docker rm -f yh_nginx 2>/dev/null || true
|
|
||||||
|
|
||||||
VERIFY_ROOT="${VERIFY_ROOT:-$ROOT/verify-root}"
|
|
||||||
mkdir -p "$VERIFY_ROOT"
|
|
||||||
|
|
||||||
CONF_OUT="${NGINX_CONF_OUT:-/etc/nginx/conf.d/yuheng.yuxindazhineng.com.conf}"
|
|
||||||
TEMPLATE="$ROOT/nginx/yuheng.host.conf"
|
|
||||||
|
|
||||||
if [[ ! -f "$TEMPLATE" ]]; then
|
|
||||||
echo "缺少模板:$TEMPLATE" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "==> 生成宿主机 Nginx 配置(VERIFY_ROOT=$VERIFY_ROOT)"
|
|
||||||
if [[ "${INSTALL_NGINX_CONF:-1}" == "1" ]]; then
|
|
||||||
if ! command -v sudo >/dev/null 2>&1; then
|
|
||||||
echo "未找到 sudo,请手动执行:" >&2
|
|
||||||
echo " sed \"s|__VERIFY_ROOT__|$VERIFY_ROOT|g\" \"$TEMPLATE\" | sudo tee \"$CONF_OUT\"" >&2
|
|
||||||
echo " sudo nginx -t && sudo systemctl reload nginx" >&2
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
sed "s|__VERIFY_ROOT__|$VERIFY_ROOT|g" "$TEMPLATE" | sudo tee "$CONF_OUT" >/dev/null
|
|
||||||
sudo nginx -t
|
|
||||||
sudo systemctl reload nginx
|
|
||||||
echo "==> 已写入 $CONF_OUT 并重载 Nginx。请确认 443 仅由宿主机占用: ss -tlnp | grep 443"
|
|
||||||
else
|
|
||||||
echo "已跳过安装(INSTALL_NGINX_CONF=0)。可手动:"
|
|
||||||
echo " sed \"s|__VERIFY_ROOT__|$VERIFY_ROOT|g\" nginx/yuheng.host.conf | sudo tee $CONF_OUT"
|
|
||||||
echo " sudo nginx -t && sudo systemctl reload nginx"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "==> 本机回环端口(宿主机 Nginx 应反代到这些地址,与 nginx/yuheng.host.conf 一致):"
|
|
||||||
echo " API http://127.0.0.1:8088"
|
|
||||||
echo " 前台 http://127.0.0.1:9080"
|
|
||||||
echo " 后台 http://127.0.0.1:9081"
|
|
||||||
Reference in New Issue
Block a user