Gitea 自建 Git 服务教程:Docker 部署、仓库迁移与外网安全访问
围绕 Docker Compose 部署 Gitea,梳理初始化、自建仓库、迁移旧仓库、局域网访问与外网安全边界,帮助个人服务器和小团队落地私有 Git 服务。
Gitea 自建 Git 服务教程:Docker 部署、仓库迁移与外网安全访问

前言
代码放在第三方平台上很省心,但团队里总会遇到几类场景:内网项目不想出公司,家用服务器想留一份私有仓库,旧项目从 GitHub 拉回来做归档,或者只是想有一个轻量的 Git Web 面板。
我自己更喜欢把这类工具先搭成“小而稳”的形态:能创建仓库,能推送代码,能迁移旧项目,能在需要时从外面打开面板。功能不用第一天全开,链路先跑顺,后面加备份、通知和团队权限才不会乱。
这篇就用 Docker Compose 搭一套 Gitea。主线只做稳定、低风险的版本:先跑通 Web 面板和仓库,再迁移已有仓库,局域网能用之后,再用 cpolar 把 Gitea 的 Web 面板安全映射出去。SSH Git 操作会单独说明边界,不把公网 SSH 当默认方案。

图1:Gitea 部署在局域网服务器中,开发者通过 HTTP/SSH 访问;外网访问优先只通过 cpolar 映射 Web 3000 面板。
1 什么是 Gitea?这篇里它负责什么
Gitea 是一个轻量级的自建 Git 服务,界面和常见代码托管平台接近,能创建仓库、管理成员、看提交记录、提 Issue,也支持从外部 Git 服务迁移仓库。
在这篇文章里,它只负责三件事:
- 给个人或小团队提供一个私有 Git Web 面板;
- 接收本地电脑的
git push、git clone; - 把 GitHub 或已有 Git 仓库迁移进来,方便后续在内网维护。
我不建议一上来就把它做成复杂的企业代码平台。先用 Docker Compose 跑起来,确认仓库创建、推送、迁移这三件事都通,再考虑邮件、OAuth、备份策略和 CI/CD,排错会轻松很多。
2 环境准备:确认 Docker 和端口
这套教程默认服务器已经安装 Docker Engine,并且支持 Docker Compose v2。Gitea 官方 Docker 文档也按 Compose v2 作为参考方式,命令是 docker compose,不是旧版 docker-compose。
在服务器上先确认版本:
docker --version
docker compose version
再看 3000 和 222 端口是否被占用:
ss -lntp | grep -E ':3000|:222' || true
这里用两个端口:
3000:Gitea Web 面板;222:宿主机对外暴露的 Git SSH 端口,容器内部仍然是22。
如果你的服务器本来就把 222 给了别的服务,后面 Compose 里的 222:22 改成别的宿主机端口,比如 2222:22。别改容器内部的 22,Gitea 容器里的 SSH 服务就是监听这个端口。
图2:部署前先在服务器终端确认 Docker Compose 可用,并检查 3000、222 端口是否被占用。
3 使用 Docker Compose 部署 Gitea
先创建一个单独目录,后续配置和数据都放在这里:
mkdir -p ~/gitea
cd ~/gitea
写入 docker-compose.yml:
cat > docker-compose.yml <<'EOF'
networks:
gitea:
external: false
services:
server:
image: docker.gitea.com/gitea:1.26.2
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__server__SSH_PORT=222
restart: always
networks:
- gitea
volumes:
- ./gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
EOF
这里先用 SQLite,适合个人、小团队和教程场景。Gitea 官方 Docker 文档也给了 SQLite 的基础部署方式。等访问量和团队规模上来,再迁移到 MySQL 或 PostgreSQL,会比一开始就堆复杂组件更稳。
启动容器:
docker compose up -d
检查状态和日志:
docker compose ps
docker compose logs -f --tail=100 server
看到 gitea 容器处于运行状态后,打开浏览器访问:
http://服务器IP:3000
如果是在服务器本机操作,也可以访问:
http://127.0.0.1:3000
如果页面打不开,先别急着改配置。按顺序查三件事:容器是否运行、3000 端口是否监听、防火墙是否放行 3000。
docker compose ps
ss -lntp | grep ':3000'
图3:首次访问 http://服务器IP:3000 会进入 Gitea 安装页面,按需填写数据库、站点地址和管理员账号。
4 初始化管理员账号
第一次打开 Gitea 会进入安装页面。这一步不是为了填满配置,而是把数据库、站点地址和管理员账号一次性落盘。
基础场景建议这样填:
- 数据库类型:SQLite3;
- 站点标题:按团队或个人习惯填写,比如
My Gitea; - Gitea 基础 URL:局域网访问就填
http://服务器IP:3000/; - SSH 服务端口:
222; - 管理员账号:设置一个新的管理员用户名、邮箱和强密码。
这里别把管理员密码设成弱口令。Gitea 面板一旦后面开放给外网访问,弱密码就是最大风险点。
安装完成后,页面会进入 Gitea 首页。登录管理员账号,右上角能看到个人菜单,就说明 Web 面板已经跑通。
图4:管理员账号初始化完成后,进入 Gitea 首页并确认右上角用户菜单可用。
5 创建第一个仓库,并从本地推送代码
先在 Gitea 页面里点右上角加号,创建一个空仓库,比如:
demo-app
仓库先设为私有。新服务刚搭好时,我更推荐默认私有,等权限和访问方式都确认后,再按项目需要开放。
图5:创建第一个私有仓库,例如 demo-app,用于验证本地 Git 推送链路。
在本地电脑准备一个测试项目:
mkdir demo-app
cd demo-app
git init
printf '# demo-app\n' > README.md
git add README.md
git commit -m "init demo app"
如果用 HTTP 推送,远程地址格式如下:
git remote add origin http://服务器IP:3000/用户名/demo-app.git
git push -u origin main
有些本地 Git 默认分支还是 master,先看一下当前分支名:
git branch --show-current
如果显示 master,就用:
git push -u origin master
推送成功后回到 Gitea 仓库页面,能看到 README.md 和第一次提交记录。这一步不是为了测试而测试,而是确认“本地 Git → Gitea Web 仓库”这条链路已经打通。
图6:推送成功后,Gitea 仓库页面应能看到 README.md 和第一次提交记录。
6 从 GitHub 或已有 Git 仓库迁移到 Gitea
Gitea 支持从其他 Git 服务迁移仓库。对于旧项目归档、把个人仓库搬回内网,这个功能比手动 clone 再 push 更省事。
在 Gitea 页面右上角打开创建菜单,选择迁移仓库入口。按页面提示选择来源服务,填写原仓库地址。公开仓库直接填 URL;私有仓库需要填对应平台的用户名和访问令牌。
这里有个提醒:令牌只给迁移所需权限,迁移完就回到原平台删除或收回。不要拿自己的长期高权限令牌到处复用。
如果你更习惯命令行,也可以用 Git 自带的镜像方式迁移。下面以公开仓库为例:
git clone --mirror https://github.com/example/demo-app.git
cd demo-app.git
git push --mirror http://服务器IP:3000/用户名/demo-app.git
--mirror 会带上分支、标签和 refs,适合做完整迁移。目标仓库必须是你在 Gitea 里提前创建好的空仓库,别把它推到已有重要提交的仓库里。
如果推送失败,先检查三点:Gitea 目标仓库地址是否写对、本地是否已经登录或输入了正确密码、目标仓库是否有写入权限。
图7:迁移仓库时填写原仓库地址;私有仓库使用最小权限访问令牌,迁移完成后及时收回。
7 局域网访问:让团队电脑 clone 和 push
局域网里使用 Gitea,最省心的方式是先走 HTTP。团队成员在浏览器打开:
http://服务器IP:3000
登录自己的账号后,进入仓库页面复制 HTTP 克隆地址,再执行:
git clone http://服务器IP:3000/用户名/demo-app.git
如果想用 SSH,宿主机端口是前面映射出来的 222,命令要明确写端口:
git clone ssh://git@服务器IP:222/用户名/demo-app.git
划重点:这里的 git 是 Gitea SSH 服务使用的用户,不是你的 Gitea 登录用户名。你的身份由 SSH Key 绑定关系决定。
添加 SSH Key 的路径在用户个人设置里。把本机公钥复制进去:
cat ~/.ssh/id_ed25519.pub
如果本机还没有 ed25519 密钥,先生成一把:
ssh-keygen -t ed25519 -C "your_email@example.com"
SSH clone 失败时,先检查端口是不是 222,再检查公钥是否加到了当前登录用户下面。不要一上来就改容器配置,十次里有八次是地址或 Key 填错。
图8:如需 SSH clone,在个人设置中添加本机公钥,并使用 ssh://git@服务器IP:222/用户名/仓库.git 格式访问。
8 离开局域网后,用 cpolar 映射 Gitea Web 面板
如果只是公司或家里局域网内使用,做到上一步就够了。人在外面临时查看仓库、处理 Issue、给同事看代码页面时,再考虑把 Gitea Web 面板映射出去。
这里用 cpolar 映射 Gitea 的 3000 Web 端口。Linux 上安装 cpolar 的官方一键命令如下:
curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash
安装后打开本地管理面板:
http://127.0.0.1:9200
在 Web UI 登录账号后,可以创建 HTTP 隧道,本地地址填写:
3000
命令行临时测试也可以直接执行:
cpolar http 3000
启动后,在 cpolar 的在线隧道列表里复制公网 HTTP 地址,用浏览器打开就能进入 Gitea Web 页面。

