init: ALiYunManager 基础设施项目 — nginx配置/docker-compose/部署文档

This commit is contained in:
Superuser
2026-05-16 23:27:24 +08:00
commit 0413d2715c
28 changed files with 2590 additions and 0 deletions
+766
View File
@@ -0,0 +1,766 @@
# Git 私有仓库 + 自动部署流水线 (AI可读)
> 基于阿里云服务器 `8.136.137.59`,部署 Gitea 私有 Git 仓库 + Webhook 自动部署流水线。
> 遵循现有架构:beian-nginx → main-nginx → 服务容器。
> **所有 Git 相关文件统一放在 `/home/Git/`,能容器化的全部容器化。**
---
## 一、架构总览
```
外网 git.dxz99wyr.cn
beian-nginx (:80/:443)
│ 新增: git.dxz99wyr.cn → 172.19.0.1:8080
main-nginx (:8080)
│ 新增: git.dxz99wyr.cn → gitea:3000
┌─────────────────────────────────────────────┐
│ gitea (Docker) │
│ 镜像: gitea/gitea:latest │
│ 内部端口: 3000 (Web UI) │
│ 内部端口: 22 (SSH Git) → 宿主机映射 2222 │
│ 数据卷: /home/Git/gitea/data → /data │
│ 网络: aliyun-app-network │
└──────────┬──────────────────────────────────┘
│ Webhook POST (push 事件)
│ URL: http://webhook:9000/hooks/xxx
┌─────────────────────────────────────────────┐
│ webhook (Docker / 自定义镜像) │
│ 内部端口: 9000 │
│ 内置: git + docker CLI + webhook 二进制 │
│ 收到 push → 执行对应脚本 │
│ 网络: aliyun-app-network │
│ 挂载: docker.sock(操控宿主机 Docker
│ /home/Git/webhook/ → 配置只读 │
│ /opt/ALiYunManager/ → 更新代码+重载 │
│ /opt/services/ → 更新各服务代码 │
│ /home/Git/logs/ → 部署日志 │
└──────────┬──────────────────────────────────┘
│ git clone/pullDocker 内网 HTTP
│ http://${GITEA_TOKEN}@gitea:3000/...
│ docker-compose up -d(通过 docker.sock
┌──────┴──────┬──────────┐
│ │ │
resume-web resume-api 其他服务...
(自动拉代码、构建、重启)
```
### 端口规划
| 端口 | 用途 | 对外网 | 说明 |
|------|------|--------|------|
| `2222` | Git SSH 克隆/推送(开发者用) | 开放 | gitea 容器 22 → 宿主机 2222 |
| `3000` | Gitea Web UI(容器内部) | 不开放 | 仅 Docker 网络内,通过 nginx 代理 |
| `9000` | Webhook 接收器(容器内部) | 不开放 | 仅 Docker 网络内,gitea 调用 |
> 2222 端口需要在阿里云安全组和服务器防火墙中放行。
### 宿主机文件总览(仅 `/home/Git/` 目录)
```
/home/Git/
├── gitea/
│ ├── docker-compose.yml # Gitea 容器定义
│ └── data/ # Gitea 全部数据(SQLite + 仓库 + 配置)
├── webhook/
│ ├── Dockerfile # 自定义镜像(git + docker CLI + webhook
│ ├── docker-compose.yml # Webhook 容器定义
│ ├── hooks.json # Webhook 路由规则
│ ├── .env # GITEA_TOKEN 等敏感变量
│ └── scripts/ # 各服务部署脚本
│ ├── deploy-common.sh
│ ├── deploy-resume-web.sh
│ ├── deploy-resume-api.sh
│ ├── deploy-aliyun-manager.sh
│ └── deploy-miniapp-web.sh
└── logs/
└── deploy.log # 部署历史日志
```
> 除此之外无需在宿主机创建其他文件。SSH 密钥、Git 配置等均在 Docker 容器内部处理。
---
## 二、部署步骤
### 步骤 1:服务器环境准备
```bash
ssh -i "D:\003_Project\小程序连接.pem" root@8.136.137.59
# 创建目录结构(一次性)
mkdir -p /home/Git/gitea/data
mkdir -p /home/Git/webhook/scripts
mkdir -p /home/Git/logs
# 放行 Git SSH 端口
ufw allow 2222/tcp
# 阿里云安全组也需要添加 2222 入方向规则
```
### 步骤 2:部署 Gitea 容器
创建 `/home/Git/gitea/docker-compose.yml`
```yaml
version: "3.8"
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: always
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__server__DOMAIN=git.dxz99wyr.cn
- GITEA__server__SSH_DOMAIN=8.136.137.59
- GITEA__server__SSH_PORT=2222
- GITEA__server__ROOT_URL=https://git.dxz99wyr.cn
- GITEA__server__HTTP_PORT=3000
- GITEA__server__DISABLE_SSH=false
- GITEA__database__DB_TYPE=sqlite3
- GITEA__repository__ENABLE_PUSH_CREATE_USER=true
- GITEA__repository__ENABLE_PUSH_CREATE_ORG=true
- GITEA__service__DISABLE_REGISTRATION=true
ports:
- "2222:22"
volumes:
- /home/Git/gitea/data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
networks:
- gitea-network
networks:
gitea-network:
driver: bridge
name: aliyun-app-network
```
```bash
cd /home/Git/gitea
docker-compose up -d
# 验证
docker-compose ps
docker-compose logs -f
```
### 步骤 3:配置 Nginx 反向代理
#### 3a. main-nginx 配置 — 已存在,确认即可
文件 `nginx/conf.d/git.conf`(已在项目中创建):
```nginx
server {
listen 80;
server_name git.dxz99wyr.cn;
access_log /var/log/nginx/git.access.log main;
error_log /var/log/nginx/git.error.log warn;
location / {
proxy_pass http://gitea:3000;
proxy_http_version 1.1;
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;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
proxy_send_timeout 300s;
client_max_body_size 512m;
}
}
```
#### 3b. 重载 main-nginx
```bash
cd /opt/ALiYunManager
docker-compose exec nginx nginx -t && docker-compose exec nginx nginx -s reload
```
#### 3c. beian-nginx 追加中转
```bash
# 备份
cp /opt/beian-docker/nginx.conf /opt/beian-docker/nginx.conf.bak.$(date +%Y%m%d_%H%M)
# 编辑配置,追加以下 server 块
vim /opt/beian-docker/nginx.conf
```
`http {}` 内追加:
```nginx
# Gitea 私有 Git 仓库
server {
listen 80;
server_name git.dxz99wyr.cn;
location / {
proxy_pass http://172.19.0.1:8080;
proxy_http_version 1.1;
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;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
client_max_body_size 512m;
}
}
```
```bash
docker exec beian-nginx nginx -t && docker exec beian-nginx nginx -s reload
```
### 步骤 4DNS 解析
阿里云域名控制台添加:
| 记录类型 | 主机记录 | 记录值 |
|---------|---------|--------|
| A | git | 8.136.137.59 |
### 步骤 5:初始化 Gitea
1. 浏览器访问 `http://git.dxz99wyr.cn`
2. 首次访问进入安装页(大部分配置已由 docker-compose.yml 环境变量预设)
3. 设置管理员账号:
- 用户名:`admin`
- 密码:**设置强密码并牢记**
- 邮箱:`admin@dxz99wyr.cn`
4. 点击「安装 Gitea」
### 步骤 6:创建 Gitea 访问令牌(供 Webhook 脚本拉取代码用)
1. Gitea Web UI → 右上角头像 → **Settings****Applications**
2. **Generate New Token**
- Token Name`deploy-token`
- 权限:勾选 `read:repository`
3. 复制生成的 Token(只显示一次),保存备用
### 步骤 7:创建仓库
在 Gitea Web UI 中创建:
| 仓库名 | 用途 |
|--------|------|
| `aliyun-manager` | ALiYunManager 部署项目 |
| `resume-web` | 个人简历前端 |
| `resume-api` | 个人简历后台 |
| `miniapp-web` | 小程序前端 |
| `miniapp-api` | 小程序后台 |
---
## 三、Webhook 自动部署流水线
```
git push → Gitea → Webhook POST → webhook:9000/hooks/xxx → 对应脚本 → clone/pull → docker-compose 重建
```
### 步骤 8:构建 Webhook 自定义镜像
创建 `/home/Git/webhook/Dockerfile`
```dockerfile
# ============================================
# Webhook 接收器自定义镜像
# 内置: docker CLI + git + bash + webhook 二进制
# ============================================
FROM docker:cli
RUN apk add --no-cache git bash curl
ARG WEBHOOK_VERSION=2.8.1
ADD https://github.com/adnanh/webhook/releases/download/${WEBHOOK_VERSION}/webhook-linux-amd64.tar.gz /tmp/
RUN tar -xzf /tmp/webhook-linux-amd64.tar.gz -C /usr/local/bin/ webhook && \
chmod +x /usr/local/bin/webhook && \
rm /tmp/webhook-linux-amd64.tar.gz
WORKDIR /opt/webhook
ENTRYPOINT ["/usr/local/bin/webhook"]
```
### 步骤 9:创建 Webhook 配置文件
#### 9a. 环境变量 `/home/Git/webhook/.env`
```bash
# Gitea 访问令牌(步骤 6 中生成的)
GITEA_TOKEN=粘贴你的token到这里
# 各个 Webhook Secret(随机生成,与 Gitea Webhook 设置保持一致)
SECRET_RESUME_WEB=resume-web-deploy-secret
SECRET_RESUME_API=resume-api-deploy-secret
SECRET_ALIYUN_MANAGER=aliyun-manager-deploy-secret
SECRET_MINIAPP_WEB=miniapp-web-deploy-secret
```
#### 9b. Webhook 路由 `/home/Git/webhook/hooks.json`
```json
[
{
"id": "resume-web",
"execute-command": "/opt/webhook/scripts/deploy-resume-web.sh",
"command-working-directory": "/opt/webhook/scripts",
"trigger-rule": {
"match": {
"type": "value",
"value": "resume-web-deploy-secret",
"parameter": {
"source": "payload",
"name": "secret"
}
}
}
},
{
"id": "resume-api",
"execute-command": "/opt/webhook/scripts/deploy-resume-api.sh",
"command-working-directory": "/opt/webhook/scripts",
"trigger-rule": {
"match": {
"type": "value",
"value": "resume-api-deploy-secret",
"parameter": {
"source": "payload",
"name": "secret"
}
}
}
},
{
"id": "aliyun-manager",
"execute-command": "/opt/webhook/scripts/deploy-aliyun-manager.sh",
"command-working-directory": "/opt/webhook/scripts",
"trigger-rule": {
"match": {
"type": "value",
"value": "aliyun-manager-deploy-secret",
"parameter": {
"source": "payload",
"name": "secret"
}
}
}
},
{
"id": "miniapp-web",
"execute-command": "/opt/webhook/scripts/deploy-miniapp-web.sh",
"command-working-directory": "/opt/webhook/scripts",
"trigger-rule": {
"match": {
"type": "value",
"value": "miniapp-web-deploy-secret",
"parameter": {
"source": "payload",
"name": "secret"
}
}
}
}
]
```
#### 9c. docker-compose `/home/Git/webhook/docker-compose.yml`
```yaml
version: "3.8"
services:
webhook:
build: .
image: webhook-receiver:latest
container_name: webhook
restart: always
ports:
- "9000:9000"
env_file:
- .env
volumes:
# Webhook 配置(只读)
- /home/Git/webhook/hooks.json:/opt/webhook/hooks.json:ro
- /home/Git/webhook/scripts:/opt/webhook/scripts:ro
# 部署日志(读写)
- /home/Git/logs:/opt/webhook/logs
# 宿主机 Docker 控制权
- /var/run/docker.sock:/var/run/docker.sock
# 各项目代码目录(用于 git pull 更新)
- /opt/ALiYunManager:/opt/ALiYunManager
- /opt/services/resume-web:/opt/services/resume-web
- /opt/services/resume-api:/opt/services/resume-api
- /opt/services/miniapp-web:/opt/services/miniapp-web
networks:
- webhook-network
command:
- "-hooks=/opt/webhook/hooks.json"
- "-verbose"
- "-hot-reload"
networks:
webhook-network:
driver: bridge
name: aliyun-app-network
```
> **说明**
> - `-hot-reload`:修改 hooks.json 后无需重启容器
> - 代码目录挂载:webhook 容器直接 git pull 到这些目录,然后通过 docker.sock 执行 docker-compose
> - 容器内部通过 HTTP 访问 gitea`http://gitea:3000`,无需 SSH
#### 9d. 通用部署函数 `/home/Git/webhook/scripts/deploy-common.sh`
```bash
#!/bin/bash
# ============================================
# 通用部署函数库
# 被各服务脚本 source 引用
# 运行在 webhook 容器内
# ============================================
set -e
LOG_DIR="/opt/webhook/logs"
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
log() {
local SERVICE=$1
local MESSAGE=$2
echo "[$TIMESTAMP] [$SERVICE] $MESSAGE" | tee -a "$LOG_DIR/deploy.log"
}
# 从 Gitea 拉取最新代码(Docker 内网 HTTP
# 参数: REPO_NAME GIT_DIR BRANCH
# 使用 GITEA_TOKEN 环境变量认证
clone_or_pull() {
local REPO_NAME=$1
local GIT_DIR=$2
local BRANCH=${3:-main}
local REPO_URL="http://${GITEA_TOKEN}@gitea:3000/admin/${REPO_NAME}.git"
if [ -d "$GIT_DIR/.git" ]; then
log "git" "拉取最新代码: ${REPO_NAME}${GIT_DIR} (分支: ${BRANCH})"
cd "$GIT_DIR"
git fetch origin
git reset --hard "origin/${BRANCH}"
else
log "git" "克隆仓库: ${REPO_NAME}${GIT_DIR} (分支: ${BRANCH})"
git clone -b "$BRANCH" "$REPO_URL" "$GIT_DIR"
fi
}
# 重建并重启 Docker 服务
# 参数: COMPOSE_DIR SERVICE_NAME
docker_rebuild() {
local COMPOSE_DIR=$1
local SERVICE_NAME=$2
cd "$COMPOSE_DIR"
if [ -f "Dockerfile" ]; then
log "$SERVICE_NAME" "构建镜像..."
docker-compose build "$SERVICE_NAME"
fi
log "$SERVICE_NAME" "重启容器..."
docker-compose up -d --no-deps --force-recreate "$SERVICE_NAME"
log "$SERVICE_NAME" "部署完成"
}
```
> **关键点**`clone_or_pull` 使用 `http://${GITEA_TOKEN}@gitea:3000/...` 格式,
> Gitea 和 webhook 同属 `aliyun-app-network`,直接用容器名 `gitea:3000` 通信,
> 不经过外网,也不需要 SSH。
#### 9e. 各服务部署脚本
**个人简历前端** `/home/Git/webhook/scripts/deploy-resume-web.sh`
```bash
#!/bin/bash
source /opt/webhook/scripts/deploy-common.sh
SERVICE="resume-web"
REPO_NAME="resume-web"
GIT_DIR="/opt/services/resume-web"
BRANCH="main"
log "$SERVICE" "========== 开始部署 =========="
clone_or_pull "$REPO_NAME" "$GIT_DIR" "$BRANCH"
docker_rebuild "$GIT_DIR" "$SERVICE"
log "$SERVICE" "========== 部署完成 =========="
```
**个人简历后台** `/home/Git/webhook/scripts/deploy-resume-api.sh`
```bash
#!/bin/bash
source /opt/webhook/scripts/deploy-common.sh
SERVICE="resume-api"
REPO_NAME="resume-api"
GIT_DIR="/opt/services/resume-api"
BRANCH="main"
log "$SERVICE" "========== 开始部署 =========="
clone_or_pull "$REPO_NAME" "$GIT_DIR" "$BRANCH"
docker_rebuild "$GIT_DIR" "$SERVICE"
log "$SERVICE" "========== 部署完成 =========="
```
**ALiYunManagernginx 配置部署)** `/home/Git/webhook/scripts/deploy-aliyun-manager.sh`
```bash
#!/bin/bash
source /opt/webhook/scripts/deploy-common.sh
SERVICE="aliyun-manager"
REPO_NAME="aliyun-manager"
GIT_DIR="/opt/ALiYunManager"
BRANCH="main"
log "$SERVICE" "========== 开始部署 =========="
clone_or_pull "$REPO_NAME" "$GIT_DIR" "$BRANCH"
cd "$GIT_DIR"
# 重载 main-nginx 配置(不重启容器,零停机)
docker-compose exec -T nginx nginx -t && docker-compose exec -T nginx nginx -s reload
log "$SERVICE" "main-nginx 配置已重载"
log "$SERVICE" "========== 部署完成 =========="
```
**小程序前端** `/home/Git/webhook/scripts/deploy-miniapp-web.sh`
```bash
#!/bin/bash
source /opt/webhook/scripts/deploy-common.sh
SERVICE="miniapp-web"
REPO_NAME="miniapp-web"
GIT_DIR="/opt/services/miniapp-web"
BRANCH="main"
log "$SERVICE" "========== 开始部署 =========="
clone_or_pull "$REPO_NAME" "$GIT_DIR" "$BRANCH"
docker_rebuild "$GIT_DIR" "$SERVICE"
log "$SERVICE" "========== 部署完成 =========="
```
### 步骤 10:构建并启动 Webhook 容器
```bash
# 赋予脚本执行权限
chmod +x /home/Git/webhook/scripts/*.sh
# 构建自定义镜像并启动
cd /home/Git/webhook
docker-compose build
docker-compose up -d
# 验证
docker-compose ps
docker-compose logs -f
```
---
## 四、Gitea Webhook 配置
对每个仓库,在 Gitea Web UI 中操作:
### 配置步骤
1. 进入仓库 → **Settings****Webhooks**
2. 点击 **Add Webhook** → 选择 **Gitea**
3. 填写:
| 字段 | 值 |
|------|-----|
| Target URL | `http://webhook:9000/hooks/resume-web`(对应 hooks.json 中的 id |
| HTTP Method | `POST` |
| POST Content Type | `application/json` |
| Secret | `resume-web-deploy-secret`(与 hooks.json 和 .env 一致) |
| Trigger On | 勾选 **Push** |
4. 点击 **Add Webhook**
5. 点击 **Test Delivery** 验证
### 各仓库 Webhook 配置汇总
| 仓库 | Target URL | Secret |
|------|-----------|--------|
| `resume-web` | `http://webhook:9000/hooks/resume-web` | `resume-web-deploy-secret` |
| `resume-api` | `http://webhook:9000/hooks/resume-api` | `resume-api-deploy-secret` |
| `aliyun-manager` | `http://webhook:9000/hooks/aliyun-manager` | `aliyun-manager-deploy-secret` |
| `miniapp-web` | `http://webhook:9000/hooks/miniapp-web` | `miniapp-web-deploy-secret` |
> Gitea 和 webhook 同属 `aliyun-app-network`,用容器名 `webhook` 直接通信。
---
## 五、本地开发环境配置
### 个人 Git 配置
```bash
git config --global user.name "Your Name"
git config --global user.email "your-email@example.com"
```
### SSH 密钥(用于 git push
```bash
# 生成密钥(如果还没有)
ssh-keygen -t ed25519 -C "your-email@example.com"
# 将公钥添加到 Gitea
cat ~/.ssh/id_ed25519.pub
# Gitea Web UI → Settings → SSH/GPG Keys → Add Key 粘贴
```
### 关联远程仓库并推送
```bash
# 以 resume-web 为例
cd D:\003_Project\ALiYunManager\services\resume-web
git init
git add .
git commit -m "init"
# 添加远程仓库(走 SSH,端口 2222)
git remote add origin ssh://git@8.136.137.59:2222/admin/resume-web.git
# 推送(此后每次推送自动触发服务器部署)
git push -u origin main
```
### SSH 别名(可选,简化地址)
编辑 `~/.ssh/config`
```
Host gitea
HostName 8.136.137.59
Port 2222
User git
IdentityFile ~/.ssh/id_ed25519
```
之后:
```bash
git clone gitea:admin/resume-web.git
```
### 日常开发流程
```bash
git add .
git commit -m "feat: 更新xxx"
git push
# ↑ 推送后自动触发 Webhook → 服务器自动拉代码并部署,无需手动 ssh
```
---
## 六、安全设计
| 措施 | 说明 |
|------|------|
| 禁用公开注册 | `DISABLE_REGISTRATION=true` |
| Webhook 仅内网可达 | 9000 端口无宿主机映射,仅 Docker 网络内 gitea 可调用 |
| 独立 Secret | 每个仓库使用不同的 Webhook Secret |
| 令牌最小权限 | Gitea Token 仅勾选 `read:repository`,只能拉代码 |
| Token 存于 .env | 不硬编码在脚本中,`.env` 文件权限 600 |
| docker.sock 隔离 | webhook 是唯一挂载 docker.sock 的辅助容器,不对外暴露端口 |
---
## 七、完整部署清单(执行顺序)
| # | 操作 | 位置 |
|---|------|------|
| 1 | `mkdir -p /home/Git/{gitea/data,webhook/scripts,logs}` | 服务器 |
| 2 | 部署 Gitea 容器 | `/home/Git/gitea/docker-compose.yml` |
| 3 | 重载 main-nginxgit.conf 已就绪) | `/opt/ALiYunManager/` |
| 4 | beian-nginx 追加 git 中转 + 重载 | `/opt/beian-docker/nginx.conf` |
| 5 | DNS 添加 `git` A 记录 → `8.136.137.59` | 阿里云控制台 |
| 6 | Gitea Web 安装 + 管理员注册 | `http://git.dxz99wyr.cn` |
| 7 | 生成 Gitea Access Token (read:repository) | Gitea Settings → Applications |
| 8 | 创建各项目仓库 | Gitea Web UI |
| 9 | 填写 `/home/Git/webhook/.env`GITEA_TOKEN + Secrets| 服务器 |
| 10 | 写入 hooks.json + 各部署脚本 | `/home/Git/webhook/` |
| 11 | 构建自定义镜像 + 启动 webhook 容器 | `/home/Git/webhook/` |
| 12 | 每个仓库配置 Webhook | Gitea Web UI |
| 13 | 本地推送测试自动部署 | 开发机 |
---
## 八、故障排查
### Webhook 不触发
```bash
docker logs webhook -f
# Gitea Web UI → Settings → Webhooks → Recent Deliveries 查看投递状态
```
### 部署脚本报错
```bash
# 查看部署日志
tail -f /home/Git/logs/deploy.log
# 进入容器手动测试
docker exec -it webhook sh
cd /opt/webhook/scripts
bash deploy-resume-web.sh
```
### Git clone 认证失败
```bash
# 检查 Token 是否正确
docker exec webhook env | grep GITEA_TOKEN
# 测试容器内能否访问 Gitea
docker exec webhook curl -s http://gitea:3000/api/v1/version
```
### Gitea 无法访问
```bash
docker ps | grep gitea
docker network inspect aliyun-app-network | grep gitea
docker logs gitea -f
```
---
## 九、ICP 备案提醒
`git.dxz99wyr.cn` 页面底部中间必须显示:
`浙ICP备2026030774号-1` 并链接到 `https://beian.miit.gov.cn`
配置方式:Gitea 管理后台 → 自定义 → Footer HTML。