Gitea配置与Nginx反向代理
概述
成功部署 Gitea 并使用国内镜像源,配置 Nginx 反向代理使 Gitea 在子路径 /gitea 下可用。
环境
- 操作系统:Ubuntu 22.04.5 LTS
- Docker 版本:29.3.1
- Docker Compose 插件版本:v5.1.1
- Nginx 版本:1.18.0
- 域名:viperekura.xyz(已配置 HTTPS)
配置变量
以下变量可根据您的实际环境调整:
| 变量 | 示例值 | 说明 |
|---|---|---|
DOMAIN |
viperekura.xyz |
您的域名 |
HTTP_PORT |
3000 |
Gitea 容器内 HTTP 端口 |
SSH_PORT |
2222 |
Gitea 容器内 SSH 端口(亦为外部映射端口) |
EXTERNAL_HTTP_PORT |
3000 |
主机 HTTP 映射端口(若与容器内不同) |
EXTERNAL_SSH_PORT |
2222 |
主机 SSH 映射端口(若与容器内不同) |
GITEA_SUBPATH |
/gitea |
Nginx 反向代理的子路径 |
GITEA_VERSION |
1.21 |
Gitea 镜像版本 |
注:本文档后续步骤中使用的值均以上表为例,您可根据需要替换。
步骤概览
1. 使用国内镜像源部署 Gitea
- 修改
docker-compose.yml中的镜像地址为docker.m.daocloud.io/gitea/gitea:1.21,加速拉取。 - 设置环境变量
GITEA__server__DOMAIN=DOMAIN和GITEA__server__ROOT_URL=https://DOMAIN/gitea。 - 启动容器:
docker compose up -d。
2. 配置 Nginx 反向代理
- 在现有 Nginx 配置(
/etc/nginx/sites-available/default)中添加 location 块:1
2
3
4
5
6
7
8
9
10
11
12
13
14location ^~ /gitea/ {
proxy_pass http://localhost: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 X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Prefix /gitea;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
proxy_send_timeout 86400;
} - 使用
^~修饰符确保该 location 优先于其他正则匹配的 location(如静态资源缓存规则),避免静态资源被错误处理。 - 重新加载 Nginx:
systemctl reload nginx。
3. 修正 Gitea 配置
- 发现 Gitea 容器启动后仍使用旧的
ROOT_URL(http://localhost:3000),原因是app.ini未及时更新。 - 直接编辑
data/gitea/conf/app.ini:- 将
DOMAIN = localhost改为DOMAIN = example.com - 将
ROOT_URL = http://localhost:3000改为ROOT_URL = https://example.com/gitea/ - 添加
STATIC_URL_PREFIX = /gitea/assets使静态资源路径正确带上子路径前缀。
- 将
- 重启 Gitea 容器:
docker compose restart,并验证日志中AppURL(ROOT_URL)已更新。
4. 解决静态资源 404 问题
- 静态资源请求返回 404,原因是 Nginx 的
location ^~ /assets/块(用于其他服务)可能优先匹配。 - 将
/gitea/的 location 改为^~ /gitea/,确保以/gitea/开头的请求全部由该块处理,不再进入其他 location。 - 重新加载 Nginx 后,静态资源加载正常。
关键经验
1. 国内镜像源选择
- DaoCloud 镜像
docker.m.daocloud.io拉取速度快,适合国内环境。 - 若镜像不存在,可尝试其他国内镜像仓库(如阿里云、中科大),但需验证可用性。
2. Gitea 子路径配置要点
- ROOT_URL 必须包含完整路径(协议、域名、子路径),且末尾斜杠不影响。
- DOMAIN 应与 ROOT_URL 的域名一致,否则可能导致链接生成错误。
- STATIC_URL_PREFIX 可强制指定静态资源路径,避免浏览器请求错误路径。
- 修改
app.ini后必须重启容器,环境变量也可能覆盖配置,需确保两者一致。
3. Nginx 反向代理注意事项
- location 优先级:前缀 location 默认按最长匹配,但正则 location 可能意外拦截。使用
^~可阻止后续正则匹配。 - proxy_pass 尾部斜杠:
proxy_pass http://localhost:3000/;会去掉匹配的前缀(/gitea/),将剩余路径传递给后端。 - 代理头设置:
X-Forwarded-*头确保后端获取真实客户端信息,X-Forwarded-Prefix让应用识别子路径(Gitea 支持)。 - 静态资源冲突:当多个服务共用同一域名时,注意 location 顺序和匹配规则,避免资源被错误代理。
4. 调试技巧
- 使用
curl -I检查 HTTP 响应头,快速判断代理是否生效。 - 查看容器日志:
docker logs gitea --tail 20确认配置加载情况。 - 直接在浏览器中打开开发者工具,观察网络请求的路径和状态,定位资源加载问题。
验证结果
- Gitea 主页可通过
https://example.com/gitea/访问。 - 静态资源(JS、CSS、图片)均从
/gitea/assets/加载,返回 200 状态码。 - 本地
http://localhost:3000/也可直接访问(仅供测试)。
后续建议
- 定期更新 Gitea 镜像版本,关注安全更新。
- 配置自动备份(数据库、仓库数据)。
- 如需更高性能,可考虑将 SQLite 更换为 PostgreSQL/MySQL。
- 若流量增加,可启用 Gitea 的缓存和 CDN 加速静态资源。
SSH 与 Git 认证问题解决
问题描述
- Git over HTTPS 推送时触发 OAuth 授权重定向(Git Credential Manager),导致推送失败。
- 切换至 SSH 后出现“does not appear to be a git repository”错误,原因是远程地址大小写不匹配。
- 修改 SSH 端口映射后,主机密钥变更导致“REMOTE HOST IDENTIFICATION HAS CHANGED”警告。
- SSH 端口 2222 在外部无法访问,原因是容器内 SSH 服务未正确监听 2222 端口。
解决方案
修正 SSH 远程地址(使用小写用户名):
1
git remote set-url origin git@DOMAIN:viperekura/proj.git
SSH 端口映射调整(使用 2222 端口):
- 修改
docker-compose.yml中端口映射"22:22"→"2222:2222"(容器内外端口一致)。 - 关键:同时设置 SSH 服务环境变量
SSH_PORT和SSH_LISTEN_PORT为2222,确保容器内的 sshd 也监听 2222 端口。 - 重启容器:
docker compose up -d --force-recreate server。
- 修改
处理 SSH 主机密钥变更:
首次连接时重新接受新主机密钥。1
ssh-keygen -R DOMAIN # 清除旧记录
备选方案:HTTPS + 个人访问令牌(无需 SSH 配置):
- 生成令牌:
docker exec -u git gitea gitea admin user generate-access-token --username <username> --token-name "CLI token" --raw --scopes "all" - 令牌值:
<your-token> - 更新远程地址:
1
git remote set-url origin https://<your-token>@DOMAIN/gitea/<username>/<repo>.git
- 生成令牌:
关键经验
- Gitea 仓库路径中的用户名一律规范为小写(
lower_name),SSH 地址必须使用小写。 - 更改容器端口映射会导致 SSH 主机密钥变更,客户端需更新
known_hosts。 - 个人访问令牌(scope 为 “all”)可完全替代 OAuth 交互,适合自动化场景。
- SSH_PORT vs SSH_LISTEN_PORT:前者是给用户显示的端口号,后者是服务实际监听的端口。两者可以不同(如 SSH_PORT=2222 用于对外展示,但 SSH_LISTEN_PORT=22 实际监听 22 端口)。
- 环境变量覆盖:Gitea Docker 镜像使用
GITEA__SECTION__KEY格式的环境变量配置,但 SSH 服务(sshd)的配置需要使用SSH_PORT和SSH_LISTEN_PORT环境变量,这些变量在容器启动时被/etc/s6/openssh/setup脚本使用来生成sshd_config。 - SSH 密钥:部署完成后需将用户公钥添加到 Gitea Web 界面或
/data/git/.ssh/authorized_keys文件中,以支持 SSH 免密登录。
自定义配置
本文档中的配置均为示例值,您可根据实际需求调整:
1. 修改域名
- 将全文中的
DOMAIN替换为您的域名。 - 同时更新
docker-compose.yml中的GITEA__server__DOMAIN和GITEA__server__ROOT_URL环境变量。 - 更新 Nginx 配置中的
server_name和 SSL 证书路径。
2. 修改端口
- HTTP 端口:若希望使用其他端口(如
8080),修改docker-compose.yml中的"3000:3000"为"<主机端口>:<容器端口>",并同步更新app.ini中的HTTP_PORT。 - SSH 端口:若希望使用其他端口(如
2223),修改docker-compose.yml中的"2222:2222"为"<主机端口>:<容器端口>",并同步更新app.ini中的SSH_PORT和SSH_LISTEN_PORT。 - 确保防火墙放行所选端口。
3. 修改子路径
- 若希望将 Gitea 部署在其他子路径(如
/git),需同时修改:docker-compose.yml中的GITEA__server__ROOT_URL。app.ini中的ROOT_URL和STATIC_URL_PREFIX。- Nginx 配置中的
location ^~ /gitea/路径。
4. 使用其他 Gitea 版本
- 修改
docker-compose.yml中的镜像标签(如gitea/gitea:1.22)。
5. 数据库配置
- 默认使用 SQLite,如需改用 PostgreSQL/MySQL,请参考 Gitea 官方文档调整
app.ini的[database]部分。
提示:任何配置变更后,均需重启 Gitea 容器(
docker compose up -d --force-recreate server)并重新加载 Nginx(systemctl reload nginx)。