图9:Gitea 容器监听 Web 3000 端口,cpolar 将本地 3000 映射为公网访问地址,适合临时查看 Web 面板。
安全边界要说清楚:这里默认只映射 Web 面板,不把 Git SSH 端口长期暴露出去。Web 面板至少要做到管理员强密码、普通成员最小权限、仓库默认私有。公网入口只是方便查看和处理仓库,不等于把整台 Git 服务器变成开放服务。
如果只是偶尔在外面改 README、看提交记录、处理一个轻量代码评审,用 Web 面板已经够了。真正需要外网 git clone 或 git push 时,再单独评估 HTTP Git 或 TCP/SSH 方案,并且限定账号权限和使用时段。
如果需要稳定访问地址,免费随机公网地址会在 24 小时内变化;固定二级子域名需要基础套餐或以上。这个适合把访问入口固定下来,比如给团队成员收藏一个固定地址。固定 TCP 地址属于更高风险的 Git SSH 场景,需要专业套餐或以上,并且要配合 SSH Key、成员权限和短时开放策略使用。
9 备份、升级和安全提醒
Gitea 的数据目录在当前部署目录下:
~/gitea/gitea
升级前先备份这个目录。最简单的做法是停容器、打包、再启动:
cd ~/gitea
docker compose down
tar -czf gitea-backup-$(date +%F).tar.gz gitea
docker compose up -d
升级 Gitea 镜像时,先修改 docker-compose.yml 里的镜像版本,再执行:
docker compose pull
docker compose up -d
别直接把 ./gitea 数据目录删掉,也别在没有备份的情况下跨多个大版本升级。Gitea 配置文件会保存在容器数据目录内,官方 Docker 文档里也说明配置文件位于 /data/gitea/conf/app.ini。
日常安全建议控制在这几条就够用:
- 仓库默认私有,按成员分配权限;
- 管理员账号使用强密码,管理员数量越少越好;
- cpolar 优先映射 Web 端口
3000,SSH/TCP 只在明确需要时短时开启; - 重要项目定期离线备份,不把唯一副本只放在一台机器上。
10 总结
到这里,一套轻量的 Gitea 自建 Git 服务已经跑起来了:Docker Compose 负责部署,Gitea 负责仓库管理,局域网内可以 clone 和 push,旧仓库也能迁移进来;离开局域网时,再用 cpolar 暴露 Web 面板,避免一上来就把多个端口都放到公网。
关键步骤可以压缩成三件事:
- 用
docker compose up -d启动 Gitea,并把 Web 端口固定在3000; - 初始化管理员后,先创建私有仓库,再用 HTTP 或 SSH 在局域网内验证 Git 操作;
- 外网访问优先只映射 Web 面板,固定入口和 TCP 访问按实际需要再开。
这套方案适合个人服务器、小团队内网仓库和旧项目归档。后续要继续增强,可以再加自动备份、邮件通知、组织权限、Runner 和镜像仓库,但第一天先把“能访问、能推送、能迁移、能备份”跑稳,后面扩展会省很多事。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)