
Gitea 自建 Git 服务教程Docker 部署、仓库迁移与外网安全访问前言代码放在第三方平台上很省心但团队里总会遇到几类场景内网项目不想出公司家用服务器想留一份私有仓库旧项目从 GitHub 拉回来做归档或者只是想有一个轻量的 Git Web 面板。我自己更喜欢把这类工具先搭成“小而稳”的形态能创建仓库能推送代码能迁移旧项目能在需要时从外面打开面板。功能不用第一天全开链路先跑顺后面加备份、通知和团队权限才不会乱。这篇就用 Docker Compose 搭一套 Gitea。主线只做稳定、低风险的版本先跑通 Web 面板和仓库再迁移已有仓库局域网能用之后再用 cpolar 把 Gitea 的 Web 面板安全映射出去。SSH Git 操作会单独说明边界不把公网 SSH 当默认方案。图1Gitea 部署在局域网服务器中开发者通过 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这里用两个端口3000Gitea Web 面板222宿主机对外暴露的 Git SSH 端口容器内部仍然是22。如果你的服务器本来就把222给了别的服务后面 Compose 里的222:22改成别的宿主机端口比如2222:22。别改容器内部的22Gitea 容器里的 SSH 服务就是监听这个端口。图2部署前先在服务器终端确认 Docker Compose 可用并检查 3000、222 端口是否被占用。3 使用 Docker Compose 部署 Gitea先创建一个单独目录后续配置和数据都放在这里mkdir -p ~/gitea cd ~/gitea写入docker-compose.ymlcat docker-compose.yml EOF networks: gitea: external: false services: server: image: docker.gitea.com/gitea:1.26.2 container_name: gitea environment: - USER_UID1000 - USER_GID1000 - GITEA__server__SSH_PORT222 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 --tail100 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 GiteaGitea 基础 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 仓库迁移到 GiteaGitea 支持从其他 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_emailexample.comSSH clone 失败时先检查端口是不是222再检查公钥是否加到了当前登录用户下面。不要一上来就改容器配置十次里有八次是地址或 Key 填错。图8如需 SSH clone在个人设置中添加本机公钥并使用ssh://git服务器IP:222/用户名/仓库.git格式访问。8 离开局域网后用 cpolar 映射 Gitea Web 面板如果只是公司或家里局域网内使用做到上一步就够了。人在外面临时查看仓库、处理 Issue、给同事看代码页面时再考虑把 Gitea Web 面板映射出去。这里用 cpolar 映射 Gitea 的3000Web 端口。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 页面。图9Gitea 容器监听 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 端口3000SSH/TCP 只在明确需要时短时开启重要项目定期离线备份不把唯一副本只放在一台机器上。10 总结到这里一套轻量的 Gitea 自建 Git 服务已经跑起来了Docker Compose 负责部署Gitea 负责仓库管理局域网内可以 clone 和 push旧仓库也能迁移进来离开局域网时再用 cpolar 暴露 Web 面板避免一上来就把多个端口都放到公网。关键步骤可以压缩成三件事用docker compose up -d启动 Gitea并把 Web 端口固定在3000初始化管理员后先创建私有仓库再用 HTTP 或 SSH 在局域网内验证 Git 操作外网访问优先只映射 Web 面板固定入口和 TCP 访问按实际需要再开。这套方案适合个人服务器、小团队内网仓库和旧项目归档。后续要继续增强可以再加自动备份、邮件通知、组织权限、Runner 和镜像仓库但第一天先把“能访问、能推送、能迁移、能备份”跑稳后面扩展会省很多事。