【实战】用 Docker Compose 一键部署私有 Git 服务 Gitea,搭配 Drone CI 实现自动部署
【实战】用 Docker Compose 一键部署私有 Git 服务 Gitea,搭配 Drone CI 实现自动部署
最近在折腾自己的一个小项目,需要频繁提交代码然后部署到服务器。一开始是用 GitHub +手动 SSH,每次改完代码都要 git push → SSH 登录 → git pull → docker-compose up -d,一天重复五六次实在受不了。
需求也很明确:代码放自己服务器上、push 后自动部署。于是搭了一套 Gitea + Drone CI 的私有 DevOps 流水线。下面是完整步骤。
环境准备
服务器:Ubuntu 22.04 LTS(4C8G,50G SSD)
Docker 24.0.x + Docker Compose v2
域名:git.yourdomain.com(Gitea)、ci.yourdomain.com(Drone)
第一步:部署 Gitea
Gitea 是一个轻量级的自托管 Git 服务,Go 写的,内存占用极小,单核 512M 就能跑。
docker-compose.yml
version: ‘3’
services:
gitea:
image: gitea/gitea:1.21
container_name: gitea
restart: always
volumes:
- ./gitea/data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- “3000:3000”
- “2222:22”
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__server__DOMAIN=git.yourdomain.com
- GITEA__server__ROOT_URL=https://git.yourdomain.com
- GITEA__server__SSH_DOMAIN=git.yourdomain.com
- GITEA__server__SSH_PORT=2222
docker-compose up -d
浏览器访问 http://your-server-ip:3000,首次进入会自动跳转到安装向导,一路默认配置即可。唯一要注意的是域名和 SSH 端口填对。
第二步:配置 Nginx 反向代理
/etc/nginx/sites-available/gitea
server {
listen 443 ssl;
server_name git.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/git.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1: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;
}
}
ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/
certbot --nginx -d git.yourdomain.com
systemctl reload nginx
第三步:部署 Drone CI
Drone 是一个容器化 CI/CD 工具,和 Gitea 集成非常简单。
docker-compose.drone.yml
version: ‘3’
services:
drone-server:
image: drone/drone:2
container_name: drone-server
restart: always
ports:
- “8080:80”
volumes:
- ./drone:/data
environment:
- DRONE_GITEA_SERVER=https://git.yourdomain.com
- DRONE_GITEA_CLIENT_ID=你的OAuth应用ID
- DRONE_GITEA_CLIENT_SECRET=你的OAuth应用密钥
- DRONE_RPC_SECRET=随机生成的长字符串
- DRONE_SERVER_HOST=ci.yourdomain.com
- DRONE_SERVER_PROTO=https
drone-runner:
image: drone/drone-runner-docker:1
container_name: drone-runner
restart: always
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DRONE_RPC_PROTO=https
- DRONE_RPC_HOST=ci.yourdomain.com
- DRONE_RPC_SECRET=与上面相同的密钥
- DRONE_RUNNER_CAPACITY=2
获取 OAuth 凭证
在 Gitea 中创建 OAuth 应用:
- Gitea → 头像 → 设置 → 应用 → 创建新的 OAuth2 应用
- 应用名: Drone CI
- 重定向 URI: https://ci.yourdomain.com/login
- 复制生成的 Client ID 和 Client Secret 填入上面的 docker-compose
生成 RPC Secret
openssl rand -hex 16
Nginx 配 Drone:
server {
listen 443 ssl;
server_name ci.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/ci.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ci.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
第四步:配置 Drone Pipeline
在项目根目录创建 .drone.yml:
kind: pipeline
type: docker
name: deploy
steps:
- name: build
image: node:20-alpine
commands:- npm install
- npm run build
- name: deploy
image: appleboy/drone-ssh
settings:
host:
- your-server-ip
username: deploy
key:
from_secret: SSH_PRIVATE_KEY
script:
- cd /opt/myapp
- docker-compose down
- docker-compose up -d --build
trigger:
branch:- main
在 Drone UI 中设置 Secret(SSH_PRIVATE_KEY)后,每次 push 到 main 分支就会自动触发构建和部署。
踩坑记录
坑 1:Drone 无法连接 Gitea
症状:Drone Server 日志报 Post “https://git.yourdomain.com/api/v1/user”: dial tcp: lookup git.yourdomain.com on 127.0.0.53:53: no such host
原因:Drone 容器内 DNS 无法解析自建域名。Docker 默认 DNS 是 8.8.8.8,你的域名只有本地 Nginx 认识。
解决:给 Drone Server 添加 extra_hosts:
drone-server:
extra_hosts:
- “git.yourdomain.com:172.17.0.1” # docker0 网关
坑 2:Drone Runner 无权限访问 Docker Socket
症状:permission denied while trying to connect to the Docker daemon socket
原因:runner 容器的 UID 和宿主机 docker.sock 权限不匹配。
解决:
把 runner 镜像的 UID 加到 docker 组
sudo usermod -aG docker $USER
或者给 socket 777(不推荐生产环境)
sudo chmod 666 /var/run/docker.sock
坑 3:Gitea SSH 端口冲突
症状:宿主机的 SSH (22) 和 Gitea 容器的 SSH (22) 不能同时占用宿主机的 22 端口。
解决:映射到宿主机 2222 端口(上面的 compose 已经用了 2222),clone 时这样写:
git clone ssh://git@git.yourdomain.com:2222/username/repo.git
或者配置 ~/.ssh/config:
Host git.yourdomain.com
Port 2222
User git
坑 4:Pipeline 中 npm install 慢
解决:用国内镜像、利用 Docker 层缓存:
- name: build
image: node:20-alpine
commands:- npm config set registry https://registry.npmmirror.com
- npm install --prefer-offline
volumes: - name: cache
path: /root/.npm
总结
Gitea + Drone CI 这套组合我用了一个多月,几点感受:
轻量:Gitea + Drone 两个容器加起来不到 500M 内存,跑在 4C8G 的服务器上没压力
不要钱的 CI:Drone 开源版免费,不像 GitHub Actions 有分钟限制
10 分钟搭完:从 docker-compose up 到第一次自动部署,全程不到半小时
OAuth 集成顺畅:Gitea 创建 OAuth App → Drone 填 ID/Secret → 秒通
缺点也有:Drone 社区不如 GitHub Actions 活跃,某些插件版本比较老。不过对于小团队或个人项目来说足够用了。
如果对你有帮助,欢迎点赞收藏 👍
本文由 lotusxyhf 整理发布。所有配置均在实际环境中验证通过。
更多推荐



所有评论(0)