From 93edad28e578006f00b54a4a6894311e42ce752c Mon Sep 17 00:00:00 2001 From: ci Date: Tue, 20 Oct 2026 19:16:05 +0800 Subject: [PATCH 1/2] =?UTF-8?q?deploy:=20=E9=80=82=E9=85=8D=201Panel=20?= =?UTF-8?q?=E5=8D=95=E6=9C=BA=EF=BC=88=E5=A4=8D=E7=94=A8=E7=8E=B0=E6=9C=89?= =?UTF-8?q?=20PG=E3=80=81=E5=9B=9E=E7=8E=AF=E7=AB=AF=E5=8F=A3=E3=80=81?= =?UTF-8?q?=E6=89=8B=E5=8A=A8=E8=A7=A6=E5=8F=91=20workflow=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/deploy.yml | 22 ++++++++++++++++++++++ deploy.sh | 12 +++++++----- docker-compose.yml | 31 ++++++++----------------------- 3 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 .gitea/workflows/deploy.yml mode change 100644 => 100755 deploy.sh diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..0b67965 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,22 @@ +name: deploy +on: + workflow_dispatch: + +jobs: + deploy: + runs-on: docker + steps: + - name: SSH deploy + shell: sh + env: + KEY_B64: ${{ secrets.DEPLOY_KEY_B64 }} + DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} + DEPLOY_USER: ${{ secrets.DEPLOY_USER }} + run: | + set -e + apk add --no-cache openssh-client >/dev/null 2>&1 || true + mkdir -p "$HOME/.ssh" + echo "$KEY_B64" | base64 -d > "$HOME/.ssh/id" + chmod 600 "$HOME/.ssh/id" + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i "$HOME/.ssh/id" \ + "$DEPLOY_USER@$DEPLOY_HOST" "cd /opt/fashion/backend_v2 && ./deploy.sh backend" diff --git a/deploy.sh b/deploy.sh old mode 100644 new mode 100755 index 99d9655..a1cb14f --- a/deploy.sh +++ b/deploy.sh @@ -214,12 +214,14 @@ else export RELEASE="${RELEASE:-latest}" fi -# 首次部署先让代理起来(前端构建期要用 18091 取 SSG 数据) -if ! healthy proxy; then - echo "==> 启动代理(首次会一并拉起 db 与 a 槽)" - docker compose up -d proxy -fi +# 首次部署:先写切换点,再只启动代理。 +# - render_active 必须先于 proxy 启动,否则 include 的 map 为空,nginx 会因未知变量启动失败。 +# - --no-deps 避免首次起代理时顺带构建前端(此时 18091 尚未就绪,SSG 取数会失败)。 render_active +if ! healthy proxy; then + echo "==> 启动代理(首次只起代理,槽位由 roll 流程构建)" + docker compose up -d --no-deps proxy +fi if [ "$TARGET" = "rollback" ]; then do_rollback diff --git a/docker-compose.yml b/docker-compose.yml index 8cbfeee..60ce1c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,7 +26,7 @@ x-backend-base: &backend-base BACKSTAGE_PORT: 8092 GIN_MODE: release - HASHID_SECRET: ${HASHID_SECRET:?HASHID_SECRET 未设置:复制 .env.example 为 .env 并填写} + HASHID_SECRET: ${HASHID_SECRET:-} JWT_SECRET: ${JWT_SECRET:?JWT_SECRET 未设置} SSG_TOKEN: ${SSG_TOKEN:-} CORS_ALLOW_ORIGINS: ${CORS_ALLOW_ORIGINS:-https://xisoa.com,https://www.xisoa.com} @@ -35,7 +35,8 @@ x-backend-base: &backend-base RATE_LIMIT_RPS: ${RATE_LIMIT_RPS:-20} RATE_LIMIT_BURST: ${RATE_LIMIT_BURST:-40} - DB_HOST: db + # 复用 1Panel 现有 Postgres(宿主 5432)。host-gateway 让容器经宿主访问它。 + DB_HOST: host.docker.internal DB_PORT: 5432 DB_USER: ${DB_USER:-fashion} DB_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD 未设置} @@ -60,9 +61,8 @@ x-backend-base: &backend-base UPLOAD_DIR: /app/uploads volumes: - uploads:/app/uploads - depends_on: - db: - condition: service_healthy + extra_hosts: + - "host.docker.internal:host-gateway" healthcheck: test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8090/api/health"] interval: 10s @@ -84,29 +84,15 @@ x-web-base: &web-base start_period: 15s services: - # ---- 数据库:PostgreSQL 16 + pgvector ---- - db: - image: pgvector/pgvector:pg16 - restart: unless-stopped - environment: - POSTGRES_USER: ${DB_USER:-fashion} - POSTGRES_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD 未设置} - POSTGRES_DB: ${DB_NAME:-fashion} - TZ: Asia/Shanghai - volumes: - - db_data:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-fashion} -d ${DB_NAME:-fashion}"] - interval: 10s - timeout: 5s - retries: 10 + # ---- 数据库:复用 1Panel 现有 Postgres(连接信息见 .env 的 DB_HOST/DB_PORT/DB_USER/DB_PASSWORD)---- # ---- 常驻代理:整个发布过程中不重建,切换只靠 reload ---- proxy: image: nginx:1.27-alpine restart: unless-stopped ports: - - "${HTTP_PORT:-80}:80" + # 只绑宿主回环:80/443 由 1Panel OpenResty 占用,外层反代到 127.0.0.1:${HTTP_PORT} + - "127.0.0.1:${HTTP_PORT:-8080}:80" - "127.0.0.1:18091:18091" # 前端构建期取 SSG - "127.0.0.1:18092:18092" # 管理后台(SSH 隧道) volumes: @@ -151,5 +137,4 @@ services: <<: *web-base volumes: - db_data: uploads: From 98284c59e89856adf5a09ec675185b157e98d442 Mon Sep 17 00:00:00 2001 From: ci Date: Tue, 20 Oct 2026 22:54:25 +0800 Subject: [PATCH 2/2] =?UTF-8?q?deploy:=20=E4=BF=AE=E5=A4=8D=E5=AE=B9?= =?UTF-8?q?=E5=99=A8=E5=86=85=2018091/18092=20=E7=9B=91=E5=90=AC=EF=BC=9B?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20--no-cache=20=E9=87=8D=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy.sh | 9 +++++++-- nginx/default.conf | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/deploy.sh b/deploy.sh index a1cb14f..425fb2a 100755 --- a/deploy.sh +++ b/deploy.sh @@ -6,6 +6,7 @@ # ./deploy.sh web 只更新前端 # ./deploy.sh --rollback 切回上一个槽(不动代码,秒级) # ./deploy.sh all --no-pull 用服务器上现有代码构建 +# ./deploy.sh web --no-cache 强制不用构建缓存(前端 SSG 依赖后端数据,数据变了要强制重建) # ./deploy.sh --prune 只清理旧镜像(保留最近 KEEP_IMAGES 个,默认 5) # GIT_BRANCH=dev ./deploy.sh all 临时指定分支(优先于 .env) # @@ -16,14 +17,16 @@ cd "$(dirname "$0")" TARGET="backend" NO_PULL=0 +NO_CACHE=0 PRUNE_ONLY=0 for arg in "$@"; do case "$arg" in backend|web|all) TARGET="$arg" ;; --rollback) TARGET="rollback" ;; --no-pull) NO_PULL=1 ;; + --no-cache) NO_CACHE=1 ;; --prune) PRUNE_ONLY=1 ;; - *) echo "用法: ./deploy.sh [backend|web|all|--rollback|--prune] [--no-pull]"; exit 1 ;; + *) echo "用法: ./deploy.sh [backend|web|all|--rollback|--prune] [--no-pull] [--no-cache]"; exit 1 ;; esac done @@ -148,7 +151,9 @@ roll() { # $1=component(backend|web) old=$(cur_slot "$comp"); idle=$(other_slot "$old") echo "==> $comp:活跃槽 $old,更新空闲槽 $idle(镜像 $RELEASE)" - docker compose build "${comp}_a" >/dev/null + local build_flag="" + [ "$NO_CACHE" = "1" ] && build_flag="--no-cache" + docker compose build $build_flag "${comp}_a" >/dev/null # latest 只是给手动执行 compose 命令用的便利别名,deploy 自己从不依赖它 docker tag "fashion-${comp}:${RELEASE}" "fashion-${comp}:latest" 2>/dev/null || true diff --git a/nginx/default.conf b/nginx/default.conf index 1ee7206..8d587a9 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -71,7 +71,7 @@ server { # 内部:前端构建期取 SSG 数据(只绑宿主回环,前端镜像 build 时用 host 网络访问) server { - listen 127.0.0.1:18091; + listen 18091; # 容器内必须监听 0.0.0.0,否则 docker 端口发布到容器网卡时连不上;宿主机只发布到 127.0.0.1 access_log off; location / { proxy_pass http://$ssg_up; @@ -81,7 +81,7 @@ server { # 内部:管理后台(只绑宿主回环;远程访问用 SSH 隧道到 18092) server { - listen 127.0.0.1:18092; + listen 18092; # 同上:容器内回环监听会导致 docker 端口发布不可达(管理后台/爬虫入库走此口) location / { proxy_pass http://$admin_up; proxy_set_header Host $host;