24 KiB
title, author, created, description, tags
| title | author | created | description | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Gitea 完整配置指南(SSH + frp + Caddy) | shenwei | 2026-06-04 | 涵盖 Gitea SSH 配置、frp 转发、Caddy 反代、以及客户端配置的完整指南 |
|
#git #gitea #ssh #frp #caddy #docker
Gitea 完整配置指南(SSH + frp + Caddy)
这是一份综合指南,涵盖 Gitea 的完整配置,包括 SSH 设置、通过 frp 和 Caddy 进行远程访问、以及 Git 客户端配置。
目录
第一部分:Gitea 部署与基础 SSH 配置
1. Docker 部署(推荐标准配置)
基础 Docker Compose 配置
version: "3"
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: always
ports:
- "3000:3000" # Web UI HTTP
- "2222:22" # SSH(宿主机 2222 -> 容器内 22)
volumes:
- ./gitea:/data
environment:
- ROOT_URL=http://localhost:3000
为什么用 2222?
- 宿主机的 22 端口通常已被系统 SSH 占用
- 使用
2222 → 22映射避免冲突 - 容器内 Gitea SSH 服务依然运行在 22,外部通过 2222 访问
2. Gitea SSH 服务启用
检查配置
进入容器检查配置:
docker exec -it gitea /bin/sh
cat /data/gitea/conf/app.ini
确保 [server] 部分包含:
[server]
START_SSH_SERVER = true
SSH_PORT = 22
START_SSH_SERVER = true:启用 SSH 服务SSH_PORT = 22:容器内监听 22 端口(通过 Docker 映射到外部端口)
重启服务
docker compose down
docker compose up -d
3. 基础 SSH 连接测试
测试 SSH 连通性(本地网络)
# 使用指定端口连接
ssh -T git@192.168.3.17 -p 2222
预期输出(成功):
Hi username! You've successfully authenticated with the key named ...
Gitea does not provide shell access.
常见错误与修复
❌ Connection refused
ssh: connect to host ... port 2222: Connection refused
原因: Docker 未正确映射端口
修复: 检查 docker-compose.yml 中是否有 - "2222:22"
❌ Connection closed
Connection closed by 192.168.3.17 port 2222
原因: SSH 服务存在但不是 Gitea 在处理,或 Gitea SSH 未启用
修复:
- 检查
app.ini中START_SSH_SERVER = true - 重启 Docker 容器
❌ Permission denied (publickey)
Permission denied (publickey)
原因: SSH key 未在 Gitea 中添加或未加载
修复:
# 确保公钥已添加到 Gitea
# 在 Gitea Web UI → Settings → SSH Keys 中验证
# 或重新加载 SSH Agent
ssh-add ~/.ssh/id_ed25519
第二部分:远程访问架构(frp + Caddy)
1. 整体架构
实际部署拓扑
┌──────────────────────────────────────────────────────────────────┐
│ Gitea 远程访问架构 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ │
│ │ Browser │──HTTPS──┐ │
│ └─────────┘ │ │
│ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Caddy │───▶│ frps │ VPS1 │
│ │ :80/:443 │ │ :7000 │ 192.227.222.142 │
│ └──────────┘ │ :13001 │ │
│ │ :12222 │ │
│ └────┬─────┘ │
│ │ frp 隧道 │
│ ┌─────────────┐ │ │
│ │ Git Client │──TCP :12222─────────┤ │
│ └─────────────┘ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ frpc │ NAS │
│ │ Gitea │ 192.168.x.x │
│ │ :3000 │ (Web) │
│ │ :2222 │ (SSH) │
│ └──────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
端口分配
| 端点 | 端口 | 说明 |
|---|---|---|
| VPS1 :7000 | frps 控制 | frpc 与 frps 通信 |
| VPS1 :13001 | Gitea HTTP | Caddy 反代目标(不直接对外) |
| VPS1 :12222 | Gitea SSH | Git 客户端直连 |
| VPS1 :443 | Caddy HTTPS | gitea.ishenwei.online 入口 |
| NAS :3000 | Gitea Web | Docker 容器映射端口 |
| NAS :2222 | Gitea SSH | Docker 2222:22 映射 |
核心原则
- HTTP 走 Caddy:浏览器通过 Caddy 反代访问 Gitea Web UI(自动 HTTPS)
- SSH 直接转发:SSH 流量不经过 Caddy(Caddy 是 HTTP 代理,无法处理 SSH TCP 流量)
- 防火墙放行:VPS1 必须放行 7000、13001、12222 三个端口
- 13001 不要直接对外:仅供 Caddy 本机反代用,可用 iptables 限制为 localhost 访问
2. frpc 配置(NAS 端)
部署位置
- 路径:
/opt/frp/frp_0.65.0_linux_amd64/frpc.toml - 运行方式:systemd(详见第五部分管理命令)
frpc.toml 配置(Gitea 相关部分)
# ===== 服务器连接 =====
serverAddr = "192.227.222.142" # VPS1
serverPort = 7000
auth.method = "token"
auth.token = "Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs"
# ===== 日志 =====
log.level = "info"
log.maxDays = 3
# ===== 管理界面(可选)=====
webServer.addr = "127.0.0.1"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "admin"
# ===== Gitea Web(给 Caddy 反代用)=====
[[proxies]]
name = "gitea-web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3000
remotePort = 13001
# ===== Gitea SSH(直接暴露给 Git 客户端)=====
[[proxies]]
name = "gitea-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 2222
remotePort = 12222
配置说明:
remotePort = 13001:Caddy 在 VPS1 上反代此端口remotePort = 12222:Git 客户端通过gitea.ishenwei.online:12222连接
3. frps 配置(VPS1 端)
基本信息
| 配置项 | 值 |
|---|---|
| 服务器 IP | 192.227.222.142 |
| 部署路径 | /opt/frp/frp_0.65.0_linux_amd64/ |
| 配置文件 | frps.toml |
| 运行方式 | systemd |
| 管理界面 | http://127.0.0.1:7500 (admin/admin) |
frps.toml 配置
# ===== 监听配置 =====
bindAddr = "0.0.0.0"
bindPort = 7000
# ===== 认证(必须与所有 frpc 一致)=====
auth.method = "token"
auth.token = "Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs"
# ===== 日志 =====
log.to = "/var/log/frps.log"
log.level = "info"
log.maxDays = 7
# ===== 管理 Dashboard =====
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"
# ===== 安全限制(可选但推荐)=====
# 限制 frpc 可以使用的端口范围
allowPorts = [
{ start = 10000, end = 65535 }
]
# 单个客户端最大代理数
maxPoolCount = 50
# 心跳超时(秒)
transport.heartbeatTimeout = 90
frps systemd 服务
创建 /etc/systemd/system/frps.service:
[Unit]
Description=frp server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/opt/frp/frp_0.65.0_linux_amd64/frps -c /opt/frp/frp_0.65.0_linux_amd64/frps.toml
Restart=on-failure
RestartSec=10
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
启用并启动:
systemctl daemon-reload
systemctl enable frps
systemctl start frps
systemctl status frps
# 查看日志
journalctl -u frps -f
tail -f /var/log/frps.log
VPS1 防火墙配置
# UFW(推荐)
ufw allow 7000/tcp # frp 控制通道
ufw allow 12222/tcp # Gitea SSH(对外)
ufw allow 80/tcp # Caddy HTTP(自动跳转 HTTPS)
ufw allow 443/tcp # Caddy HTTPS
# 13001 仅本机访问,无需对外放行
# 如果需要明确禁止,可以:
ufw deny 13001/tcp
# 验证规则
ufw status numbered
重要: 如果 VPS 提供商有云控制台安全组(如 AWS Security Group、阿里云安全组),必须同时放行,缺一不可。
4. Caddy 反代配置(VPS1 端)
Caddy 部署在与 frps 相同的 VPS1 上,自动申请并续期 Let's Encrypt 证书。
安装 Caddy(Debian/Ubuntu)
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Caddy 安装后自动注册为 systemd 服务,配置文件位于 /etc/caddy/Caddyfile。
Caddyfile 配置
编辑 /etc/caddy/Caddyfile:
# ============================================
# Gitea Web UI
# ============================================
gitea.ishenwei.online {
# 反代到本机 frps 监听的 Gitea HTTP 端口
reverse_proxy 127.0.0.1:13001 {
# 传递真实客户端 IP 给 Gitea
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
# 日志(可选)
log {
output file /var/log/caddy/gitea.log {
roll_size 50mb
roll_keep 5
}
format json
}
# 大文件支持(Git push/LFS 必需)
request_body {
max_size 5GB
}
}
# ============================================
# 其他服务示例(同样模式)
# ============================================
# n8n.ishenwei.online {
# reverse_proxy 127.0.0.1:15679
# }
#
# vaultwarden.ishenwei.online {
# reverse_proxy 127.0.0.1:15151
# }
关键要点
- 反代目标是
127.0.0.1:13001:frps 把 NAS 上 Gitea 的 :3000 转发到 VPS1 的 :13001 - 不要将 SSH 端口(12222)配进 Caddy:Caddy 是 HTTP/HTTPS 反向代理,无法承载 SSH TCP 协议
- 自动 HTTPS:Caddy 会自动通过 Let's Encrypt 申请证书并自动续期(前提是域名 A 记录已正确指向 VPS1,且 80/443 端口已放行)
- 大文件支持:
request_body max_size必须设置足够大,否则git push大仓库会失败
DNS 配置
在你的 DNS 服务商(Cloudflare/阿里云等)添加 A 记录:
gitea.ishenwei.online A 192.227.222.142
如果使用 Cloudflare,必须关闭代理(小灰云) 用 DNS only 模式,否则 Caddy 申请证书会失败,且 SSH 不工作。
Caddy 管理命令
# 验证 Caddyfile 语法
caddy validate --config /etc/caddy/Caddyfile
# 优雅重载(修改配置后用这个,不会断连)
sudo systemctl reload caddy
# 查看状态
sudo systemctl status caddy
# 查看日志
sudo journalctl -u caddy -f
tail -f /var/log/caddy/gitea.log
验证 HTTPS
# 测试证书
curl -I https://gitea.ishenwei.online
# 预期返回:
# HTTP/2 200
# server: Caddy
# ...
5. Gitea app.ini 配置
SSH 相关配置
编辑 /data/gitea/conf/app.ini:
[server]
ROOT_URL = https://gitea.ishenwei.online/
SSH_DOMAIN = gitea.ishenwei.online
SSH_PORT = 12222
START_SSH_SERVER = true
配置说明:
SSH_DOMAIN = gitea.ishenwei.online:Web 界面显示的 SSH 地址SSH_PORT = 12222:对外暴露的 SSH 端口(影响 Web 上显示的 Clone 地址)ROOT_URL:Web UI 根路径,通常指向域名
重启应用
docker compose down
docker compose up -d
第三部分:客户端配置
1. SSH Key 生成
生成密钥对
ssh-keygen -t ed25519 -C "your-email@example.com"
为什么用 ed25519?
- 更安全、密钥更短
- 现代标准推荐
默认路径:
~/.ssh/id_ed25519 # 私钥
~/.ssh/id_ed25519.pub # 公钥
启动 SSH Agent
# Linux/macOS
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Windows (PowerShell)
# 通常自动运行,无需手动启动
ssh-add $env:USERPROFILE\.ssh\id_ed25519
2. 添加公钥到 Gitea
在 Gitea Web UI 中添加
- 登录 Gitea Web UI
- 点击右上角头像 → Settings
- 选择 SSH Keys
- 点击 Add Key
复制公钥内容
cat ~/.ssh/id_ed25519.pub
将输出内容完整复制到 Gitea,包括前缀 ssh-ed25519 AAA...
3. SSH Config 配置(推荐)
简化 SSH 连接
编辑 ~/.ssh/config:
# 本地网络 - Gitea(Docker)
Host gitea-local
HostName 192.168.3.17
User git
Port 2222
IdentityFile ~/.ssh/id_ed25519
# 远程 - Gitea(通过 frp)
Host gitea.ishenwei.online
HostName gitea.ishenwei.online
User git
Port 12222
IdentityFile ~/.ssh/id_ed25519
使用简化命令
配置后,可以用更简洁的命令:
# 本地网络
ssh -T gitea-local
# 远程(通过 frp)
ssh -T gitea.yourdomain.com
4. Git 仓库配置
方式一:Clone 时使用 SSH
# 本地
git clone ssh://git@192.168.3.17:2222/username/repo.git
# 远程(通过 frp)
git clone ssh://git@gitea.ishenwei.online:12222/username/repo.git
# 使用 SSH Config 别名
git clone ssh://gitea-local/username/repo.git
git clone ssh://gitea.ishenwei.online/username/repo.git
方式二:修改已有仓库的 Remote URL
# 查看当前 remote
git remote -v
# 修改为 SSH
git remote set-url origin ssh://git@192.168.3.17:2222/username/repo.git
# 远程版本
git remote set-url origin ssh://git@gitea.ishenwei.online:12222/username/repo.git
# 验证修改
git remote -v
验证连接
git pull
5. VS Code / IDE 集成
在配置好 SSH 和 Git Remote 后:
- VS Code:无需额外配置,自动使用 Git + SSH
- JetBrains IDE:自动识别 SSH Config
- 其他 IDE:通常也会自动识别系统 SSH 配置
优势:
- 无需输入密码
- 不受代理干扰
- Clone / Pull 不会卡住
第四部分:故障排除
1. SSH 连接测试
测试不同场景
# 本地网络测试
ssh -vT git@192.168.3.17 -p 2222
# 远程(通过 frp)测试
ssh -vT git@gitea.ishenwei.online -p 12222
# 使用 SSH Config 别名测试
ssh -vT gitea-local
ssh -vT gitea.ishenwei.online
详细调试信息
# -v 显示调试信息
# -vv 显示更详细信息
# -vvv 显示最详细信息
ssh -vvv git@gitea.ishenwei.online -p 12222
2. 常见问题
问题:Permission denied (publickey)
可能原因:
- SSH key 未加载
- 公钥未在 Gitea 中添加
- 使用了错误的用户名(应该是
git,不是账户名)
检修步骤:
# 1. 查看已加载的 key
ssh-add -l
# 2. 如果列表为空,重新加载
ssh-add ~/.ssh/id_ed25519
# 3. 验证 Gitea Web UI 中是否已添加该公钥
# 4. 确认使用 git 用户
ssh -vT git@gitea.ishenwei.online -p 12222
问题:Connection refused
可能原因:
- Gitea 未运行
- SSH 端口未正确映射
- 防火墙未放行端口
检修步骤:
# 1. 检查 Docker 容器状态
docker ps | grep gitea
# 2. 检查端口映射
docker port gitea
# 3. 检查防火墙(本地)
ss -tlnp | grep 2222
# 4. 检查防火墙(远程 VPS)
ufw status
问题:Connection closed by remote
可能原因:
- SSH 服务异常关闭
- 连接超时
- 网络问题
检修步骤:
# 1. 重启 Gitea 容器
docker restart gitea
# 2. 检查容器日志
docker logs -f gitea
# 3. 测试基本连通性
ping gitea.ishenwei.online
问题:Bad owner or permissions on ~/.ssh/config
原因: SSH config 文件权限不正确
修复:
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
3. 防火墙排查
本地网络(NAS/局域网)
# Windows - 测试端口连通性
Test-NetConnection -ComputerName 192.168.3.17 -Port 2222
# macOS/Linux - 测试端口连通性
nc -zv 192.168.3.17 2222
# 或使用 telnet
telnet 192.168.3.17 2222
远程 VPS
# 测试 frp 通信端口
telnet your-vps.com 7000
# 测试 Gitea HTTP 端口(给 Caddy)
telnet your-vps.com 13000
# 测试 Gitea SSH 端口
telnet your-vps.com 12222
群晖 NAS 防火墙
NAS 无 UFW,防火墙配置在:
- DSM → 控制面板 → 安全性 → 防火墙
- 需手动添加规则放行 frp 和 SSH 端口
4. frp 故障排除
检查 frp 日志
# 查看 frpc 日志
journalctl -u frpc -f
# 或直接运行 frpc 查看输出
./frpc -c frpc.toml
验证 frps 连接
# 在 VPS 上检查已连接的隧道
netstat -tlnp | grep 13000
netstat -tlnp | grep 12222
# 或使用 frp 的状态查询(如果启用了 admin 功能)
curl http://localhost:7400/api/serverinfo
第五部分:最佳实践
1. 安全建议
SSH Key 管理
- ✅ 使用 ed25519 算法
- ✅ 为私钥设置强密码
- ✅ 定期轮换密钥
- ✅ 不同用途使用不同密钥(添加
-C "标签"区分)
防火墙配置
- ✅ 只放行必要的端口
- ✅ 使用 VPN 或跳板机访问敏感服务
- ✅ 监控 SSH 连接日志
- ✅ 禁用密码认证,仅允许密钥认证
Gitea 配置
- ✅ 设置强密码
- ✅ 启用 2FA(双因素认证)
- ✅ 定期备份仓库
- ✅ 监控访问日志
2. 性能优化
SSH 连接复用
编辑 ~/.ssh/config 添加连接复用:
Host *
ControlMaster auto
ControlPath ~/.ssh/control-%C
ControlPersist 600
ServerAliveInterval 60
ServerAliveCountMax 3
Git 相关优化
# 配置 SSH 超时
git config --global core.sshCommand "ssh -o ConnectTimeout=10"
# 配置代理(如需要)
git config --global https.proxy [proxy-url]
3. 多环境管理
SSH Config 示例
# 本地 Gitea
Host gitea-local
HostName 192.168.3.17
User git
Port 2222
IdentityFile ~/.ssh/id_ed25519_gitea
# 远程 Gitea(通过 frp)
Host gitea-remote
HostName gitea.ishenwei.online
User git
Port 12222
IdentityFile ~/.ssh/id_ed25519_gitea
# GitHub
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
# GitLab
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_gitlab
Git 配置管理
# 查看当前配置
git config --list
# 全局配置
git config --global user.name "Your Name"
git config --global user.email "your-email@example.com"
# 项目级配置(在仓库目录中)
git config --local user.email "project-specific@example.com"
4. 监控与维护
定期检查
# 检查 SSH key 过期情况
ssh-keygen -l -f ~/.ssh/id_ed25519.pub
# 查看 Gitea 日志
docker logs -f gitea
# 查看 frp 连接状态
journalctl -u frpc -f
日志轮转
确保日志不会占满磁盘:
# Docker 日志轮转配置(docker-compose.yml)
services:
gitea:
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
总结
快速检查清单
部署完成后,按以下顺序验证:
NAS 端(Gitea + frpc):
- Docker 容器运行:
docker ps | grep gitea - SSH 服务启用:
docker exec gitea cat /data/gitea/conf/app.ini | grep SSH - 本地 SSH 测试:
ssh -T git@<NAS-IP> -p 2222 - frpc 服务运行:
systemctl status frpc - frpc 日志正常:
journalctl -u frpc -f显示[gitea-web] start proxy success和[gitea-ssh] start proxy success
VPS1 端(frps + Caddy):
- frps 服务运行:
systemctl status frps - frps Dashboard 可访问:
http://192.227.222.142:7500(admin/admin) - 端口监听:
ss -tlnp | grep -E '7000|12222|13001' - 防火墙放行:
ufw status包含 7000/12222/80/443 - Caddy 运行:
systemctl status caddy - DNS 解析正确:
dig gitea.ishenwei.online +short→192.227.222.142
客户端:
- 公钥已添加:Gitea Web UI → Settings → SSH Keys
- HTTPS 访问:浏览器打开
https://gitea.ishenwei.online(绿锁) - SSH 连接:
ssh -T git@gitea.ishenwei.online -p 12222返回Hi <user>! - Git Clone:
git clone ssh://git@gitea.ishenwei.online:12222/<user>/<repo>.git
完整端到端部署流程速查
┌─────────────────────────────────────────────────────────────┐
│ 1. NAS: 启动 Gitea Docker (端口 3000, 2222:22) │
│ 2. NAS: 配置 app.ini (SSH_DOMAIN, SSH_PORT=12222) │
│ 3. NAS: 部署 frpc.toml (gitea-web:13001, gitea-ssh:12222) │
│ 4. NAS: systemctl restart frpc │
│ ↓ │
│ 5. VPS1: 部署 frps.toml + frps.service │
│ 6. VPS1: ufw allow 7000/12222/80/443 │
│ 7. VPS1: systemctl enable --now frps │
│ 8. VPS1: 编辑 /etc/caddy/Caddyfile (gitea.ishenwei.online) │
│ 9. VPS1: systemctl reload caddy │
│ ↓ │
│ 10. DNS: 添加 A 记录 gitea → 192.227.222.142 │
│ ↓ │
│ 11. 客户端: 生成 SSH key + 上传公钥到 Gitea │
│ 12. 客户端: 配置 ~/.ssh/config │
│ 13. 客户端: git clone ssh://git@gitea.ishenwei.online:12222 │
└─────────────────────────────────────────────────────────────┘
一句话结论
Git 的本质:
user.name/email→ 标识身份- SSH Key → 认证身份
推荐方案:
Gitea + Docker + SSH + frp + Caddy = 稳定可靠的远程 Git 服务
记录时间: 2026-06-04
最后更新: 2026-06-04