diff --git a/.env.example b/.env.example index d814103..2fc8698 100644 --- a/.env.example +++ b/.env.example @@ -18,6 +18,12 @@ GITEA__lfs__PATH=/data/git/lfs # 禁用公开注册(仅管理员可创建账号) GITEA__service__DISABLE_REGISTRATION=true +# PostgreSQL 配置 +POSTGRES_VERSION=16-alpine +POSTGRES_DB=gitea +POSTGRES_USER=gitea +POSTGRES_PASSWORD=changeme + # 域名配置 DOMAIN=git.example.com diff --git a/README.md b/README.md index faed507..fb3cf67 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,16 @@ ``` Client → Gitea (HTTP_PORT, e.g. 3000) - Gitea SSH (22 → 宿主机 SSH_PORT) + ├─ PostgreSQL (5432, Docker 内部网络) + └─ Gitea SSH (22 → 宿主机 SSH_PORT) ``` ### Caddy 模式(--profile caddy) ``` Client → Caddy (80/443, HTTP + HTTPS) → Gitea (3000, Docker 内部网络) - Gitea SSH (22 → 宿主机 SSH_PORT) + ├─ PostgreSQL (5432, Docker 内部网络) + └─ Gitea SSH (22 → 宿主机 SSH_PORT) ``` ## 快速开始 @@ -39,6 +41,7 @@ cp .env.example .env ```env DOMAIN=git.example.com # 你的域名 SSH_PORT=2222 # SSH 端口(宿主机端口,容器内仍为 22) +POSTGRES_PASSWORD=changeme # PostgreSQL 密码(务必修改) ``` #### HTTP 模式 @@ -56,7 +59,7 @@ ROOT_URL=https://git.example.com/ ### 2. 启动服务 ```bash -# HTTP 模式(仅 Gitea,无 Caddy) +# HTTP 模式(仅 Gitea + PostgreSQL,无 Caddy) docker compose up -d # Caddy 模式(HTTP + HTTPS,Caddy 反向代理) @@ -70,7 +73,7 @@ docker compose --profile caddy up -d 首次访问会进入安装向导: 1. 设置管理员账户 -2. 数据库已默认使用 SQLite +2. 数据库已通过环境变量配置为 PostgreSQL,无需手动设置 ## 访问方式 @@ -105,21 +108,84 @@ git push ## 数据备份 -备份 `data/` 目录: +### 备份 PostgreSQL 数据库 ```bash -# 备份 -tar -czvf gitea-backup-$(date +%Y%m%d).tar.gz data/ +docker exec postgres pg_dump -U gitea gitea > gitea-db-$(date +%Y%m%d).sql +``` -# 恢复 -tar -xzvf gitea-backup-20260320.tar.gz +### 备份全部数据 + +```bash +# 备份数据目录 + 数据库导出 +tar -czvf gitea-data-$(date +%Y%m%d).tar.gz data/ +docker exec postgres pg_dump -U gitea gitea > gitea-db-$(date +%Y%m%d).sql +``` + +### 恢复数据库 + +```bash +cat gitea-db-20260327.sql | docker exec -i postgres psql -U gitea gitea ``` 重要文件: -- `data/gitea/gitea.db` - 用户和配置数据 +- `data/postgres/` - PostgreSQL 数据 - `data/git/repositories/` - 仓库数据 - `data/git/lfs/` - LFS 文件 +- `data/gitea/conf/app.ini` - Gitea 配置 + +## SQLite 迁移到 PostgreSQL + +如果之前使用 SQLite,需执行以下步骤迁移到 PostgreSQL: + +### 1. 停止 Gitea(保留 PostgreSQL 运行) + +```bash +docker compose stop gitea +``` + +### 2. 备份现有数据 + +```bash +cp data/gitea/gitea.db data/gitea/gitea.db.bak +``` + +### 3. 修改 app.ini 数据库配置 + +编辑 `data/gitea/conf/app.ini`,将 `[database]` 段改为: + +```ini +[database] +DB_TYPE = postgres +HOST = postgres:5432 +NAME = gitea +USER = gitea +PASSWD = <你的 POSTGRES_PASSWORD> +SCHEMA = +SSL_MODE = disable +PATH = +``` + +> 注意:如果 docker-compose.yml 中已通过 `GITEA__database__*` 环境变量配置,则 app.ini 中的值会被覆盖,可不修改 app.ini。 + +### 4. 执行数据迁移 + +```bash +docker compose exec gitea gitea migrate +``` + +### 5. 重启 Gitea + +```bash +docker compose start gitea +``` + +### 6. 验证 + +访问 Web 界面,确认用户、仓库数据完整。 + +> 迁移成功后 `data/gitea/gitea.db` 可以保留作为备份,不会影响 PostgreSQL 运行。 ## 常用命令 @@ -136,6 +202,9 @@ docker compose down # 查看日志 docker compose logs -f +# 查看 PostgreSQL 日志 +docker compose logs -f postgres + # 查看 Caddy 日志 docker compose logs -f caddy @@ -145,4 +214,7 @@ docker compose restart # 更新版本 # 修改 .env 中的 GITEA_VERSION 后 docker compose up -d + +# 连接 PostgreSQL +docker exec -it postgres psql -U gitea ``` diff --git a/docker-compose.yml b/docker-compose.yml index 5b611f7..4498803 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,6 +4,11 @@ services: container_name: gitea environment: - TZ=${TZ} + - GITEA__database__DB_TYPE=postgres + - GITEA__database__HOST=postgres:5432 + - GITEA__database__NAME=${POSTGRES_DB} + - GITEA__database__USER=${POSTGRES_USER} + - GITEA__database__PASSWD=${POSTGRES_PASSWORD} - GITEA__lfs__START_SERVER=${GITEA__lfs__START_SERVER} - GITEA__lfs__PATH=${GITEA__lfs__PATH} - GITEA__service__DISABLE_REGISTRATION=${GITEA__service__DISABLE_REGISTRATION} @@ -17,6 +22,25 @@ services: ports: - "${HTTP_PORT}:3000" - "${SSH_PORT}:22" + depends_on: + postgres: + condition: service_healthy + + postgres: + image: postgres:${POSTGRES_VERSION} + container_name: postgres + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + restart: always + volumes: + - ./data/postgres:/var/lib/postgresql/data + healthcheck: + test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER}"] + interval: 5s + timeout: 3s + retries: 5 caddy: image: caddy:2 diff --git a/docs/superpowers/plans/2026-03-20-gitea-lan-deployment.md b/docs/superpowers/plans/2026-03-20-gitea-lan-deployment.md index 9202a7c..5be679c 100644 --- a/docs/superpowers/plans/2026-03-20-gitea-lan-deployment.md +++ b/docs/superpowers/plans/2026-03-20-gitea-lan-deployment.md @@ -2,11 +2,11 @@ > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. -**Goal:** 使用 Docker Compose 部署 Gitea Git 服务,支持 HTTP/SSH 访问和 Git LFS +**Goal:** 使用 Docker Compose 部署 Gitea Git 服务,支持 HTTP/SSH 访问、Git LFS 和 PostgreSQL 数据库 -**Architecture:** 单容器部署,SQLite 数据库,宿主机目录挂载持久化数据,通过 .env 文件配置端口和环境变量 +**Architecture:** Gitea + PostgreSQL 双容器部署,宿主机目录挂载持久化数据,通过 .env 文件配置端口和环境变量,Caddy 可选反向代理 -**Tech Stack:** Docker Compose, Gitea 1.25.4, SQLite +**Tech Stack:** Docker Compose, Gitea 1.25.4, PostgreSQL 16 (alpine), Caddy 2 (可选) --- @@ -14,14 +14,16 @@ | 文件 | 职责 | |-----|------| -| `docker-compose.yml` | 容器编排配置:镜像、端口、卷、环境变量 | -| `.env` | 可配置参数:版本、端口、时区、LFS 配置 | +| `docker-compose.yml` | 容器编排:Gitea + PostgreSQL + Caddy(可选) | +| `.env` | 可配置参数:版本、端口、时区、数据库、域名 | +| `.env.example` | 环境变量示例(无敏感信息) | +| `Caddyfile` | Caddy 反向代理配置 | | `.gitignore` | 忽略数据目录和环境变量文件 | -| `README.md` | 使用说明:启动、访问、备份 | +| `README.md` | 使用说明:启动、访问、备份、迁移 | --- -## Chunk 1: 基础配置文件 +## Chunk 1: 核心配置文件 ### Task 1: 创建 .env 环境变量文件 @@ -41,9 +43,25 @@ SSH_PORT=2222 # 时区 TZ=Asia/Shanghai +# SSH 端口配置(告知 Gitea 对外 SSH 端口) +GITEA__server__SSH_PORT=${SSH_PORT} + # Git LFS 配置 GITEA__lfs__START_SERVER=true GITEA__lfs__PATH=/data/git/lfs + +# 禁用公开注册 +GITEA__service__DISABLE_REGISTRATION=true + +# PostgreSQL 配置 +POSTGRES_VERSION=16-alpine +POSTGRES_DB=gitea +POSTGRES_USER=gitea +POSTGRES_PASSWORD=changeme + +# 域名配置 +DOMAIN=git.example.com +ROOT_URL=http://${DOMAIN}:${HTTP_PORT}/ ``` - [ ] **Step 2: 验证文件创建成功** @@ -60,28 +78,11 @@ Expected: 显示上述内容 - [ ] **Step 1: 创建 docker-compose.yml 文件** -```yaml -services: - gitea: - image: gitea/gitea:${GITEA_VERSION} - container_name: gitea - environment: - - TZ=${TZ} - - GITEA__lfs__START_SERVER=${GITEA__lfs__START_SERVER} - - GITEA__lfs__PATH=${GITEA__lfs__PATH} - restart: always - volumes: - - ./data:/data - - /etc/timezone:/etc/timezone:ro - - /etc/localtime:/etc/localtime:ro - ports: - - "${HTTP_PORT}:3000" - - "${SSH_PORT}:22" - -networks: - default: - driver: bridge -``` +关键配置: +- Gitea 服务:通过 `GITEA__database__*` 环境变量连接 PostgreSQL +- PostgreSQL 服务:`postgres:16-alpine`,健康检查 `pg_isready` +- Gitea `depends_on` PostgreSQL(健康检查通过后才启动) +- Caddy 服务:`profiles: [caddy]`,可选启用 - [ ] **Step 2: 验证 Docker Compose 配置语法** @@ -104,154 +105,44 @@ data/ # 环境变量(可能包含敏感信息) .env +# Caddy 数据 +caddy_data/ +caddy_config/ + # macOS .DS_Store ``` -- [ ] **Step 2: 验证文件创建成功** - -Run: `cat .gitignore` -Expected: 显示上述内容 - --- -### Task 4: 创建 README.md 使用说明 - -**Files:** -- Create: `README.md` - -- [ ] **Step 1: 创建 README.md 文件** - -```markdown -# Gitea 局域网部署 - -使用 Docker Compose 部署的 Gitea Git 服务。 - -## 快速开始 - -### 1. 配置环境变量 - -复制并编辑 `.env` 文件: - -```bash -cp .env.example .env -``` - -修改端口等配置: - -```env -HTTP_PORT=3000 # Web 界面端口 -SSH_PORT=2222 # SSH 端口 -``` - -### 2. 启动服务 - -```bash -docker compose up -d -``` - -### 3. 初始配置 - -首次访问 `http://<服务器IP>:3000` 会进入安装向导: - -1. 设置管理员账户 -2. 配置服务器域名(可选) -3. 数据库已默认使用 SQLite - -## 访问方式 - -| 方式 | 地址 | -|-----|------| -| Web 界面 | `http://:3000` | -| HTTP 克隆 | `git clone http://:3000/<用户>/<仓库>.git` | -| SSH 克隆 | `git clone ssh://git@:2222/<用户>/<仓库>.git` | - -## Git LFS - -已启用 Git LFS 支持,使用方法: - -```bash -git lfs install -git lfs track "*.psd" -git add .gitattributes -git commit -m "Track PSD files with LFS" -git push -``` - -## 数据备份 - -备份 `data/` 目录: - -```bash -# 备份 -tar -czvf gitea-backup-$(date +%Y%m%d).tar.gz data/ - -# 恢复 -tar -xzvf gitea-backup-20260320.tar.gz -``` - -重要文件: -- `data/gitea/gitea.db` - 用户和配置数据 -- `data/git/repositories/` - 仓库数据 -- `data/git/lfs/` - LFS 文件 - -## 常用命令 - -```bash -# 启动 -docker compose up -d - -# 停止 -docker compose down - -# 查看日志 -docker compose logs -f - -# 重启 -docker compose restart - -# 更新版本 -# 修改 .env 中的 GITEA_VERSION 后 -docker compose up -d -``` -``` - -- [ ] **Step 2: 验证文件创建成功** - -Run: `cat README.md` -Expected: 显示上述内容 - ---- - -## Chunk 2: 创建示例配置和验证 - -### Task 5: 创建 .env.example 示例文件 +### Task 4: 创建 .env.example **Files:** - Create: `.env.example` - [ ] **Step 1: 创建 .env.example 文件** -```env -# Gitea 版本 -GITEA_VERSION=1.25.4 +与 `.env` 结构相同,但密码使用占位值 `changeme`。 -# 端口配置 -HTTP_PORT=3000 -SSH_PORT=2222 +--- -# 时区 -TZ=Asia/Shanghai +## Chunk 2: 文档和验证 -# Git LFS 配置 -GITEA__lfs__START_SERVER=true -GITEA__lfs__PATH=/data/git/lfs -``` +### Task 5: 创建 README.md 使用说明 -- [ ] **Step 2: 验证文件创建成功** +**Files:** +- Create: `README.md` -Run: `cat .env.example` -Expected: 显示上述内容 +- [ ] **Step 1: 创建 README.md 文件** + +内容包含: +- 架构说明(HTTP 模式 / Caddy 模式) +- 快速开始(配置 → 启动 → 初始设置) +- 访问方式 +- Git LFS 使用 +- 数据备份(PostgreSQL pg_dump + 数据目录) +- SQLite 迁移到 PostgreSQL 步骤 +- 常用命令 --- @@ -265,12 +156,12 @@ Expected: 显示 `docker-compose.yml`, `.env`, `.env.example`, `.gitignore`, `RE - [ ] **Step 2: 验证 Docker Compose 配置** Run: `docker compose config` -Expected: 无错误输出,显示完整配置 +Expected: 无错误输出,显示完整配置(包含 gitea、postgres、caddy 服务) - [ ] **Step 3: (可选)启动服务测试** Run: `docker compose up -d` -Expected: 容器启动成功 +Expected: postgres 和 gitea 容器均启动成功 --- @@ -278,5 +169,6 @@ Expected: 容器启动成功 - [ ] 所有配置文件已创建 - [ ] `docker compose config` 验证通过 -- [ ] 服务可以正常启动 +- [ ] 服务可以正常启动(Gitea + PostgreSQL) - [ ] 可以通过 Web 界面访问安装向导 +- [ ] 数据库连接正常(安装向导中数据库类型显示为 PostgreSQL) diff --git a/docs/superpowers/specs/2026-03-20-gitea-lan-deployment-design.md b/docs/superpowers/specs/2026-03-20-gitea-lan-deployment-design.md index fe9bbbd..644509b 100644 --- a/docs/superpowers/specs/2026-03-20-gitea-lan-deployment-design.md +++ b/docs/superpowers/specs/2026-03-20-gitea-lan-deployment-design.md @@ -2,13 +2,13 @@ ## 概述 -使用 Docker Compose 在局域网中部署 Gitea Git 服务,支持 HTTP 和 SSH 访问,启用 Git LFS 支持。 +使用 Docker Compose 在局域网中部署 Gitea Git 服务,支持 HTTP 和 SSH 访问,启用 Git LFS 支持。使用 PostgreSQL 替代 SQLite 以获得更好的并发性能(尤其是 LFS 大文件上传)。 ## 需求 - 仅局域网使用 - Docker Compose 容器化部署 -- 数据库:SQLite(简单可靠) +- 数据库:PostgreSQL(解决 SQLite 文件锁导致的 LFS 上传瓶颈) - 访问方式:HTTP + SSH - 端口配置:通过 `.env` 文件灵活配置 - 数据存储:宿主机目录挂载 @@ -18,10 +18,15 @@ ## 技术选型 | 组件 | 选择 | 说明 | -|-----|------|-----| +|-----|------|------| | Gitea 版本 | 1.25.4 | 当前最新稳定版 | -| 数据库 | SQLite | 零配置,适合小规模使用 | +| 数据库 | PostgreSQL 16 | 并发写入性能好,解决 SQLite 文件锁瓶颈 | | 容器镜像 | gitea/gitea:1.25.4 | 官方镜像,固定版本 | +| 数据库镜像 | postgres:16-alpine | 轻量 PostgreSQL,~80MB | + +### 为什么从 SQLite 迁移到 PostgreSQL + +SQLite 使用文件级写锁,在 LFS 大文件上传时,元数据写入被串行化,导致上传速度被限制在约 1.7 MB/s。PostgreSQL 支持并发写入,消除了这个瓶颈。 ## 目录结构 @@ -29,14 +34,18 @@ gitea/ ├── docker-compose.yml # 容器编排配置 ├── .env # 环境变量(端口等配置) +├── .env.example # 环境变量示例 ├── .gitignore # 忽略数据目录和敏感文件 +├── Caddyfile # Caddy 反向代理配置(可选) +├── README.md # 使用说明 └── data/ # Gitea 数据(挂载目录) ├── git/ # Git 仓库数据 │ ├── repositories/ # 仓库存储 │ └── lfs/ # LFS 文件存储 - ├── gitea/ # Gitea 配置和数据库 - │ ├── gitea.db # SQLite 数据库(用户数据) + ├── gitea/ # Gitea 配置 + │ ├── gitea.db # SQLite 数据库(迁移后保留作备份) │ └── conf/app.ini # 配置文件 + ├── postgres/ # PostgreSQL 数据 └── ssh/ # SSH 密钥 ``` @@ -55,31 +64,73 @@ SSH_PORT=2222 # 时区 TZ=Asia/Shanghai +# PostgreSQL 配置 +POSTGRES_VERSION=16-alpine +POSTGRES_DB=gitea +POSTGRES_USER=gitea +POSTGRES_PASSWORD=changeme + # Git LFS 配置 GITEA__lfs__START_SERVER=true GITEA__lfs__PATH=/data/git/lfs + +# 禁用公开注册 +GITEA__service__DISABLE_REGISTRATION=true + +# 域名配置 +DOMAIN=git.example.com +ROOT_URL=http://${DOMAIN}:${HTTP_PORT}/ ``` ### docker-compose.yml +#### Gitea 服务 + - 镜像:`gitea/gitea:${GITEA_VERSION}` - 端口映射: - `${HTTP_PORT}:3000` - Web 界面和 HTTP Git 操作 - `${SSH_PORT}:22` - SSH Git 操作 - 数据卷挂载:`./data:/data` -- 环境变量:从 `.env` 文件读取 +- 环境变量:从 `.env` 文件读取(数据库连接通过 `GITEA__database__*` 环境变量覆盖 app.ini) +- 依赖:`postgres`(健康检查通过后启动) - 重启策略:`always` -- 网络:bridge 模式 + +#### PostgreSQL 服务 + +- 镜像:`postgres:${POSTGRES_VERSION}`(默认 16-alpine) +- 环境变量:`POSTGRES_DB`、`POSTGRES_USER`、`POSTGRES_PASSWORD` +- 数据卷挂载:`./data/postgres:/var/lib/postgresql/data` +- 健康检查:`pg_isready`,5 秒间隔,3 秒超时,5 次重试 +- 重启策略:`always` + +#### Caddy 服务(可选,--profile caddy) + +- 镜像:`caddy:2` +- 端口:80、443 +- 配置:`./Caddyfile` 只读挂载 +- 依赖:`gitea` ### .gitignore -忽略 `data/` 目录和 `.env` 文件(避免敏感信息提交) +忽略 `data/` 目录、`.env` 文件、Caddy 数据目录(避免敏感信息提交) + +## 数据库配置说明 + +数据库配置通过 docker-compose.yml 中的 `GITEA__database__*` 环境变量设置,优先级高于 `app.ini`: + +| 环境变量 | 值 | 说明 | +|---------|---|------| +| `GITEA__database__DB_TYPE` | `postgres` | 数据库类型 | +| `GITEA__database__HOST` | `postgres:5432` | Docker 内部网络连接 | +| `GITEA__database__NAME` | `${POSTGRES_DB}` | 数据库名 | +| `GITEA__database__USER` | `${POSTGRES_USER}` | 用户名 | +| `GITEA__database__PASSWD` | `${POSTGRES_PASSWORD}` | 密码 | ## 数据存储说明 | 数据类型 | 容器内路径 | 宿主机路径 | |---------|-----------|-----------| -| 用户账户、权限 | /data/gitea/gitea.db | ./data/gitea/gitea.db | +| PostgreSQL 数据 | /var/lib/postgresql/data | ./data/postgres/ | | Git 仓库 | /data/git/repositories/ | ./data/git/repositories/ | | SSH 密钥 | /data/git/.ssh/ | ./data/git/.ssh/ | | LFS 文件 | /data/git/lfs/ | ./data/git/lfs/ | @@ -103,20 +154,25 @@ docker compose up -d 首次访问 Web 界面会进入安装向导,需要: 1. 设置管理员账户 -2. 配置服务器域名等基本信息 -3. 数据库已使用 SQLite,无需额外配置 +2. 数据库已通过环境变量配置为 PostgreSQL,无需手动设置 ### 备份 -备份 `./data/` 目录即可,特别是: -- `./data/gitea/gitea.db` - 用户和配置数据 -- `./data/git/repositories/` - 仓库数据 -- `./data/git/lfs/` - LFS 文件 +```bash +# 导出数据库 +docker exec postgres pg_dump -U gitea gitea > gitea-db-$(date +%Y%m%d).sql + +# 备份数据目录 +tar -czvf gitea-data-$(date +%Y%m%d).tar.gz data/ +``` ## 文件清单 -需要创建的文件: -1. `docker-compose.yml` - Docker Compose 配置 -2. `.env` - 环境变量配置 -3. `.gitignore` - Git 忽略规则 -4. `README.md` - 使用说明文档 +| 文件 | 职责 | +|-----|------| +| `docker-compose.yml` | 容器编排:Gitea + PostgreSQL + Caddy | +| `.env` | 环境变量:版本、端口、数据库、域名 | +| `.env.example` | 环境变量示例 | +| `.gitignore` | 忽略数据目录和敏感文件 | +| `Caddyfile` | Caddy 反向代理配置 | +| `README.md` | 使用说明文档 |