ci(deploy): deploy images over ssh from gitea actions
This commit is contained in:
@@ -131,6 +131,105 @@ jobs:
|
|||||||
docker push "$IMAGE_VERSION_TAG"
|
docker push "$IMAGE_VERSION_TAG"
|
||||||
docker push "$IMAGE_LATEST_TAG"
|
docker push "$IMAGE_LATEST_TAG"
|
||||||
|
|
||||||
|
- name: Deploy image over SSH
|
||||||
|
env:
|
||||||
|
TEST_SSH_HOST: ${{ secrets.TEST_SSH_HOST }}
|
||||||
|
TEST_SSH_USER: ${{ secrets.TEST_SSH_USER }}
|
||||||
|
TEST_SSH_PORT: ${{ secrets.TEST_SSH_PORT }}
|
||||||
|
TEST_SSH_PRIVATE_KEY: ${{ secrets.TEST_SSH_PRIVATE_KEY }}
|
||||||
|
TEST_SSH_KNOWN_HOSTS: ${{ secrets.TEST_SSH_KNOWN_HOSTS }}
|
||||||
|
TEST_DEPLOY_DIR: ${{ secrets.TEST_DEPLOY_DIR }}
|
||||||
|
PROD_SSH_HOST: ${{ secrets.PROD_SSH_HOST }}
|
||||||
|
PROD_SSH_USER: ${{ secrets.PROD_SSH_USER }}
|
||||||
|
PROD_SSH_PORT: ${{ secrets.PROD_SSH_PORT }}
|
||||||
|
PROD_SSH_PRIVATE_KEY: ${{ secrets.PROD_SSH_PRIVATE_KEY }}
|
||||||
|
PROD_SSH_KNOWN_HOSTS: ${{ secrets.PROD_SSH_KNOWN_HOSTS }}
|
||||||
|
PROD_DEPLOY_DIR: ${{ secrets.PROD_DEPLOY_DIR }}
|
||||||
|
REGISTRY_HOST: ${{ secrets.REGISTRY_HOST }}
|
||||||
|
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
|
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
case "$DEPLOY_ENV" in
|
||||||
|
test)
|
||||||
|
DEPLOY_HOST="$TEST_SSH_HOST"
|
||||||
|
DEPLOY_USER="$TEST_SSH_USER"
|
||||||
|
DEPLOY_PORT="${TEST_SSH_PORT:-22}"
|
||||||
|
DEPLOY_KEY="$TEST_SSH_PRIVATE_KEY"
|
||||||
|
DEPLOY_KNOWN_HOSTS="$TEST_SSH_KNOWN_HOSTS"
|
||||||
|
DEPLOY_DIR="${TEST_DEPLOY_DIR:-/opt/cozsweet-web-test}"
|
||||||
|
HOST_PORT="9135"
|
||||||
|
CONTAINER_NAME="cozsweet-web-test"
|
||||||
|
PROJECT_NAME="cozsweet-web-test"
|
||||||
|
;;
|
||||||
|
prod)
|
||||||
|
DEPLOY_HOST="$PROD_SSH_HOST"
|
||||||
|
DEPLOY_USER="$PROD_SSH_USER"
|
||||||
|
DEPLOY_PORT="${PROD_SSH_PORT:-22}"
|
||||||
|
DEPLOY_KEY="$PROD_SSH_PRIVATE_KEY"
|
||||||
|
DEPLOY_KNOWN_HOSTS="$PROD_SSH_KNOWN_HOSTS"
|
||||||
|
DEPLOY_DIR="${PROD_DEPLOY_DIR:-/opt/cozsweet-web-prod}"
|
||||||
|
HOST_PORT="9185"
|
||||||
|
CONTAINER_NAME="cozsweet-web-prod"
|
||||||
|
PROJECT_NAME="cozsweet-web-prod"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported deploy env: $DEPLOY_ENV" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$DEPLOY_HOST" ] || [ -z "$DEPLOY_USER" ] || [ -z "$DEPLOY_KEY" ]; then
|
||||||
|
echo "Missing SSH deployment secrets for $DEPLOY_ENV" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
chmod 700 ~/.ssh
|
||||||
|
KEY_FILE="$HOME/.ssh/cozsweet_deploy_key"
|
||||||
|
printf '%s\n' "$DEPLOY_KEY" > "$KEY_FILE"
|
||||||
|
chmod 600 "$KEY_FILE"
|
||||||
|
|
||||||
|
if [ -n "$DEPLOY_KNOWN_HOSTS" ]; then
|
||||||
|
printf '%s\n' "$DEPLOY_KNOWN_HOSTS" > ~/.ssh/known_hosts
|
||||||
|
else
|
||||||
|
ssh-keyscan -p "$DEPLOY_PORT" "$DEPLOY_HOST" >> ~/.ssh/known_hosts
|
||||||
|
fi
|
||||||
|
|
||||||
|
SSH_TARGET="$DEPLOY_USER@$DEPLOY_HOST"
|
||||||
|
SSH_OPTS="-i $KEY_FILE -p $DEPLOY_PORT -o IdentitiesOnly=yes"
|
||||||
|
SCP_OPTS="-i $KEY_FILE -P $DEPLOY_PORT -o IdentitiesOnly=yes"
|
||||||
|
|
||||||
|
ssh $SSH_OPTS "$SSH_TARGET" "mkdir -p '$DEPLOY_DIR'"
|
||||||
|
scp $SCP_OPTS docker-compose.yml "$SSH_TARGET:$DEPLOY_DIR/docker-compose.yml"
|
||||||
|
scp $SCP_OPTS scripts/server/deploy-docker-image.sh "$SSH_TARGET:$DEPLOY_DIR/deploy-docker-image.sh"
|
||||||
|
scp $SCP_OPTS "$NEXT_ENV_FILE" "$SSH_TARGET:$DEPLOY_DIR/$NEXT_ENV_FILE"
|
||||||
|
|
||||||
|
printf '%s' "$REGISTRY_PASSWORD" \
|
||||||
|
| ssh $SSH_OPTS "$SSH_TARGET" \
|
||||||
|
"docker login '$REGISTRY_HOST' -u '$REGISTRY_USERNAME' --password-stdin"
|
||||||
|
|
||||||
|
ssh $SSH_OPTS "$SSH_TARGET" \
|
||||||
|
"cd '$DEPLOY_DIR' && chmod +x ./deploy-docker-image.sh && ./deploy-docker-image.sh '$IMAGE_VERSION_TAG' '$NEXT_ENV_FILE' '$HOST_PORT' '$CONTAINER_NAME' '$PROJECT_NAME'"
|
||||||
|
|
||||||
|
- name: Purge Cloudflare cache
|
||||||
|
env:
|
||||||
|
CF_ZONE_ID: ${{ secrets.CF_ZONE_ID }}
|
||||||
|
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
if [ -z "$CF_ZONE_ID" ] || [ -z "$CF_API_TOKEN" ]; then
|
||||||
|
echo "Cloudflare secrets are not configured, skip purge."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl -fsS -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/purge_cache" \
|
||||||
|
-H "Authorization: Bearer $CF_API_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"purge_everything":true}'
|
||||||
|
|
||||||
- name: Cleanup build env file
|
- name: Cleanup build env file
|
||||||
if: always()
|
if: always()
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+13
-29
@@ -1,12 +1,14 @@
|
|||||||
# 自动构建与自动重启流程
|
# 自动构建与自动重启流程(旧 Git Hook 方案)
|
||||||
|
|
||||||
本文档说明当前项目通过 Git remote + `post-receive` hook 实现自动部署、自动重启的流程。当前服务器端运行方式已经容器化,核心文件为 [.githooks/post-receive](../.githooks/post-receive)、[Dockerfile](../Dockerfile) 和 [docker-compose.yml](../docker-compose.yml)。
|
本文档记录旧的 Git remote + `post-receive` hook 部署流程,仅作为回滚参考。当前推荐方案已迁移为 Gitea Actions 构建镜像并通过 SSH 部署,见 [Gitea Actions SSH 部署流程](./gitea-actions-ssh-deploy.md)。
|
||||||
|
|
||||||
|
旧方案核心文件为 [.githooks/post-receive](../.githooks/post-receive)、[Dockerfile](../Dockerfile) 和 [docker-compose.yml](../docker-compose.yml)。
|
||||||
|
|
||||||
服务器默认仍会本地构建 Docker 镜像;如果服务器工作树中存在 `.deploy.env` 且配置 `COZSWEET_DEPLOY_IMAGE_SOURCE=pull`,则会改为从镜像仓库拉取由 Gitea Actions 构建好的镜像。
|
服务器默认仍会本地构建 Docker 镜像;如果服务器工作树中存在 `.deploy.env` 且配置 `COZSWEET_DEPLOY_IMAGE_SOURCE=pull`,则会改为从镜像仓库拉取由 Gitea Actions 构建好的镜像。
|
||||||
|
|
||||||
## 部署入口
|
## 旧部署入口
|
||||||
|
|
||||||
当前涉及两个服务器 remote:
|
旧方案涉及两个服务器 remote:
|
||||||
|
|
||||||
| 环境 | Git remote | 推送分支 | 宿主机端口 | 容器端口 | 部署脚本 |
|
| 环境 | Git remote | 推送分支 | 宿主机端口 | 容器端口 | 部署脚本 |
|
||||||
| --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- |
|
||||||
@@ -20,48 +22,30 @@ test root@43.106.13.130:/root/cozsweet-repos/test
|
|||||||
production root@43.106.13.130:/root/cozsweet-repos/main
|
production root@43.106.13.130:/root/cozsweet-repos/main
|
||||||
```
|
```
|
||||||
|
|
||||||
常用发布入口:
|
当前日常发布入口已经改为推送 Gitea 分支并触发 Actions,详见 [Gitea Actions SSH 部署流程](./gitea-actions-ssh-deploy.md)。`scripts/deploy/*` 已改为推送 `gitea` remote,不再推送服务器 remote。旧方案如果需要手动触发,需要直接操作对应服务器仓库。
|
||||||
|
|
||||||
```bash
|
|
||||||
# 发布测试环境
|
|
||||||
./scripts/release/pre_release_web.sh
|
|
||||||
|
|
||||||
# 发布生产环境
|
|
||||||
./scripts/release/release_web.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
也可以只执行推送脚本:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 推送 test remote 的 test 分支
|
|
||||||
./scripts/deploy/deploy_web_test.sh
|
|
||||||
|
|
||||||
# 推送 production remote 的 main 分支
|
|
||||||
./scripts/deploy/deploy_web.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## 本地发布流程
|
## 本地发布流程
|
||||||
|
|
||||||
测试环境发布流程:
|
旧测试环境发布流程(脚本迁移前):
|
||||||
|
|
||||||
1. 进入 test worktree:`cozsweet-frontend-nextjs.worktrees/cozsweet-nextjs-test`
|
1. 进入 test worktree:`cozsweet-frontend-nextjs.worktrees/cozsweet-nextjs-test`
|
||||||
2. 确认当前分支。
|
2. 确认当前分支。
|
||||||
3. 执行 `git rebase dev`,把 `dev` 的最新代码变基到 `test` 分支。
|
3. 执行 `git rebase dev`,把 `dev` 的最新代码变基到 `test` 分支。
|
||||||
4. 复制测试环境图标到 `public/`。
|
4. 复制测试环境图标到 `public/`。
|
||||||
5. 复制 `env-example/.env.local.example` 到 `.env.local`。
|
5. 复制 `env-example/.env.local.example` 到 `.env.local`。
|
||||||
6. 执行 `scripts/deploy/deploy_web_test.sh`。
|
6. 执行旧版 `scripts/deploy/deploy_web_test.sh`。
|
||||||
7. `deploy_web_test.sh` 推送 `test` remote 的 `test` 分支。
|
7. 旧版 `deploy_web_test.sh` 推送 `test` remote 的 `test` 分支。
|
||||||
8. 推送成功后尝试清除 Cloudflare CDN 缓存。
|
8. 推送成功后尝试清除 Cloudflare CDN 缓存。
|
||||||
|
|
||||||
生产环境发布流程:
|
旧生产环境发布流程(脚本迁移前):
|
||||||
|
|
||||||
1. 进入 main worktree:`cozsweet-frontend-nextjs.worktrees/cozsweet-nextjs-main`
|
1. 进入 main worktree:`cozsweet-frontend-nextjs.worktrees/cozsweet-nextjs-main`
|
||||||
2. 确认当前分支。
|
2. 确认当前分支。
|
||||||
3. 执行 `git rebase dev`,把 `dev` 的最新代码变基到 `main` 分支。
|
3. 执行 `git rebase dev`,把 `dev` 的最新代码变基到 `main` 分支。
|
||||||
4. 复制生产环境图标到 `public/`。
|
4. 复制生产环境图标到 `public/`。
|
||||||
5. 复制 `env-example/.env.production.example` 到 `.env.production`。
|
5. 复制 `env-example/.env.production.example` 到 `.env.production`。
|
||||||
6. 执行 `scripts/deploy/deploy_web.sh`。
|
6. 执行旧版 `scripts/deploy/deploy_web.sh`。
|
||||||
7. `deploy_web.sh` 强制推送 `production` remote 的 `main` 分支。
|
7. 旧版 `deploy_web.sh` 强制推送 `production` remote 的 `main` 分支。
|
||||||
8. 推送成功后尝试清除 Cloudflare CDN 缓存。
|
8. 推送成功后尝试清除 Cloudflare CDN 缓存。
|
||||||
|
|
||||||
## 服务器端 post-receive 流程
|
## 服务器端 post-receive 流程
|
||||||
|
|||||||
+6
-23
@@ -1,6 +1,6 @@
|
|||||||
# Docker 镜像持续构建与发布
|
# Docker 镜像持续构建与发布
|
||||||
|
|
||||||
本文档说明 Gitea Actions 中 Docker 镜像构建与发布 workflow 的使用方式。对应脚本为 [.gitea/workflows/docker-image.yml](../.gitea/workflows/docker-image.yml)。
|
本文档说明 Gitea Actions 中 Docker 镜像构建、发布与 SSH 部署 workflow 的使用方式。对应脚本为 [.gitea/workflows/docker-image.yml](../.gitea/workflows/docker-image.yml)。
|
||||||
|
|
||||||
## 职责划分
|
## 职责划分
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
| Workflow | 触发时机 | 职责 |
|
| Workflow | 触发时机 | 职责 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `.gitea/workflows/ci.yml` | `dev`、`main`、`test` push / PR | 安装依赖、Lint、单元测试、Next.js 构建 |
|
| `.gitea/workflows/ci.yml` | `dev`、`main`、`test` push / PR | 安装依赖、Lint、单元测试、Next.js 构建 |
|
||||||
| `.gitea/workflows/docker-image.yml` | `main`、`test` push / 手动触发 | 构建 Docker 镜像并推送到镜像仓库 |
|
| `.gitea/workflows/docker-image.yml` | `main`、`test` push / 手动触发 | 构建 Docker 镜像、推送到镜像仓库,并通过 SSH 部署 |
|
||||||
|
|
||||||
这样可以避免所有开发分支都发布镜像,也能让代码检查失败时不污染镜像仓库。
|
这样可以避免所有开发分支都发布镜像,也能让代码检查失败时不污染镜像仓库。
|
||||||
|
|
||||||
@@ -90,36 +90,19 @@ docker image ls | grep cozsweet-web
|
|||||||
|
|
||||||
## 部署服务器拉取镜像
|
## 部署服务器拉取镜像
|
||||||
|
|
||||||
部署服务器需要先登录镜像仓库:
|
当前推荐由 Gitea Actions 通过 SSH 登录部署服务器并执行部署脚本,不再依赖服务器 Git remote 的 `post-receive` hook。完整说明见 [Gitea Actions SSH 部署流程](./gitea-actions-ssh-deploy.md)。
|
||||||
|
|
||||||
|
如果需要在服务器上手动验证镜像拉取,可先登录镜像仓库:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker login REGISTRY_HOST
|
docker login REGISTRY_HOST
|
||||||
```
|
```
|
||||||
|
|
||||||
然后在部署服务器工作树中创建 `.deploy.env`:
|
Actions 部署时会根据当前分支和 commit 自动拉取:
|
||||||
|
|
||||||
```bash
|
|
||||||
cp env-example/.deploy.env.example .deploy.env
|
|
||||||
```
|
|
||||||
|
|
||||||
配置示例:
|
|
||||||
|
|
||||||
```env
|
|
||||||
COZSWEET_DEPLOY_IMAGE_SOURCE=pull
|
|
||||||
COZSWEET_REGISTRY_IMAGE=gitea.banlv-ai.com/admin/cozsweet-web
|
|
||||||
```
|
|
||||||
|
|
||||||
`post-receive` 会根据当前分支和 commit 自动拉取:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gitea.banlv-ai.com/admin/cozsweet-web:test-<short_sha>
|
gitea.banlv-ai.com/admin/cozsweet-web:test-<short_sha>
|
||||||
gitea.banlv-ai.com/admin/cozsweet-web:prod-<short_sha>
|
gitea.banlv-ai.com/admin/cozsweet-web:prod-<short_sha>
|
||||||
```
|
```
|
||||||
|
|
||||||
如果需要改用 latest tag,可以在服务器 `.deploy.env` 中显式设置:
|
|
||||||
|
|
||||||
```env
|
|
||||||
COZSWEET_REMOTE_IMAGE_TAG=prod-latest
|
|
||||||
```
|
|
||||||
|
|
||||||
推荐优先使用默认的 `<env>-<short_sha>` 精确 tag,这样发布和回滚都更可控。
|
推荐优先使用默认的 `<env>-<short_sha>` 精确 tag,这样发布和回滚都更可控。
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
# Gitea Actions SSH 部署流程
|
||||||
|
|
||||||
|
当前推荐部署链路:
|
||||||
|
|
||||||
|
```text
|
||||||
|
push test/main
|
||||||
|
→ Gitea Actions 构建并推送 Docker 镜像
|
||||||
|
→ Actions 通过 SSH 登录目标服务器
|
||||||
|
→ 目标服务器 docker pull 指定镜像 tag
|
||||||
|
→ docker compose up -d --no-build
|
||||||
|
```
|
||||||
|
|
||||||
|
服务器不再依赖 Git remote 的 `post-receive` hook 拉取或构建镜像。
|
||||||
|
|
||||||
|
## 分支与环境
|
||||||
|
|
||||||
|
| 分支 | 环境 | 镜像 tag | 宿主机端口 | 默认服务器目录 | 容器名 |
|
||||||
|
| --- | --- | --- | --- | --- | --- |
|
||||||
|
| `test` | 测试环境 | `test-<short_sha>` | `9135` | `/opt/cozsweet-web-test` | `cozsweet-web-test` |
|
||||||
|
| `main` | 生产环境 | `prod-<short_sha>` | `9185` | `/opt/cozsweet-web-prod` | `cozsweet-web-prod` |
|
||||||
|
|
||||||
|
## Gitea Secrets
|
||||||
|
|
||||||
|
已有镜像构建 Secrets:
|
||||||
|
|
||||||
|
| Secret | 说明 |
|
||||||
|
| --- | --- |
|
||||||
|
| `REGISTRY_HOST` | Docker registry host,例如 `gitea.banlv-ai.com` |
|
||||||
|
| `REGISTRY_IMAGE` | 镜像仓库,例如 `gitea.banlv-ai.com/admin/cozsweet-web` |
|
||||||
|
| `REGISTRY_USERNAME` | registry 用户名 |
|
||||||
|
| `REGISTRY_PASSWORD` | registry 密码或 token |
|
||||||
|
| `TEST_ENV_FILE` | 测试环境 `.env.local` 内容 |
|
||||||
|
| `PRODUCTION_ENV_FILE` | 生产环境 `.env.production` 内容 |
|
||||||
|
|
||||||
|
新增 SSH 部署 Secrets:
|
||||||
|
|
||||||
|
| Secret | 说明 |
|
||||||
|
| --- | --- |
|
||||||
|
| `TEST_SSH_HOST` / `PROD_SSH_HOST` | 测试 / 生产服务器地址 |
|
||||||
|
| `TEST_SSH_USER` / `PROD_SSH_USER` | SSH 用户,例如 `root` |
|
||||||
|
| `TEST_SSH_PRIVATE_KEY` / `PROD_SSH_PRIVATE_KEY` | 私钥内容 |
|
||||||
|
| `TEST_SSH_PORT` / `PROD_SSH_PORT` | 可选,默认 `22` |
|
||||||
|
| `TEST_SSH_KNOWN_HOSTS` / `PROD_SSH_KNOWN_HOSTS` | 可选,推荐配置 `ssh-keyscan` 输出 |
|
||||||
|
| `TEST_DEPLOY_DIR` / `PROD_DEPLOY_DIR` | 可选,覆盖默认服务器目录 |
|
||||||
|
| `CF_ZONE_ID` / `CF_API_TOKEN` | 可选,部署成功后清理 Cloudflare 缓存 |
|
||||||
|
|
||||||
|
## 服务器要求
|
||||||
|
|
||||||
|
目标服务器需要:
|
||||||
|
|
||||||
|
1. 安装 Docker,并支持 `docker compose` 或 `docker-compose`。
|
||||||
|
2. SSH 用户可执行 Docker 命令。
|
||||||
|
3. 能访问 Gitea registry。
|
||||||
|
4. 部署目录允许 SSH 用户写入。
|
||||||
|
|
||||||
|
workflow 会自动同步以下文件到服务器部署目录:
|
||||||
|
|
||||||
|
```text
|
||||||
|
docker-compose.yml
|
||||||
|
deploy-docker-image.sh
|
||||||
|
.env.local 或 .env.production
|
||||||
|
```
|
||||||
|
|
||||||
|
## 本地发布入口
|
||||||
|
|
||||||
|
本地发布脚本现在只负责推送 Gitea 分支,触发 Actions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 测试环境
|
||||||
|
./scripts/release/pre_release_web.sh
|
||||||
|
|
||||||
|
# 生产环境
|
||||||
|
./scripts/release/release_web.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
也可以直接推送:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git push gitea test
|
||||||
|
git push --force gitea main
|
||||||
|
```
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
测试环境:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh <user>@<test-host>
|
||||||
|
cd /opt/cozsweet-web-test
|
||||||
|
docker compose ps
|
||||||
|
curl -I http://127.0.0.1:9135/
|
||||||
|
```
|
||||||
|
|
||||||
|
生产环境:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh <user>@<prod-host>
|
||||||
|
cd /opt/cozsweet-web-prod
|
||||||
|
docker compose ps
|
||||||
|
curl -I http://127.0.0.1:9185/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 旧 hook 处理
|
||||||
|
|
||||||
|
服务器上的 Git remote `post-receive` hook 属于旧部署链路。迁移完成并验证 Actions SSH 部署成功后,可以在服务器上禁用旧 hook,避免误触发:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mv /root/cozsweet-repos/test/.git/hooks/post-receive /root/cozsweet-repos/test/.git/hooks/post-receive.disabled
|
||||||
|
mv /root/cozsweet-repos/main/.git/hooks/post-receive /root/cozsweet-repos/main/.git/hooks/post-receive.disabled
|
||||||
|
```
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# 推送指定分支到指定远端
|
# 推送指定分支到指定远端。
|
||||||
# 期望服务器端 post-receive hook 已就位;本脚本只做 git push,不负责构建/启动
|
# 当前发布由 Gitea Actions 构建镜像并通过 SSH 部署;本脚本只负责触发分支 push。
|
||||||
# 调用方:deploy_web.sh(production)→ push_to_remote "production" "main"
|
# 调用方:deploy_web.sh(production)→ push_to_remote "gitea" "main"
|
||||||
# deploy_web_test.sh(test)→ push_to_remote "test" "test"
|
# deploy_web_test.sh(test)→ push_to_remote "gitea" "test"
|
||||||
push_to_remote() {
|
push_to_remote() {
|
||||||
local remote="$1"
|
local remote="$1"
|
||||||
local branch="$2"
|
local branch="$2"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# ==========================================
|
# ==========================================
|
||||||
# 生产环境 Web 部署脚本(Next.js + git push 模型)
|
# 生产环境 Web 部署脚本(Next.js + Gitea Actions SSH 部署模型)
|
||||||
# 原始 Dart: scripts/deploy/deploy_web.sh
|
# 原始 Dart: scripts/deploy/deploy_web.sh
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
|
||||||
@@ -11,8 +11,8 @@ source "$SCRIPT_DIR/_deploy_lib.sh"
|
|||||||
|
|
||||||
# 主函数
|
# 主函数
|
||||||
main() {
|
main() {
|
||||||
push_to_remote "production" "main"
|
push_to_remote "gitea" "main"
|
||||||
purge_cdn_cache
|
# NEW_VERSION=$(bump_version)
|
||||||
}
|
}
|
||||||
|
|
||||||
main
|
main
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# ==========================================
|
# ==========================================
|
||||||
# 测试环境 Web 部署脚本(Next.js + git push 模型)
|
# 测试环境 Web 部署脚本(Next.js + Gitea Actions SSH 部署模型)
|
||||||
# 原始 Dart: scripts/deploy/deploy_web_test.sh
|
# 原始 Dart: scripts/deploy/deploy_web_test.sh
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
|
||||||
@@ -11,8 +11,7 @@ source "$SCRIPT_DIR/_deploy_lib.sh"
|
|||||||
|
|
||||||
# 主函数
|
# 主函数
|
||||||
main() {
|
main() {
|
||||||
push_to_remote "test" "test"
|
push_to_remote "gitea" "test"
|
||||||
purge_cdn_cache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main
|
main
|
||||||
|
|||||||
Executable
+53
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
IMAGE="${1:-}"
|
||||||
|
ENV_FILE="${2:-}"
|
||||||
|
HOST_PORT="${3:-}"
|
||||||
|
CONTAINER_NAME="${4:-}"
|
||||||
|
PROJECT_NAME="${5:-}"
|
||||||
|
|
||||||
|
if [ -z "$IMAGE" ] || [ -z "$ENV_FILE" ] || [ -z "$HOST_PORT" ] || [ -z "$CONTAINER_NAME" ] || [ -z "$PROJECT_NAME" ]; then
|
||||||
|
echo "Usage: $0 <image> <env-file> <host-port> <container-name> <compose-project-name>" >&2
|
||||||
|
exit 64
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "docker-compose.yml" ]; then
|
||||||
|
echo "Missing docker-compose.yml in $(pwd)" >&2
|
||||||
|
exit 66
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$ENV_FILE" ]; then
|
||||||
|
echo "Missing env file: $ENV_FILE" >&2
|
||||||
|
exit 66
|
||||||
|
fi
|
||||||
|
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
COMPOSE=(docker compose)
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
COMPOSE=(docker-compose)
|
||||||
|
else
|
||||||
|
echo "docker compose command not found" >&2
|
||||||
|
exit 127
|
||||||
|
fi
|
||||||
|
|
||||||
|
export COZSWEET_IMAGE="$IMAGE"
|
||||||
|
export COZSWEET_ENV_FILE="$ENV_FILE"
|
||||||
|
export COZSWEET_HOST_PORT="$HOST_PORT"
|
||||||
|
export COZSWEET_CONTAINER_NAME="$CONTAINER_NAME"
|
||||||
|
export COMPOSE_PROJECT_NAME="$PROJECT_NAME"
|
||||||
|
|
||||||
|
echo "=== deploy image: $COZSWEET_IMAGE ==="
|
||||||
|
echo "=== env file: $COZSWEET_ENV_FILE ==="
|
||||||
|
echo "=== host port: $COZSWEET_HOST_PORT ==="
|
||||||
|
echo "=== container: $COZSWEET_CONTAINER_NAME ==="
|
||||||
|
echo "=== compose project: $COMPOSE_PROJECT_NAME ==="
|
||||||
|
|
||||||
|
"${COMPOSE[@]}" pull web
|
||||||
|
"${COMPOSE[@]}" up -d --remove-orphans --no-build web
|
||||||
|
"${COMPOSE[@]}" ps
|
||||||
|
|
||||||
|
docker image prune -f
|
||||||
|
|
||||||
|
echo "=== deploy done ==="
|
||||||
Reference in New Issue
Block a user