06.使用Docker-Compose快速部署轻量级私有Git服务-Gitea
1. 为什么你需要一个自己的私有Git仓库?
如果你写过代码,那你肯定用过Git。GitHub、GitLab这些平台大家都很熟悉,但它们都是“别人家”的。你有没有想过,自己动手搭一个完全属于自己、或者属于小团队的代码仓库?这听起来可能有点技术门槛,但今天我要告诉你,用Docker-Compose来部署Gitea,这件事简单得就像搭积木。
我自己最早也是把代码一股脑全扔在GitHub上。后来遇到几个挺实际的问题:有时候网络连接不稳定,提交个代码要等半天;有些项目涉及一些内部工具或者未成形的想法,暂时不想公开,但GitHub的私有仓库名额有限(虽然现在免费了,但早期可不是这样)。更重要的是,当你和几个小伙伴一起捣鼓一个项目,需要一个私密、稳定、完全可控的协作空间时,一个自建的私有仓库就成了刚需。
市面上能自建的开源Git服务不少,最出名的是GitLab。它功能确实强大,CI/CD、项目管理一套全齐,但它是典型的“重量级选手”。官方推荐的最低配置就要4核4G内存,对个人开发者或者小团队来说,为了一个代码仓库占用这么多资源,实在有点“杀鸡用牛刀”。而且它的界面和配置相对复杂,维护起来也需要不少精力。
这时候,轻量级的替代品就进入了视野,主要是Gogs和Gitea。它们俩都源自同一个想法:做一个足够用、又极其轻便的Git服务。Gogs出现得更早,以极简和易部署著称。而Gitea是从Gogs项目分叉(Fork)出来的,社区更活跃,发展更快,在功能迭代和安全性更新上更有优势。简单来说,你可以把Gitea看作是Gogs的一个更活跃、功能更现代的“社区增强版”。它用Go语言编写,打包成一个独立的二进制文件,对系统资源消耗极小,在树莓派上都能流畅运行,这正好切中了我们个人开发者“资源敏感”的痛点。
所以,当你需要的是一个私密、可控、部署简单、不吃资源的代码托管服务时,Gitea配合Docker-Compose,就成了一个近乎完美的解决方案。接下来,我就带你一步步亲手把它搭起来。
2. 部署前,你需要准备好这些“食材”
在开始“烹饪”我们的私有Git服务大餐之前,得先把厨房和食材准备好。整个过程其实就依赖两样核心工具:Docker和Docker-Compose。别被名字吓到,你可以把它们理解为一个超级高效的“应用打包和运行工具箱”。
Docker 就像是集装箱。以前运输货物,东西形状大小不一,装卸起来非常麻烦。集装箱出现后,把所有货物都打包进标准箱里,船、火车、卡车都只负责运输集装箱,效率大大提升。Docker做的也是类似的事,它把应用程序和它需要的所有环境(比如特定的系统库、依赖软件)一起打包成一个“镜像”。这个镜像在任何安装了Docker的机器上,都能以完全一致的方式运行起来,彻底解决了“在我电脑上好好的,怎么到你那就挂了”的千古难题。
Docker-Compose 则是管理多个集装箱的吊车和编排图。我们的Gitea服务不仅仅需要Gitea本身这个“集装箱”,还需要一个数据库(比如PostgreSQL)作为另一个“集装箱”来存储用户、仓库等数据。Docker-Compose允许我们用一个简单的配置文件(docker-compose.yml),一次性定义好这两个“集装箱”怎么启动、怎么连接、数据存哪里。之后一条命令,就能让整个服务栈井然有序地跑起来。
对于你的服务器环境,要求非常低:
- 操作系统:任何主流的Linux发行版(如Ubuntu、CentOS、Debian)都可以,macOS和Windows也行,但生产环境建议用Linux。
- 内存:1GB RAM就足以流畅运行,512MB也能启动,但体验会打折扣。
- CPU:1核就够用。
- 磁盘空间:至少预留10GB,用于存放Docker镜像、Gitea代码仓库和数据库数据。
我强烈建议你使用一台干净的Linux服务器(可以是云服务器,也可以是家里的旧电脑装的Linux),从头开始操作。接下来,我们首先安装Docker和Docker-Compose。
2.1 安装Docker引擎
我们以最常见的Ubuntu系统为例。打开你的终端(SSH连接到你的服务器),执行下面的命令。
首先,更新系统软件包列表并安装一些必要的工具:
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
然后,添加Docker的官方GPG密钥和软件源:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
再次更新,并安装Docker引擎:
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
安装完成后,启动Docker服务并设置开机自启:
sudo systemctl start docker
sudo systemctl enable docker
为了不用每次都输入sudo来执行docker命令(这涉及到用户组权限,是出于安全考虑),我们可以将当前用户加入docker用户组:
sudo usermod -aG docker $USER
注意:执行这条命令后,你需要完全退出当前终端会话(关闭窗口或输入exit命令),然后重新登录,这个改动才会生效。重新登录后,运行docker version命令,如果能看到Client和Server的版本信息,就说明安装成功了。
2.2 安装Docker-Compose
Docker-Compose现在通常作为一个独立的二进制文件提供,安装起来比Docker还简单。我们直接去GitHub下载最新稳定版。
首先,检查一下最新版本的编号。你可以访问 Docker Compose的GitHub发布页 查看,或者用下面的命令获取(以写作时的最新稳定版v2.24.5为例):
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
下载完成后,赋予它可执行权限:
sudo chmod +x /usr/local/bin/docker-compose
最后,验证安装是否成功:
docker-compose --version
如果输出了类似 Docker Compose version v2.24.5 的信息,那么恭喜你,所有“厨具”都已备齐。
3. 编写“食谱”:详解Docker-Compose配置文件
食材厨具都齐了,现在我们来写“食谱”,也就是docker-compose.yml文件。这个文件定义了整个Gitea服务栈的蓝图:用什么镜像、怎么配置、数据存哪、网络怎么连。我会逐行解释,让你不仅知其然,更知其所以然。
首先,我们创建一个专属的目录来存放所有相关文件,这样管理起来清晰:
mkdir -p /docker/gitea
cd /docker/gitea
在这个目录下,我们创建三个子目录,分别用于映射容器内的数据、配置和数据库文件。这样做的好处是,即使以后我们删除或重建容器,这些持久化的数据也不会丢失。
mkdir data config postgres
现在,创建并编辑核心的docker-compose.yml文件:
nano docker-compose.yml
(如果你习惯用vim,把nano换成vim即可。)
将以下内容复制进去,我会在关键位置加上注释:
version: "3.8" # 使用较新的Compose文件格式版本,兼容性更好
services:
# 定义Gitea服务
server:
image: gitea/gitea:1.21.4-rootless # 使用rootless镜像,安全性更高
container_name: gitea-server # 给容器起个名字,方便管理
environment:
- USER_UID=1000 # 容器内运行Gitea的用户UID,与宿主机用户对应可避免权限问题
- USER_GID=1000 # 容器内运行Gitea的用户组GID
- GITEA__database__DB_TYPE=postgres # 指定数据库类型为PostgreSQL
- GITEA__database__HOST=db:5432 # 数据库地址,`db`是下面定义的数据库服务名,容器内会自动解析
- GITEA__database__NAME=gitea # 数据库名称
- GITEA__database__USER=gitea # 数据库用户名
- GITEA__database__PASSWD=gitea # 数据库密码(生产环境请务必修改为强密码!)
restart: unless-stopped # 容器退出时总是重启,除非手动停止
volumes:
- ./data:/var/lib/gitea # 将Gitea的数据目录(仓库、附件等)映射到宿主机的`./data`
- ./config:/etc/gitea # 将Gitea的配置文件目录映射到宿主机的`./config`
- /etc/timezone:/etc/timezone:ro # 同步宿主机时区,只读
- /etc/localtime:/etc/localtime:ro # 同步宿主机本地时间,只读
ports:
- "3000:3000" # 将容器内的3000端口(Gitea的HTTP端口)映射到宿主机的3000端口
- "2222:22" # 将容器内的22端口(SSH端口)映射到宿主机的2222端口。注意容器内是22,映射出来是2222,避免与宿主机SSH冲突。
depends_on:
- db # 声明依赖,确保`db`服务先启动
networks:
- gitea-network # 将服务接入自定义网络,方便内部通信
# 定义PostgreSQL数据库服务
db:
image: postgres:14-alpine # 使用Alpine版本的PostgreSQL,更轻量
container_name: gitea-db
restart: unless-stopped
environment:
- POSTGRES_USER=gitea # 数据库超级用户(与上面Gitea配置对应)
- POSTGRES_PASSWORD=gitea # 数据库超级用户密码(同上,务必修改!)
- POSTGRES_DB=gitea # 初始创建的数据库名
volumes:
- ./postgres:/var/lib/postgresql/data # 将数据库数据文件映射到宿主机的`./postgres`
networks:
- gitea-network
# 定义一个自定义的Docker网络,让两个服务在独立的网络空间内通信
networks:
gitea-network:
driver: bridge
几个关键点解释和避坑指南:
- 镜像标签:我们使用了
:1.21.4-rootless这个标签。rootless意味着容器内的进程不以root权限运行,提升了安全性。使用固定版本号(如1.21.4)而非latest,可以确保部署的一致性,避免因自动升级导致意外问题。 - 端口映射:
ports部分很重要。3000:3000意味着你通过浏览器访问服务器的3000端口就能打开Gitea网页。2222:22意味着Git的SSH克隆地址端口是2222。例如,如果你的服务器IP是192.168.1.100,那么克隆仓库的地址就是ssh://git@192.168.1.100:2222/用户名/仓库名.git。务必确保宿主机的3000和2222端口没有被其他程序占用。 - 数据持久化:
volumes映射是数据的生命线。./data、./config、./postgres这三个目录就在我们刚才创建的/docker/gitea下面。所有用户代码、配置、数据库信息都保存在这里。定期备份这个/docker/gitea目录,就等于备份了你的整个Gitea服务。 - 环境变量:数据库密码等敏感信息直接写在文件里。对于更正式的环境,建议使用Docker的
secrets功能或外部环境变量文件来管理。 - 权限问题:配置文件里我们通过
USER_UID和USER_GID指定了容器内运行用户的ID。你需要确认宿主机上/docker/gitea/data和/docker/gitea/config目录的所属用户和组ID。通常,如果宿主机当前用户的UID是1000,那么直接运行sudo chown -R 1000:1000 /docker/gitea/data /docker/gitea/config来设置所有权。如果启动容器后遇到权限错误,可以查看容器日志 (docker-compose logs server) 来排查。
4. 一键启动与初始化配置
配置文件写好保存后,激动人心的时刻就到了:启动服务。整个过程简单得超乎想象。
确保你的终端当前位于/docker/gitea目录下,然后执行:
docker-compose up -d
这个-d参数代表“detached”,即让服务在后台运行。执行后,你会看到Docker开始拉取gitea和postgres镜像,然后创建网络、启动容器。
稍等片刻,使用以下命令查看服务状态:
docker-compose ps
如果看到两个服务的状态都是 Up,那就说明启动成功了。如果状态是 Exit 或者一直在 Restarting,可以用 docker-compose logs(查看所有日志)或 docker-compose logs server(只看Gitea日志)来排查错误,最常见的就是端口冲突或目录权限问题。
启动成功后,打开你的浏览器,访问 http://你的服务器IP地址:3000。比如你的服务器内网IP是192.168.1.100,那就访问 http://192.168.1.100:3000。
第一次访问,你会进入Gitea的安装引导页面。因为我们在docker-compose.yml里已经配置了数据库连接信息,所以页面上“数据库设置”部分应该是自动填好的,不需要改动。你需要重点关注的是下面这几项:
- 站点名称:给你的Git服务起个名字,比如“小明的代码库”或“TeamDev”。
- 服务器域名:填写你的服务器IP地址,或者你为它准备的域名(例如
git.yourcompany.com)。这里非常重要,它会影响仓库的克隆地址。如果你在内网用IP访问,就填IP(如192.168.1.100);如果有公网IP或域名,就填对应的地址。 - 基础URL:这个会根据你上面填的“服务器域名”和端口自动生成,格式是
http://服务器域名:3000/。确保它正确无误。 - 可选设置 - 管理员帐号设置:强烈建议在这里设置一个管理员账号和密码。如果不设,第一个注册的普通用户会自动成为管理员。
- 可选设置 - 电子邮件设置:如果你希望Gitea能发送注册确认、密码重置等邮件,需要在这里配置SMTP服务器信息。对于个人测试或内网使用,可以先跳过。
检查无误后,点击页面最下方的“安装Gitea”按钮。系统会进行初始化,这个过程大概十几秒到一分钟。完成后,页面会自动跳转到Gitea的登录页。
用你刚才设置的管理员账号登录,一个崭新的、完全由你掌控的私有Git服务就出现在眼前了!它的界面和操作逻辑与GitHub、GitLab非常相似,创建仓库、提交代码、发起Pull Request、管理组织,该有的功能一个不少,但运行在你自己的服务器上,数据完全私有。
5. 日常使用与管理进阶技巧
成功登录后,你就可以像使用GitHub一样使用Gitea了。点击右上角的“+”号可以创建新仓库,在仓库页面可以找到HTTP和SSH两种克隆地址。这里我分享几个在实际使用中非常实用的进阶技巧和配置。
5.1 配置SSH克隆(提升体验的关键)
在安装页面,我们把容器的22端口映射到了宿主机的2222端口。这意味着Git over SSH的地址会包含:2222。为了让git clone命令更简洁,我们可以配置本地的SSH客户端。
在你的本地电脑(不是服务器)上,编辑SSH配置文件 ~/.ssh/config(如果没有就创建一个):
Host your-gitea-server # 给服务器起个别名,比如 `mygit`
HostName 192.168.1.100 # 你的Gitea服务器IP或域名
Port 2222 # 映射的SSH端口
User git # Gitea服务的固定SSH用户,永远是`git`
保存后,你就可以用非常简洁的方式克隆仓库了。假设你在Gitea上创建了一个叫 myproject 的仓库,克隆命令将是:
git clone mygit:yourusername/myproject.git
系统会自动使用你配置的HostName和Port,体验上和克隆GitHub仓库 (git clone git@github.com:...) 几乎无差。
5.2 修改Gitea的配置文件
Gitea的所有配置最终都保存在我们之前映射的 config 目录下的 app.ini 文件里。网页管理后台可以修改大部分常用设置,但更深入的定制需要直接编辑这个文件。
例如,你想关闭开放注册,只允许管理员创建用户:
- 用编辑器打开服务器上的
/docker/gitea/config/app.ini。 - 找到
[service]部分,将DISABLE_REGISTRATION的值改为true。 - 保存文件,然后回到
/docker/gitea目录,重启Gitea服务使配置生效:docker-compose restart server
再比如,你觉得默认的3000端口不够“专业”,想改用80端口(HTTP默认端口):
- 首先,修改
docker-compose.yml文件中server服务的端口映射,将- "3000:3000"改为- "80:3000"。注意:在Linux上,使用1024以下的端口(如80)需要root权限,Docker默认可能需要sudo,或者调整Docker守护进程的配置。更常见的做法是先用3000端口,然后用Nginx反向代理到80端口,这样更安全、灵活。 - 同时,修改
app.ini中[server]部分的ROOT_URL,将:3000去掉,变成http://你的域名/。 - 保存两个文件,然后重启服务:
docker-compose down然后docker-compose up -d。
5.3 数据的备份与迁移
因为你所有的数据(代码仓库、数据库、配置)都保存在宿主机的 /docker/gitea 目录下,所以备份极其简单。
完整备份:直接打包整个目录即可。
tar -czvf gitea-backup-$(date +%Y%m%d).tar.gz /docker/gitea
这个压缩包包含了全部数据。要迁移到新服务器,只需要在新服务器上安装好Docker和Docker-Compose,解压这个包,然后运行 docker-compose up -d,服务就会原样恢复。
Gitea内置备份:Gitea也提供了命令行工具进行热备份,备份文件更小,且可以定时任务。 首先,进入Gitea容器内部:
docker-compose exec server bash
然后在容器内执行备份命令(假设备份到容器内的 /tmp):
su git -c "/usr/local/bin/gitea dump -c /etc/gitea/app.ini --file /tmp/gitea-dump.zip"
退出容器后,将备份文件复制到宿主机:
docker-compose cp server:/tmp/gitea-dump.zip ./
你可以写一个脚本,结合cron定时任务,定期执行这个备份流程,并将备份文件上传到云存储,实现自动化异地备份。
5.4 使用Nginx反向代理并配置HTTPS(让服务更专业)
直接通过IP:3000访问不够美观,也不安全。我们可以用Nginx作为反向代理,并配置SSL证书启用HTTPS。
首先,在宿主机上安装Nginx(假设是Ubuntu):
sudo apt install -y nginx
然后,为你的Gitea服务创建一个Nginx配置文件,例如 /etc/nginx/sites-available/gitea:
server {
listen 80;
server_name git.yourdomain.com; # 你的域名
# 将HTTP请求重定向到HTTPS(配置好SSL后启用)
# return 301 https://$server_name$request_uri;
location / {
proxy_pass http://127.0.0.1:3000; # 指向Gitea服务
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;
client_max_body_size 100M; # 允许上传大文件
}
}
创建一个符号链接启用该配置,并测试Nginx配置:
sudo ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
现在,你就可以通过 http://git.yourdomain.com 访问Gitea了。
配置HTTPS:强烈建议使用Let‘s Encrypt的免费证书。安装Certbot工具可以自动化完成证书申请和Nginx配置更新,命令类似 sudo certbot --nginx -d git.yourdomain.com。配置完成后,记得将上面Nginx配置中的HTTP重定向注释去掉,并修改Gitea的app.ini中ROOT_URL为https://git.yourdomain.com。
6. 故障排查与性能优化指南
即使按照步骤操作,也可能会遇到一些小问题。这里汇总几个我踩过的坑和解决方案。
问题一:访问页面显示“502 Bad Gateway”或连接被拒绝。
- 可能原因1:容器没启动。 运行
docker-compose ps检查状态。如果是Exit,运行docker-compose logs server查看具体错误日志。最常见的是端口冲突,换一个宿主机端口试试。 - 可能原因2:目录权限错误。 查看日志中是否有“permission denied”字样。确保
data和config目录的所属用户/组与容器内运行的UID/GID(默认为1000:1000)一致。用ls -la /docker/gitea查看,并用sudo chown -R 1000:1000 /docker/gitea/data /docker/gitea/config修正。
问题二:能打开页面,但注册或登录时提示数据库错误。
- 可能原因:数据库服务启动失败或连接配置错误。 运行
docker-compose logs db查看数据库日志。检查docker-compose.yml中数据库的环境变量(用户名、密码、数据库名)是否与app.ini或安装页面中的配置完全一致。确保depends_on设置正确,给数据库一点初始化时间。
问题三:Git克隆或推送速度慢。
- 优化方向1:服务器资源。 确保服务器有足够的内存和CPU。对于超过100个仓库或活跃团队,考虑将数据库(PostgreSQL)单独部署到性能更好的机器上。
- 优化方向2:Gitea配置。 编辑
app.ini,在[repository]部分可以设置DISABLE_HTTP_GIT = false来强制使用HTTP协议进行Git操作(在某些网络环境下可能更快)。但SSH协议通常更安全高效。 - 优化方向3:启用Gitea的缓存。 在
app.ini中配置[cache]和[session]部分,使用Redis或memcached作为缓存后端,可以显著提升页面加载速度,特别是当用户和仓库数量增多时。这需要额外部署一个Redis容器并在配置中连接它。
问题四:如何升级Gitea版本? 升级非常简单,得益于Docker的封装。
- 备份! 执行前面提到的完整备份命令。
- 修改
docker-compose.yml文件中server服务的image标签,指向新的版本号,例如gitea/gitea:1.21.5-rootless。 - 在
/docker/gitea目录下执行:docker-compose pull # 拉取新版本镜像 docker-compose up -d # 重新创建并启动容器,数据卷会自动挂载 - 访问Web界面,Gitea通常会提示正在进行数据库迁移,等待其自动完成即可。
整个过程,从准备环境到完成部署,如果网络顺畅,半小时内绝对可以搞定。最关键的是,你收获的不仅仅是一个工具,而是一个完全受控、可定制、能随着你需求成长的开发基础设施。当你的项目代码在这个自己搭建的小天地里顺畅地流转时,那种成就感和掌控感,是使用任何第三方服务都无法替代的。
更多推荐
所有评论(0)