Gitea
Office Web - Source - Docker Image - Document
Gitea 是一个轻量级的 DevOps 平台软件。从开发计划到产品成型的整个软件生命周期,他都能够高效而轻松的帮助团队和开发者。包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD。它与 GitHub、Bitbucket 和 GitLab 等比较类似。
本教程以 PostgreSQL 方式进行安装。
先决条件
- 确保当前服务器的 ssh 连接端口非 22 端口。以便可以通过 ssh 方式拉取和提交代码。
- 将此域名绑定到此服务器 IP,以便通过域名拉取和提交代码。
使用方法
- 创建数据库
CREATE DATABASE gitea;环境变量
# 若主域名使用了 CDN,则必须设置此域名
GITEA__server__SSH_DOMAIN=ssh.example.com
# 去掉 repo.actions,则默认不启用 Actions
GITEA__repository__DEFAULT_REPO_UNITS=repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages,repo.actions
GITEA__database__DB_TYPE=postgres
GITEA__database__HOST=db:5432
GITEA__database__NAME=gitea
GITEA__database__USER=gitea
GITEA__database__PASSWD=gitea
GITEA__mailer__ENABLED=true
GITEA__mailer__FROM=
GITEA__mailer__PROTOCOL=smtp
GITEA__mailer__HOST=
GITEA__mailer__IS_TLS_ENABLED=true
GITEA__mailer__USER=
GITEA__mailer__PASSWD=配置 app.ini
- 关闭注册功能
[server]
# 自定义 SSH 域名
SSH_DOMAIN = ssh.example.com
[service]
# 禁止用户注册
DISABLE_REGISTRATION = true
# 显示注册按钮
SHOW_REGISTRATION_BUTTON = false
# 默认禁用新仓库的 Actions
# https://docs.gitea.com/zh-cn/next/usage/actions/faq#%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E5%9C%A8%E6%88%91%E7%9A%84%E5%AE%9E%E4%BE%8B%E4%B8%AD%E9%BB%98%E8%AE%A4%E7%A6%81%E7%94%A8%E6%96%B0%E4%BB%93%E5%BA%93%E7%9A%84actions
[repository]
# 去掉 repo.actions 将不会为新仓库自动启用actions
# https://docs.gitea.com/zh-cn/administration/config-cheat-sheet?_highlight=default_repo_units#%E4%BB%93%E5%BA%93-repository
DEFAULT_REPO_UNITS = ...,repo.actionsNginx 反向代理
参考:官方反向代理文档
通用配置
- 在
app.ini中设置[server] ROOT_URL = https://git.example.com/。 - 让反向代理将
https://git.example.com/foo转发到http://gitea:3000/foo。 - 确保反向代理不解码 URI,即
https://git.example.com/a%2Fb应原样转发为http://gitea:3000/a%2Fb。 - 确保
Host和X-Forwarded-Proto请求头正确传递给 Gitea,使其能看到真实访问的 URL。 - 确保 Web 服务器证书完整(含中间证书和根证书),否则
git clone、git pull会失败。 - Gitea 通过
/-/ws的 WebSocket 连接实现实时更新(如通知计数)。反向代理必须使用 HTTP/1.1 并转发Upgrade、Connection请求头,否则 Gitea 会退化为周期性轮询。 - 确保反向代理设置了
X-Real-IP请求头,否则 Gitea 会使用客户端发送的值。如需在日志中记录客户端端口,还需设置X-Real-Port。
基础配置
将以下 server 段添加到 nginx.conf 的 http 段中:
注意
client_max_body_size要足够大,否则上传大文件时会报413 Request Entity Too Large错误。
server {
...
location / {
client_max_body_size 512M;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
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;
}
}子路径(Sub-path)部署
若已有站点,想让 Gitea 共用同一域名,可将其部署在子路径下(通常不推荐,部分场景可能有兼容性问题):
server {
...
location ~ ^/(gitea|v2)($|/) {
client_max_body_size 512M;
# 让 nginx 使用未转义的 URI,保留 "%2F" 原样,去掉 "/gitea" 子路径前缀,"/v2" 原样透传。
rewrite ^ $request_uri;
rewrite ^/(gitea($|/))?(.*) /$3 break;
proxy_pass http://127.0.0.1:3000$uri;
proxy_http_version 1.1;
# 其他通用请求头,见上方「基础配置」
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
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;
}
}子路径下容器镜像仓库需要根级别的固定子路径
/v2,上面配置中的v2已一并处理。
然后必须在配置中正确设置 [server] ROOT_URL = http://git.example.com/gitea/。
Nginx 直接托管静态资源(性能优化)
可将请求分为静态与动态两类:CSS、JavaScript、图片、Web 字体属于静态内容;首页、仓库视图、Issue 列表属于动态内容。Nginx 直接返回静态资源、仅将动态请求代理给 Gitea,可获得更好的性能。
下载 Gitea 源码仓库快照到 /path/to/gitea/,在仓库目录执行 make frontend 生成静态资源(需要 Node.js/npm 和 make),只需保留其中的 public/ 目录。
单节点单域名:在配置中设置 [server] STATIC_URL_PREFIX = /_/static
server {
listen 80;
server_name git.example.com;
location /_/static/assets/ {
alias /path/to/gitea/public/;
}
location / {
# 其余指令见上方「基础配置」
proxy_pass http://localhost:3000;
}
}双节点双域名:在配置中设置 [server] STATIC_URL_PREFIX = http://cdn.example.com/gitea
# 运行 Gitea 的应用服务器
server {
listen 80;
server_name git.example.com;
location / {
# 其余指令见上方「基础配置」
proxy_pass http://localhost:3000;
}
}# 静态内容分发服务器
server {
listen 80;
server_name cdn.example.com;
location /gitea/ {
alias /path/to/gitea/public/;
}
location / {
return 404;
}
}SSH(22 端口)反向代理
适用场景:Gitea 部署在海外 VPS,国内无法直连其 22 端口,需要用一台国内 VPS 中转 SSH 流量,以便 git clone、git push、ssh 正常工作。
SSH 是四层 TCP 流量,必须使用 nginx 的
stream模块,而不是上面http模块的反向代理。stream模块自 nginx 1.9.0 起可用,但默认不编译,需以--with-stream参数启用。检查是否已编译:nginx -V 2>&1 | grep with-stream(Debian/Ubuntu/RHEL 等发行版官方源安装的 nginx 一般已包含)。stream {}块必须写在nginx.conf的顶层(与http {}平级),不能放进http或conf.d/*.conf中。
假设:海外 VPS 为 overseas.example.com,Gitea 容器的 SSH 端口映射为宿主机 2222;国内中转 VPS 监听 22 端口。
国内中转 VPS 的 nginx.conf 顶层添加:
stream {
server {
listen 22;
# SSH 为长连接,超时时间设置长一些,避免大仓库传输中途断开
proxy_connect_timeout 10s;
proxy_timeout 300s;
proxy_pass overseas.example.com:2222;
}
}
proxy_pass中的域名只在 nginx 启动/重载时解析一次。若海外 VPS 的 IP 会变化,可改用变量形式并配合resolver,让 nginx 按缓存的 TTL 重新解析,无需 reload:nginxstream { resolver 223.5.5.5 119.29.29.29 valid=30s; resolver_timeout 5s; server { listen 22; proxy_connect_timeout 10s; proxy_timeout 300s; set $backend overseas.example.com:2222; proxy_pass $backend; } }若大仓库推送/拉取长时间无数据传输导致连接被中断,可在
listen上追加so_keepalive=on启用 TCP 保活:listen 22 so_keepalive=on;。
海外 VPS 上无需任何改动,只需确保:
- 防火墙/安全组放行来自国内中转 VPS 的
2222端口(更安全的做法:仅允许中转 VPS 的 IP 访问,不对公网开放)。 app.ini中[server] SSH_DOMAIN设置为国内中转 VPS 的域名(或 IP),这样 Gitea 页面上展示的克隆地址才是国内可直连的:
[server]
SSH_DOMAIN = relay.example.com使用方式:
# 对用户而言与直连完全一样,只是实际流量走了国内中转
git clone git@relay.example.com:username/repo.git若中转 VPS 的 22 端口被占用(如自身 SSH 服务),可监听其他端口(如
listen 2222;),用户端改用ssh://git@relay.example.com:2222/username/repo.git形式克隆;此时若希望 Gitea 页面展示的 SSH 地址也带端口,可继续配合SSH_PORT配置。更轻量的替代方案:中转 VPS 也可以不做任何代理,仅修改用户端
~/.ssh/config走跳板:ProxyJump或ProxyCommand。nginxstream的优点是全透明,团队所有成员无需各自配置。
CI/CD 自动构建平台
Gitea Runner
初始化配置文件
docker run --entrypoint="" --rm -it gitea/act_runner:nightly act_runner generate-config > config.yaml获取注册令牌
gitea --config /etc/gitea/app.ini actions generate-runner-token或全局注册令牌
openssl rand -hex 24 > /some-dir/runner-token
export GITEA_RUNNER_REGISTRATION_TOKEN_FILE=/some-dir/runner-token
./gitea --config ...
# Docker 中使用时
## 1. 生成密钥文件
openssl rand -hex 24 > runner-token
## 2. 更新 .env 文件中 GITEA_RUNNER_REGISTRATION_TOKEN_FILE 的环境变量
## 若 GITEA_RUNNER_REGISTRATION_TOKEN 与 GITEA_RUNNER_REGISTRATION_TOKEN_FILE 同时设置时,优先使用 GITEA_RUNNER_REGISTRATION_TOKEN
GITEA_RUNNER_REGISTRATION_TOKEN_FILE=/runner-token
## 3. 映射至容器中
gitea:
...
volumes:
- ./runner-token:/runner-token
runner:
...
volumes:
- ./runner-token:/runner-token注册 Runner
./act_runner register
# 或
./act_runner --config config.yaml register非交互式
./act_runner register --no-interactive --instance <instance_url> --token <registration_token> --name <runner_name> --labels <runner_labels>Runner 镜像
ghcr.io/catthehacker/ubuntu:act-22.04
ghcr.io/catthehacker/ubuntu:act-24.04
ghcr.io/catthehacker/ubuntu:act-latest- 更新
config.yaml,使用对应的镜像
labels:
- "ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest"
- "ubuntu-24.04:docker://ghcr.io/catthehacker/ubuntu:act-24.04"
- "ubuntu-22.04:docker://ghcr.io/catthehacker/ubuntu:act-22.04"Drone 平台
首先,将此域名绑定到此服务器 IP。
生成 Gitea 应用密钥
GITEA 为 Gitea 代码托管服务的域名,DRONE 为 Drone 的访问域名。
- 打开网址
https://{GITEA}/user/settings/applications。 - 最下方 创建新的 OAuth2 应用程序,应用名称设置为
Drone,重定向 URI设置为https://{DRONE}/login. - 记录下 客户端ID(DRONE_GITEA_CLIENT_ID)、客户端密钥(DRONE_GITEA_CLIENT_SECRET)。
- 执行下述命令行:
# 安装
./run.sh drone {{DRONE_SERVER_HOST}} {{DRONE_GITEA_CLIENT_ID}} {{DRONE_GITEA_CLIENT_SECRET}}DRONE_SERVER_HOST: Drone 访问的实际域名 DRONE_GITEA_CLIENT_ID: Gitea 应用客户端ID DRONE_GITEA_CLIENT_SECRET: Gitea 应用客户端密钥
Woodpecker 平台
首先,将此域名绑定到此服务器 IP。
生成 Gitea 应用密钥
GITEA 为 Gitea 代码托管服务的域名,WOODPECKER 为 Woodpecker 的访问域名。
- 打开网址
https://{GITEA}/user/settings/applications。 - 最下方 创建新的 OAuth2 应用程序,应用名称设置为
Woodpecker,重定向 URI设置为https://{WOODPECKER}/authorize. - 记录下 客户端ID(WOODPECKER_GITEA_CLIENT)、客户端密钥(WOODPECKER_GITEA_SECRET)。
- 执行下述命令行:
# 安装
./run.sh woodpecker {{WOODPECKER_HOST}} {{WOODPECKER_GITEA_CLIENT}} {{WOODPECKER_GITEA_SECRET}}WOODPECKER_HOST: Woodpecker 访问的实际域名 WOODPECKER_GITEA_CLIENT: Gitea 应用客户端ID WOODPECKER_GITEA_SECRET: Gitea 应用客户端密钥
教程
- 视频教程: