概述
什么是 Gitea
Gitea 是一个轻量级的开源 Git 服务,使用 Go 语言编写,旨在提供一个简单、快速、自托管的 Git 解决方案。它是从 Gogs 项目 fork 而来,提供了类似 GitHub、GitLab 的功能,但资源占用更少。
核心特点
-
轻量级
- 内存占用少(最低 256MB)
- 单个二进制文件即可运行
- 启动速度快
-
功能丰富
- 支持 Git 所有基本操作
- 内置 Issues、Pull Requests、Wiki
- 支持组织和团队管理
- 提供 WebHooks 和 API
-
易于部署
- 支持多种部署方式
- 配置简单直观
- 跨平台支持
-
开源免费
- MIT 许可证
- 活跃的社区支持
- 定期更新维护
使用场景
- 小团队代码托管:适合中小型团队的私有代码管理
- 个人项目管理:个人开发者的代码备份和版本控制
- 企业内部仓库:企业内部代码托管平台
- 教学环境:编程教学的代码提交和管理平台
- 备用方案:作为 GitHub/GitLab 的备用或镜像服务
环境准备
系统要求
💡 最低配置
- CPU:1 核心
- 内存:256MB(推荐 512MB 以上)
- 磁盘:根据仓库大小,建议至少 10GB
- 系统:Linux、Windows、macOS
依赖安装
首先检查 Docker 和 Docker Compose 的安装情况
docker-compose -v
安装部署
Docker 部署(推荐)
1. 创建工作目录
cd /var/lib
mkdir docker-compose
2. 编写 docker-compose 配置
创建 docker-compose.yml 文件:
vi docker-compose.yml
version: "3.8"
networks:
gitea:
external: false
services:
# Gitea 服务
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=mysql
- GITEA__database__HOST=db:3306
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea123456
- GITEA__cache__ENABLED=true
- GITEA__cache__ADAPTER=redis
- GITEA__cache__HOST=redis://cache:6379/0?pool_size=100&idle_timeout=180s
- GITEA__server__ROOT_URL=http://localhost:10800/
- GITEA__server__SSH_DOMAIN=localhost
- GITEA__server__SSH_PORT=2222
restart: always
networks:
- gitea
volumes:
- ./gitea-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "10800:3000" # Web 界面
- "2222:22" # SSH 端口
depends_on:
- db
- cache
# MySQL 数据库
db:
image: mysql:8.0
container_name: gitea-mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=gitea
- MYSQL_USER=gitea
- MYSQL_PASSWORD=gitea123456
networks:
- gitea
volumes:
- ./mysql-data:/var/lib/mysql
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# Redis 缓存
cache:
image: redis:7-alpine
container_name: gitea-redis
restart: always
networks:
- gitea
volumes:
- ./redis-data:/data
command: redis-server --appendonly yes
volumes:
gitea-data:
mysql-data:
redis-data:
⚠️ 注意:生产环境请修改数据库密码和其他敏感配置
3. 启动服务
docker-compose up -d
4. 检查运行状态
# 查看容器状态
docker-compose ps
# 查看日志
docker-compose logs -f gitea
# 检查所有服务
docker ps | grep gitea
5. 初始化配置
访问 http://localhost:10800 进行初始化配置。
二进制安装
1. 下载二进制文件
# 下载最新版本
wget -O gitea https://dl.gitea.io/gitea/1.21.0/gitea-1.21.0-linux-amd64
chmod +x gitea
# 或使用 curl
curl -fsSL -o gitea https://dl.gitea.io/gitea/1.21.0/gitea-1.21.0-linux-amd64
chmod +x gitea
2. 创建用户和目录
# 创建 git 用户
sudo useradd -r -s /bin/bash -m -d /home/git git
# 创建必要目录
sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo chown -R git:git /var/lib/gitea/
sudo chmod -R 750 /var/lib/gitea/
sudo mkdir /etc/gitea
sudo chown root:git /etc/gitea
sudo chmod 770 /etc/gitea
3. 配置 systemd 服务
创建 /etc/systemd/system/gitea.service:
[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
Wants=mysql.service
[Service]
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
[Install]
WantedBy=multi-user.target
4. 启动服务
sudo systemctl daemon-reload
sudo systemctl enable gitea
sudo systemctl start gitea
源码编译安装
1. 安装依赖
# 安装 Go 语言环境(需要 Go 1.20+)
wget https://go.dev/dl/go1.21.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
# 安装编译工具
sudo apt-get update
sudo apt-get install -y git nodejs npm make
2. 克隆源码
git clone https://github.com/go-gitea/gitea
cd gitea
3. 编译
# 编译后端
GOOS=linux GOARCH=amd64 make build
# 编译前端资源
make generate
配置管理
基本配置
配置文件位置:/etc/gitea/app.ini 或 custom/conf/app.ini
核心配置示例
[server]
; 协议 (http, https, fcgi, http+unix, fcgi+unix)
PROTOCOL = http
; 监听地址
HTTP_ADDR = 0.0.0.0
; 监听端口
HTTP_PORT = 3000
; 外部访问 URL
ROOT_URL = https://git.example.com/
; 禁用 SSH
DISABLE_SSH = false
; SSH 端口
SSH_PORT = 22
; SSH 监听地址
SSH_LISTEN_HOST = 0.0.0.0
; SSH 域名
SSH_DOMAIN = git.example.com
[database]
; 数据库类型 [mysql, postgres, sqlite3, mssql]
DB_TYPE = mysql
; 数据库连接信息
HOST = 127.0.0.1:3306
; 数据库名称
NAME = gitea
; 数据库用户名
USER = gitea
; 数据库密码
PASSWD = `your_password`
; SSL 模式 [disable, require, verify-ca, verify-full]
SSL_MODE = disable
; 字符集
CHARSET = utf8mb4
[security]
; 安装锁定
INSTALL_LOCK = true
; 密钥
SECRET_KEY = your_secret_key
; 内部令牌
INTERNAL_TOKEN = your_internal_token
; 密码哈希算法
PASSWORD_HASH_ALGO = pbkdf2
[service]
; 禁用注册
DISABLE_REGISTRATION = false
; 需要登录才能查看
REQUIRE_SIGNIN_VIEW = false
; 注册时需要邮箱确认
REGISTER_EMAIL_CONFIRM = true
; 启用邮件通知
ENABLE_NOTIFY_MAIL = true
; 默认保持邮箱私密
DEFAULT_KEEP_EMAIL_PRIVATE = true
; 默认允许创建组织
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
数据库配置
MySQL 配置
[database]
DB_TYPE = mysql
HOST = 127.0.0.1:3306
NAME = gitea
USER = gitea
PASSWD = gitea_password
CHARSET = utf8mb4
; 连接池配置
MAX_OPEN_CONNS = 30
MAX_IDLE_CONNS = 5
CONN_MAX_LIFETIME = 0
PostgreSQL 配置
[database]
DB_TYPE = postgres
HOST = 127.0.0.1:5432
NAME = gitea
USER = gitea
PASSWD = gitea_password
SSL_MODE = disable
SCHEMA = public
SQLite 配置
[database]
DB_TYPE = sqlite3
PATH = /var/lib/gitea/data/gitea.db
缓存配置
[cache]
; 是否启用缓存
ENABLED = true
; 缓存适配器 [memory, redis, memcache, twoqueue]
ADAPTER = redis
; 缓存有效期
INTERVAL = 60
; Redis 配置
HOST = redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s
邮件配置
[mailer]
; 是否启用邮件
ENABLED = true
; SMTP 服务器
HOST = smtp.gmail.com:587
; 发件人
FROM = gitea@example.com
; SMTP 用户名
USER = gitea@example.com
; SMTP 密码
PASSWD = your_email_password
; 使用客户端证书
USE_CERTIFICATE = false
; 使用客户端证书文件
CERT_FILE = custom/mailer/cert.pem
KEY_FILE = custom/mailer/key.pem
; 跳过证书验证
SKIP_VERIFY = false
; 使用 TLS
IS_TLS_ENABLED = true
; HELO 主机名
HELO_HOSTNAME =
; 邮件队列长度
SEND_BUFFER_LEN = 100
SSH 配置
[server]
; SSH 配置
START_SSH_SERVER = true
SSH_DOMAIN = git.example.com
SSH_PORT = 22
SSH_LISTEN_HOST = 0.0.0.0
SSH_LISTEN_PORT = %(SSH_PORT)s
; SSH 密钥目录
SSH_ROOT_PATH = /home/git/.ssh
; SSH 密钥测试
SSH_KEY_TEST_PATH =
; SSH 密钥交换算法
SSH_KEYGEN_PATH = ssh-keygen
; 最小密钥大小
MINIMUM_KEY_SIZE_CHECK = true
; ED25519
ED25519 = 256
; ECDSA
ECDSA = 256
; RSA
RSA = 2048
; DSA
DSA = -1
用户和仓库管理
用户管理
创建管理员用户
# 通过命令行创建管理员
sudo -u git gitea admin user create \
--username admin \
--password admin123 \
--email admin@example.com \
--admin \
--config /etc/gitea/app.ini
用户权限级别
- 管理员:拥有所有权限
- 普通用户:可以创建仓库和组织
- 受限用户:只能查看和参与授权的仓库
批量用户管理
# 导出用户列表
sudo -u git gitea admin user list --config /etc/gitea/app.ini
# 修改用户密码
sudo -u git gitea admin user change-password \
--username user1 \
--password newpassword \
--config /etc/gitea/app.ini
# 删除用户
sudo -u git gitea admin user delete \
--username user1 \
--config /etc/gitea/app.ini
组织管理
创建组织
# 通过 API 创建组织
curl -X POST "http://localhost:3000/api/v1/orgs" \
-H "Authorization: token YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "myorg",
"full_name": "My Organization",
"description": "This is my organization",
"website": "https://example.com",
"location": "Beijing",
"visibility": "public"
}'
团队管理
组织内可以创建不同的团队,并设置不同的权限:
- Owners:组织所有者,拥有所有权限
- Admin:管理员团队,可以管理仓库
- Write:写入团队,可以推送代码
- Read:只读团队,只能查看代码
仓库管理
仓库设置
[repository]
; 默认分支名称
DEFAULT_BRANCH = main
; 仓库根目录
ROOT = /home/git/gitea-repositories
; 强制私有
FORCE_PRIVATE = false
; 默认私有
DEFAULT_PRIVATE = false
; 最大创建限制
MAX_CREATION_LIMIT = -1
; 禁用 HTTP Git
DISABLE_HTTP_GIT = false
; 启用本地 Wiki
ENABLE_LOCAL_WIKI = true
仓库镜像
# 创建镜像仓库
curl -X POST "http://localhost:3000/api/v1/repos/migrate" \
-H "Authorization: token YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"clone_addr": "https://github.com/example/repo.git",
"repo_name": "mirrored-repo",
"mirror": true,
"private": false,
"description": "Mirror of example repo"
}'
权限控制
仓库权限级别
- Owner:仓库所有者,拥有所有权限
- Admin:管理员,可以修改仓库设置
- Write:可以推送代码、管理 issues 和 PR
- Read:只能查看和克隆仓库
分支保护
{
"branch_name": "main",
"enable_push": false,
"enable_push_whitelist": true,
"push_whitelist_usernames": ["admin", "developer1"],
"push_whitelist_teams": ["developers"],
"enable_merge_whitelist": true,
"merge_whitelist_usernames": ["admin"],
"merge_whitelist_teams": ["maintainers"],
"enable_status_check": true,
"status_check_contexts": ["continuous-integration/travis-ci"],
"required_approvals": 2,
"dismiss_stale_approvals": true,
"require_signed_commits": false,
"protected_file_patterns": "README.md\n.gitignore"
}
集成配置
CI/CD 集成
Jenkins 集成
- 安装 Gitea 插件
// Jenkinsfile 示例
pipeline {
agent any
triggers {
gitea(
server: 'https://git.example.com',
credentialsId: 'gitea-credentials',
events: [
push(),
pullRequest()
]
)
}
stages {
stage('Build') {
steps {
echo 'Building...'
sh 'make build'
}
}
stage('Test') {
steps {
echo 'Testing...'
sh 'make test'
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
echo 'Deploying...'
sh 'make deploy'
}
}
}
}
- 配置 Webhook
在 Gitea 仓库设置中添加 Webhook:
- URL:
http://jenkins:8080/gitea-webhook/post - Secret: 配置共享密钥
- Events: 选择需要触发的事件
GitLab CI 风格的 CI/CD
使用 Gitea Actions(实验性功能):
# .gitea/workflows/ci.yml
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.20'
- name: Install dependencies
run: go mod download
- name: Run tests
run: go test -v ./...
- name: Build
run: go build -v ./...
Webhook 配置
支持的 Webhook 事件
- 仓库事件:创建、删除、Fork
- 推送事件:代码推送
- Issue 事件:创建、关闭、重新打开、编辑、分配、标签、里程碑、评论
- Pull Request 事件:创建、关闭、重新打开、编辑、分配、标签、里程碑、评论、同步
- Release 事件:发布、更新、删除
- Wiki 事件:创建、编辑、删除页面
Webhook 配置示例
{
"type": "gitea",
"config": {
"url": "https://example.com/webhook",
"content_type": "json",
"secret": "your-webhook-secret",
"insecure_ssl": "0",
"authorization_header": ""
},
"events": [
"push",
"pull_request",
"issues",
"release"
],
"active": true,
"branch_filter": "main|develop|feature/*"
}
处理 Webhook 的示例代码
# Python Flask 示例
from flask import Flask, request, jsonify
import hmac
import hashlib
app = Flask(__name__)
WEBHOOK_SECRET = 'your-webhook-secret'
def verify_signature(payload, signature):
"""验证 Webhook 签名"""
expected_signature = hmac.new(
WEBHOOK_SECRET.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected_signature, signature)
@app.route('/webhook', methods=['POST'])
def handle_webhook():
# 验证签名
signature = request.headers.get('X-Gitea-Signature', '')
if not verify_signature(request.data, signature):
return jsonify({'error': 'Invalid signature'}), 401
# 处理不同的事件
event = request.headers.get('X-Gitea-Event')
payload = request.json
if event == 'push':
# 处理推送事件
branch = payload['ref'].split('/')[-1]
print(f"Push to branch {branch}")
# 触发 CI/CD 流程
elif event == 'pull_request':
# 处理 PR 事件
action = payload['action']
pr_number = payload['number']
print(f"PR #{pr_number} {action}")
return jsonify({'status': 'success'}), 200
if __name__ == '__main__':
app.run(port=5000)
OAuth2 配置
配置 OAuth2 提供商
[oauth2]
; 启用 OAuth2 提供商
ENABLE = true
; JWT 密钥
JWT_SECRET = your-jwt-secret
; 访问令牌有效期(秒)
ACCESS_TOKEN_EXPIRATION_TIME = 3600
; 刷新令牌有效期(秒)
REFRESH_TOKEN_EXPIRATION_TIME = 730000
; 授权码有效期(秒)
AUTH_CODE_EXPIRATION_TIME = 300
添加外部认证源
- GitHub OAuth
[oauth2_client]
REGISTER_EMAIL_CONFIRM = false
ENABLE_AUTO_REGISTRATION = true
USERNAME = nickname
UPDATE_AVATAR = true
[[oauth2_client.sources]]
NAME = GitHub
PROVIDER = github
KEY = your-github-client-id
SECRET = your-github-client-secret
AUTO_DISCOVER_URL =
USE_CUSTOM_URLS = false
CUSTOM_AUTH_URL =
CUSTOM_TOKEN_URL =
CUSTOM_PROFILE_URL =
CUSTOM_EMAIL_URL =
SCOPES = user:email
- LDAP 认证
[auth.ldap]
NAME = Company LDAP
SECURITY_PROTOCOL = ldaps
HOST = ldap.example.com
PORT = 636
USER_SEARCH_BASE = ou=users,dc=example,dc=com
USER_FILTER = (&(objectClass=person)(uid=%s))
ADMIN_FILTER = (memberOf=cn=admins,ou=groups,dc=example,dc=com)
USERNAME_ATTRIBUTE = uid
FIRSTNAME_ATTRIBUTE = givenName
SURNAME_ATTRIBUTE = sn
EMAIL_ATTRIBUTE = mail
PUBLIC_SSH_KEY_ATTRIBUTE = sshPublicKey
BIND_DN = cn=readonly,dc=example,dc=com
BIND_PASSWORD = readonly-password
SYNC_USERS = true
PAGE_SIZE = 100
第三方集成
Drone CI 集成
# .drone.yml
kind: pipeline
type: docker
name: default
steps:
- name: test
image: golang:1.20
commands:
- go test ./...
- name: build
image: golang:1.20
commands:
- go build -o app .
- name: docker
image: plugins/docker
settings:
repo: myregistry.com/myapp
tags:
- latest
- ${DRONE_TAG}
username:
from_secret: docker_username
password:
from_secret: docker_password
when:
event:
- tag
Prometheus 监控集成
# prometheus.yml
scrape_configs:
- job_name: 'gitea'
static_configs:
- targets: ['gitea:3000']
metrics_path: '/metrics'
params:
token: ['your-metrics-token']
备份与恢复
备份策略
1. 全量备份脚本
#!/bin/bash
# gitea-backup.sh
# 配置变量
BACKUP_DIR="/backup/gitea"
GITEA_DIR="/var/lib/gitea"
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_NAME="gitea_backup_${DATE}"
# 创建备份目录
mkdir -p ${BACKUP_DIR}
# 停止 Gitea 服务(可选)
systemctl stop gitea
# 备份数据库
if [[ "$DB_TYPE" == "mysql" ]]; then
mysqldump -u${DB_USER} -p${DB_PASS} -h${DB_HOST} ${DB_NAME} > ${BACKUP_DIR}/${BACKUP_NAME}_database.sql
elif [[ "$DB_TYPE" == "postgres" ]]; then
pg_dump -U ${DB_USER} -h ${DB_HOST} ${DB_NAME} > ${BACKUP_DIR}/${BACKUP_NAME}_database.sql
fi
# 备份仓库数据
tar -czf ${BACKUP_DIR}/${BACKUP_NAME}_repositories.tar.gz ${GITEA_DIR}/gitea-repositories
# 备份配置文件
tar -czf ${BACKUP_DIR}/${BACKUP_NAME}_config.tar.gz /etc/gitea
# 备份数据目录
tar -czf ${BACKUP_DIR}/${BACKUP_NAME}_data.tar.gz ${GITEA_DIR}/data
# 启动 Gitea 服务
systemctl start gitea
# 清理旧备份(保留最近7天)
find ${BACKUP_DIR} -name "gitea_backup_*" -mtime +7 -delete
echo "Backup completed: ${BACKUP_NAME}"
2. 使用 Gitea 内置备份命令
# 执行备份
sudo -u git gitea dump -c /etc/gitea/app.ini
# 指定备份文件位置
sudo -u git gitea dump -c /etc/gitea/app.ini -f /backup/gitea-dump.zip
# 排除仓库数据(仅备份数据库和配置)
sudo -u git gitea dump -c /etc/gitea/app.ini --skip-repository
# 排除 LFS 数据
sudo -u git gitea dump -c /etc/gitea/app.ini --skip-lfs-data
3. 定时备份配置
# 创建 cron 任务
crontab -e
# 每天凌晨 2 点执行备份
0 2 * * * /usr/local/bin/gitea-backup.sh >> /var/log/gitea-backup.log 2>&1
# 每周日凌晨 3 点执行完整备份
0 3 * * 0 sudo -u git gitea dump -c /etc/gitea/app.ini -f /backup/weekly/gitea-$(date +\%Y\%m\%d).zip
恢复流程
1. 从备份文件恢复
# 解压备份文件
unzip gitea-dump-1234567890.zip
# 恢复数据库
mysql -u${DB_USER} -p${DB_PASS} ${DB_NAME} < gitea-db.sql
# 恢复仓库数据
cp -r repos/* /home/git/gitea-repositories/
# 恢复配置文件
cp -r custom/* /var/lib/gitea/custom/
# 恢复数据目录
cp -r data/* /var/lib/gitea/data/
# 修复权限
chown -R git:git /home/git/gitea-repositories
chown -R git:git /var/lib/gitea
# 重启服务
systemctl restart gitea
2. 灾难恢复步骤
#!/bin/bash
# disaster-recovery.sh
# 1. 准备新服务器
apt-get update
apt-get install -y git mysql-server
# 2. 恢复 Gitea 程序
wget -O gitea https://dl.gitea.io/gitea/1.21.0/gitea-1.21.0-linux-amd64
chmod +x gitea
mv gitea /usr/local/bin/
# 3. 创建用户和目录
useradd -r -s /bin/bash -m -d /home/git git
mkdir -p /var/lib/gitea/{custom,data,log}
mkdir /etc/gitea
# 4. 恢复数据
# 从备份服务器拷贝备份文件
scp backup-server:/backup/gitea/latest.zip /tmp/
# 解压并恢复
cd /tmp
unzip latest.zip
mysql < gitea-db.sql
cp -r repos/* /home/git/gitea-repositories/
cp -r custom/* /var/lib/gitea/custom/
cp app.ini /etc/gitea/
# 5. 设置权限
chown -R git:git /home/git
chown -R git:git /var/lib/gitea
chown root:git /etc/gitea
chmod 770 /etc/gitea
# 6. 配置并启动服务
systemctl enable gitea
systemctl start gitea
迁移指南
1. 迁移到新服务器
# 在源服务器上
# 创建迁移包
sudo -u git gitea dump -c /etc/gitea/app.ini -f /tmp/gitea-migrate.zip
# 传输到目标服务器
scp /tmp/gitea-migrate.zip user@new-server:/tmp/
# 在目标服务器上
# 安装 Gitea(相同版本)
# 解压并恢复数据
cd /tmp
unzip gitea-migrate.zip
# 按照恢复流程操作
2. 版本升级迁移
# 1. 备份当前版本
sudo -u git gitea dump -c /etc/gitea/app.ini
# 2. 停止服务
systemctl stop gitea
# 3. 下载新版本
wget -O gitea.new https://dl.gitea.io/gitea/1.21.0/gitea-1.21.0-linux-amd64
# 4. 替换程序
mv /usr/local/bin/gitea /usr/local/bin/gitea.old
mv gitea.new /usr/local/bin/gitea
chmod +x /usr/local/bin/gitea
# 5. 执行数据库迁移
sudo -u git gitea migrate -c /etc/gitea/app.ini
# 6. 启动新版本
systemctl start gitea
# 7. 验证升级
curl http://localhost:3000/api/v1/version
性能优化
服务器优化
1. 系统参数调优
# /etc/sysctl.conf
# 网络优化
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
# 文件系统优化
fs.file-max = 1000000
fs.inotify.max_user_watches = 524288
# 应用配置
sysctl -p
2. Gitea 性能配置
[server]
; 启用 GZIP 压缩
ENABLE_GZIP = true
; 静态文件缓存
STATIC_CACHE_TIME = 6h
[cache]
; 启用缓存
ENABLED = true
; 使用 Redis 缓存
ADAPTER = redis
HOST = redis://127.0.0.1:6379/0?pool_size=100&idle_timeout=180s
; 缓存 TTL
INTERVAL = 60
[session]
; 使用 Redis 存储会话
PROVIDER = redis
PROVIDER_CONFIG = redis://127.0.0.1:6379/1?pool_size=100&idle_timeout=180s
[queue]
; 使用 Redis 队列
TYPE = redis
CONN_STR = redis://127.0.0.1:6379/2?pool_size=100&idle_timeout=180s
数据库优化
MySQL 优化
# /etc/mysql/mysql.conf.d/gitea.cnf
[mysqld]
# InnoDB 优化
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
# 查询缓存
query_cache_type = 1
query_cache_size = 128M
query_cache_limit = 2M
# 连接池
max_connections = 500
max_connect_errors = 1000
# 临时表
tmp_table_size = 256M
max_heap_table_size = 256M
PostgreSQL 优化
# postgresql.conf
# 内存设置
shared_buffers = 2GB
effective_cache_size = 6GB
work_mem = 32MB
maintenance_work_mem = 512MB
# 检查点
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
# 连接池
max_connections = 200
缓存优化
Redis 配置优化
# /etc/redis/redis.conf
# 持久化策略
save 900 1
save 300 10
save 60 10000
# 内存策略
maxmemory 4gb
maxmemory-policy allkeys-lru
# 连接池
maxclients 10000
timeout 300
# 性能优化
tcp-backlog 511
tcp-keepalive 300
页面缓存配置
# Nginx 缓存配置
proxy_cache_path /var/cache/nginx/gitea
levels=1:2
keys_zone=gitea_cache:100m
max_size=10g
inactive=60m
use_temp_path=off;
server {
location / {
proxy_pass http://localhost:3000;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_cache gitea_cache;
proxy_cache_valid 200 7d;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
add_header X-Cache-Status $upstream_cache_status;
}
}
}
安全加固
访问控制
1. 防火墙配置
# UFW 防火墙配置
ufw default deny incoming
ufw default allow outgoing
# 允许 SSH
ufw allow 22/tcp
# 允许 Gitea Web
ufw allow 10800/tcp
# 允许 Gitea SSH
ufw allow 2222/tcp
# 启用防火墙
ufw enable
2. Fail2ban 配置
# /etc/fail2ban/filter.d/gitea.conf
[Definition]
failregex = .*Failed authentication attempt for .* from <HOST>
.*invalid credentials from <HOST>
ignoreregex =
# /etc/fail2ban/jail.d/gitea.conf
[gitea]
enabled = true
port = 10800,2222
protocol = tcp
filter = gitea
logpath = /var/lib/gitea/log/gitea.log
maxretry = 5
bantime = 3600
findtime = 600
SSL/TLS 配置
1. 使用 Let’s Encrypt
# 安装 Certbot
apt-get install certbot
# 获取证书
certbot certonly --standalone -d git.example.com
# 配置 Gitea 使用 HTTPS
[server]
PROTOCOL = https
CERT_FILE = /etc/letsencrypt/live/git.example.com/fullchain.pem
KEY_FILE = /etc/letsencrypt/live/git.example.com/privkey.pem
HTTP_PORT = 443
2. 使用 Nginx 反向代理
# /etc/nginx/sites-available/gitea
server {
listen 80;
server_name git.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name git.example.com;
# SSL 配置
ssl_certificate /etc/letsencrypt/live/git.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头部
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# 反向代理
location / {
proxy_pass http://localhost:3000;
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;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 超时设置
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
proxy_read_timeout 600s;
# 文件上传大小
client_max_body_size 500M;
}
}
安全最佳实践
1. 密码策略
[security]
; 最小密码长度
MIN_PASSWORD_LENGTH = 12
; 密码复杂度
PASSWORD_COMPLEXITY = lower,upper,digit,spec
; 密码哈希算法
PASSWORD_HASH_ALGO = pbkdf2
2. API 安全
[api]
; 启用 API
ENABLED = true
; API 速率限制
ENABLE_RATE_LIMIT = true
; 每小时请求限制
RATE_LIMIT_PER_HOUR = 1000
; 启用 Swagger
ENABLE_SWAGGER = false
; 最大响应项目数
MAX_RESPONSE_ITEMS = 50
; 默认分页大小
DEFAULT_PAGING_NUM = 30
3. 安全审计
# 审计日志配置
[log]
MODE = file
LEVEL = Info
ROOT_PATH = /var/lib/gitea/log
[log.file]
LOG_ROTATE = true
MAX_DAYS = 30
MAX_SIZE_SHIFT = 28
DAILY_ROTATE = true
COMPRESS = true
监控与维护
日志管理
1. 日志配置
[log]
; 日志级别:Trace, Debug, Info, Warn, Error, Critical
LEVEL = Info
; 日志模式:console, file, conn, smtp, database
MODE = file
; 日志根路径
ROOT_PATH = /var/lib/gitea/log
; 访问日志
[log.access]
ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}" "{{.Ctx.Req.UserAgent}}"
; 路由日志
[log.router]
ENABLE_ACCESS_LOG = true
ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteAddr}} - "{{.Ctx.Req.Method}} {{.Ctx.Req.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.UserAgent}}"
2. 日志轮转
# /etc/logrotate.d/gitea
/var/lib/gitea/log/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 git git
sharedscripts
postrotate
systemctl reload gitea
endscript
}
性能监控
1. Prometheus 指标
[metrics]
; 启用指标
ENABLED = true
; 指标令牌
TOKEN = your-metrics-token
2. Grafana 仪表板
{
"dashboard": {
"title": "Gitea Metrics",
"panels": [
{
"title": "HTTP Requests",
"targets": [
{
"expr": "rate(gitea_http_requests_total[5m])"
}
]
},
{
"title": "Active Users",
"targets": [
{
"expr": "gitea_users_active"
}
]
},
{
"title": "Repository Count",
"targets": [
{
"expr": "gitea_repositories_total"
}
]
}
]
}
}
故障排查
1. 常见问题诊断
# 检查服务状态
systemctl status gitea
journalctl -u gitea -f
# 检查端口监听
ss -tlnp | grep gitea
# 检查进程
ps aux | grep gitea
# 检查数据库连接
mysql -u gitea -p -h localhost gitea -e "SELECT 1"
# 检查磁盘空间
df -h /var/lib/gitea
# 检查内存使用
free -h
2. 性能问题排查
# 查看慢查询
tail -f /var/lib/gitea/log/xorm.log | grep -E "\[SQL\].*\([0-9]{4,}ms\)"
# 查看 HTTP 慢请求
tail -f /var/lib/gitea/log/access.log | awk '$NF > 1000'
# 分析 CPU 使用
top -p $(pgrep gitea)
# 查看网络连接
netstat -antp | grep gitea
最佳实践
1. 部署建议
- 使用反向代理:始终在 Nginx/Apache 后面运行 Gitea
- 启用 HTTPS:生产环境必须使用 SSL/TLS
- 分离数据库:使用独立的 MySQL/PostgreSQL 实例
- 使用缓存:配置 Redis 提升性能
- 定期备份:自动化备份策略,异地备份
2. 安全建议
- 最小权限原则:运行 Gitea 使用专用用户
- 强密码策略:启用密码复杂度要求
- 双因素认证:为管理员账户启用 2FA
- 定期更新:及时安装安全更新
- 审计日志:保留完整的操作日志
3. 性能建议
- SSD 存储:使用 SSD 存储仓库数据
- 充足内存:根据用户量配置足够内存
- CDN 加速:静态资源使用 CDN
- 数据库优化:定期优化数据库索引
- 监控告警:配置完善的监控系统
4. 运维建议
- 版本管理:使用稳定版本,避免频繁升级
- 变更管理:重要变更先在测试环境验证
- 文档维护:维护详细的运维文档
- 应急预案:制定故障恢复预案
- 团队培训:确保团队了解 Gitea 运维
常见问题
Q1: Gitea 无法启动
问题描述:服务启动失败,提示端口被占用或权限不足
解决方案:
# 检查端口占用
lsof -i:3000
lsof -i:22
# 检查权限
ls -la /var/lib/gitea
ls -la /etc/gitea
# 修复权限
chown -R git:git /var/lib/gitea
chown root:git /etc/gitea
chmod 770 /etc/gitea
Q2: 推送代码失败
问题描述:Git push 提示认证失败或权限不足
解决方案:
# 检查 SSH 配置
cat ~/.ssh/config
# 测试 SSH 连接
ssh -T git@git.example.com -p 2222
# 检查仓库权限
# 在 Gitea 界面检查用户权限
# 重新添加 SSH 密钥
ssh-keygen -t ed25519 -C "your_email@example.com"
# 将公钥添加到 Gitea
Q3: 数据库连接错误
问题描述:日志显示数据库连接失败
解决方案:
# 测试数据库连接
mysql -u gitea -p -h localhost
# 检查数据库服务
systemctl status mysql
# 验证配置文件
grep -A5 "\[database\]" /etc/gitea/app.ini
# 重置数据库密码
mysql -u root -p
ALTER USER 'gitea'@'localhost' IDENTIFIED BY 'new_password';
FLUSH PRIVILEGES;
Q4: 内存占用过高
问题描述:Gitea 进程占用大量内存
解决方案:
# 优化配置
[cache]
ENABLED = true
ADAPTER = memory
; 限制缓存大小
INTERVAL = 60
ITEM_TTL = 16h
[git.timeout]
; 减少 Git 操作超时
DEFAULT = 360
MIGRATE = 600
MIRROR = 300
CLONE = 300
PULL = 300
GC = 60
Q5: 仓库损坏修复
问题描述:仓库无法访问,提示损坏
解决方案:
# 进入仓库目录
cd /home/git/gitea-repositories/user/repo.git
# 检查仓库完整性
git fsck --full
# 重建索引
git update-server-info
# 垃圾回收
git gc --aggressive
# 修复权限
chown -R git:git .
相关文章
- Docker 容器化部署指南
- Nginx 反向代理配置
- MySQL 数据库优化
- Redis 缓存配置
- Git 使用指南
- Jenkins CI/CD 集成
- Let’s Encrypt SSL 证书
- 系统监控方案