使用 Caddy 和 Docker 轻松搭建你的私有 Git 服务器 (Git Over HTTPS)
AI 生成 + 人工编辑,文章中省略了一些有关 Docker/Podman 的基础知识
想拥有一个像 GitHub 一样通过 HTTPS 访问的私有 Git 服务器,但又不想部署 GitLab 或 Gitea 这样功能强大但相对复杂的系统?本文将向你展示如何利用 Caddy2 和 Docker,以一种极其轻量、高效且安全的方式,在几分钟内快速搭建属于你自己的 Git 服务。
最终效果
- 轻量高效: 基于 Caddy 和原生 Git,资源占用极低。
- 自动 HTTPS: Caddy 自动管理 TLS 证书,所有传输都加密。
- 简单认证: 使用 Caddy 内置的
basic_auth
实现用户名/密码保护。 - 数据持久化: Git 仓库和 Caddy 证书都通过 Docker Volume 持久化,确保数据安全。
- 易于维护: 所有组件打包在 Docker 中,一键启停,轻松迁移。
准备工作
在开始之前,请确保你已具备:
- 一台安装了
Docker
和Docker Compose
(或Podman
)的服务器。 - 一个解析到你服务器 IP 的域名(例如
git.your-domain.com
)。 - 服务器的 80 和 443 端口已开放,用于 Caddy 申请证书和提供 HTTPS 服务。
目录结构
为了方便管理,我们先创建如下的目录和文件结构:
/my-caddy-git-server
├── Caddyfile
├── compose.yml
├── custom-dockerfile/
│ └── Dockerfile
├── git-repos/
│ └── (Git 仓库将存放在这里)
└── caddy_data/
└── (Caddy 的证书和状态将存放在这里)
第一步:构建带 caddy-cgi
插件的 Caddy 镜像
我们需要一个包含 caddy-cgi
插件的自定义 Caddy 镜像,以便让 Caddy 能够执行 git-http-backend
程序。
在 custom-dockerfile/Dockerfile
文件中写入以下内容:
# 阶段 1: Builder - 仅用于编译带有插件的 Caddy
FROM caddy:2-builder AS builder
# 使用 xcaddy 构建一个带 cgi 插件的 Caddy
# caddy-cgi 插件让 Caddy 可以作为 CGI 网关
RUN xcaddy build \
--with github.com/aksdb/caddy-cgi/v2
# 阶段 2: 最终运行镜像
FROM caddy:latest
# 在最终镜像中安装 git-daemon,这样运行环境中才会有 git-http-backend
RUN apk update && apk add --no-cache git git-daemon
# 从 builder 阶段复制我们刚刚编译好的、带插件的 caddy 二进制文件
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
这个 Dockerfile 使用多阶段构建,最终镜像只包含必要的 git-daemon
和带插件的 caddy
,非常精简。
第二步:配置 Caddyfile
Caddyfile
是 Caddy 的配置文件,我们用它来定义 Git 服务的行为。
在项目根目录的 Caddyfile
中写入以下内容:
# 你的 Git 服务域名
git.your-domain.com {
# 启用基础认证保护整个服务
basic_auth {
# 使用 `caddy hash-password` 命令生成你的密码哈希
# 将 "your_username" 替换为你的用户名
# 将 "$2a$14$..." 替换为生成的哈希密码
your_username $2a$14$ABC...
}
# 将所有请求路由到 git-http-backend
# 在 Alpine 镜像中,git-http-backend 的路径通常是这个
cgi * /usr/libexec/git-core/git-http-backend {
# 关键:设置环境变量,告诉 Git 后端如何工作
# GIT_PROJECT_ROOT: Git 仓库的根目录,必须与 compose.yml 中的挂载路径一致
# GIT_HTTP_EXPORT_ALL: 允许客户端发现所有仓库,无需额外配置
env GIT_PROJECT_ROOT=/git-repos GIT_HTTP_EXPORT_ALL=1
}
}
第三步:编写 Docker Compose 文件
compose.yml
文件将所有部分(自定义镜像、配置文件、数据卷)串联起来。
在项目根目录的 compose.yml
中写入以下内容:
name: git-server
services:
git-server:
# 指定使用我们自定义的 Dockerfile 进行构建
build: ./custom-dockerfile
restart: unless-stopped
ports:
# 映射 HTTPS 和 HTTP 端口
- "443:443"
- "80:80"
volumes:
# 挂载 Caddyfile
- ./Caddyfile:/etc/caddy/Caddyfile
# 挂载存放 Git 仓库的目录
- ./git-repos:/git-repos
# 挂载 Caddy 数据卷,用于持久化 TLS 证书
- ./caddy_data:/data
Podman
用户提示:Podman
同样可以很好地支持 compose.yml
文件。
第四步:启动服务并创建仓库
-
启动服务 在
my-caddy-git-server
目录下,运行以下命令启动服务:docker-compose up -d
Docker Compose 会自动构建镜像、创建并启动容器。Caddy 会为你的域名申请并配置好 HTTPS 证书。
-
创建你的第一个仓库 服务启动后,在宿主机的
git-repos
目录下创建你的第一个裸仓库(Bare Repository)。# 进入存放仓库的目录 cd git-repos # 创建一个名为 my-project.git 的裸仓库 git init --bare my-project.git
-
(可选)迁移现有仓库 如果你想从 GitHub 或其他地方迁移一个仓库,可以使用
--mirror
选项。# 这会在当前目录创建一个 my-awesome-project.git 的镜像裸仓库 git clone --mirror https://github.com/someuser/my-awesome-project.git
第五步:克隆与推送
一切就绪!现在,你可以在任何机器上通过 HTTPS 访问你的 Git 仓库了。Clone URL 的格式为 https://<你的域名>/<仓库名>.git
。
克隆仓库:
git clone https://git.your-domain.com/my-project.git
Git 会提示你输入在 Caddyfile
中配置的用户名和密码。验证通过后,仓库就会被成功克隆。
推送更新:
cd my-project
echo "Hello, private Git server!" > README.md
git add .
git commit -m "Initial commit"
git push origin main
同样,输入凭证后,你的代码就会被安全地推送到私有服务器上。
总结
通过 Caddy 和 Docker,我们用极简的配置就实现了一个功能完善、安全可靠的私有 Git 服务器。相较于 GitLab/Gitea 等方案,它资源占用极小、维护成本低,并且能享受 Caddy 带来的自动 HTTPS 的便利。希望这篇教程能帮助你轻松掌控自己的代码。
附:关于 Git Over SSH
本文专注于 Git over HTTPS。如果你更喜欢使用 SSH,其实并不需要 Caddy 或 Docker。
你只需要在你的服务器上有一个标准的用户账户,并在该服务器上安装了 Git。然后:
- 在服务器上创建一个裸仓库 (
git init --bare my-repo.git
)。 - 确保你的 SSH 公钥在服务器用户的
~/.ssh/authorized_keys
文件中。 - 使用 SSH 协议进行克隆:
git clone user@your-domain.com:/path/to/my-repo.git
。
这种方式依赖于系统的 SSH 服务,与本文描述的 HTTPS 服务是完全独立的。