Nginx 本身不支持 Git 协议,也不能直接运行 Git 服务;但可通过反向代理或配合 git-http-backend 等后端实现基于 HTTP(S) 的私有仓库托管,纯静态托管不可行。

直接说结论:Nginx 本身不支持 Git 协议(如 git:// 或 ssh://),也不能直接运行 Git 服务;但你可以用 Nginx 做反向代理或静态文件网关,配合 Git 的 HTTP(S) 协议裸仓库(bare repo) 实现基于端口的私有仓库托管——前提是后端有 Git HTTP 后端服务(如 git-http-backend)或轻量工具(如 cgit、gitweb、gitea、gitlab 等)。纯靠 Nginx “静态托管” Git 仓库是行不通的,因为 Git clone/push 需要 CGI/FCGI 动态交互。
为什么不能只用 Nginx 静态托管 Git 仓库
Nginx 是 Web 服务器,不是 Git 服务进程。Git 的 HTTP 协议(Smart HTTP)依赖 git-http-backend(来自 Git 源码的 CGI 程序)处理 GET /repo.git/info/refs?service=git-upload-pack 这类动态请求。若你只是把 .git 目录放在 /var/www 下让 Nginx 直接暴露,用户访问会看到目录列表或 403/404,git clone http://... 必然失败。
正确方案:Nginx + git-http-backend(CGI 方式)
这是最贴近“轻量私有 Git 托管”的原生方案,无需数据库或额外服务,适合小团队或 CI/CD 辅助场景。
-
前提:系统已安装 Git(含
git-http-backend),并启用 Perl/FCGI 支持(Ubuntu/Debian 默认带fcgiwrap) -
准备裸仓库:在
/srv/git/myproject.git初始化裸库:git init --bare /srv/git/myproject.git,确保 Nginx 用户(如www-data)有读写权限 -
配置 fcgiwrap(以 systemd 为例):
sudo systemctl enable --now fcgiwrap.socket - Nginx server 块监听指定端口(如 8080):
server {
listen 8080;
server_name _;
<pre class="brush:php;toolbar:false;">root /srv/git;
autoindex off;
# 允许 .git 目录被访问(但禁止列出)
location ~ /\.git {
deny all;
}
# Git HTTP 后端路由
location ~ ^/(?<repo>[^/]+\.git)(/.*)?$ {
fastcgi_pass 127.0.0.1:9001; # fcgiwrap 默认端口
fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
fastcgi_param PATH_INFO $uri;
fastcgi_param GIT_PROJECT_ROOT /srv/git;
fastcgi_param GIT_HTTP_EXPORT_ALL "";
fastcgi_param REMOTE_USER $remote_user;
include fastcgi_params;
}</repo>
}
重启 Nginx 和 fcgiwrap 后,即可通过 git clone http://localhost:8080/myproject.git 使用。
简化替代:用 Gitea(单二进制,自带 Web 服务)+ Nginx 反向代理
如果追求开箱即用和权限管理,推荐 Gitea(比 GitLab 轻量得多):
- 下载 Gitea 二进制,运行在本地端口(如
./gitea web -p 3000) - Nginx 配置反向代理到该端口,并绑定自定义端口(如 8443):
server {
listen 8443 ssl;
server_name _;
<pre class="brush:php;toolbar:false;">ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.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;
}
}
Gitea 自动提供 Git HTTP/SSH、Web UI、权限控制、Webhook,比手搭 git-http-backend 更实用稳定。
安全与权限关键提醒
无论哪种方式,都必须注意:
-
禁止未授权 push:git-http-backend 默认只读;如需 push,需配合 HTTP Basic Auth(用
auth_basic+auth_basic_user_file)或外部认证(如 LDAP) -
仓库路径隔离:不要把所有
.git放在 Web 可遍历路径下;用GIT_PROJECT_ROOT严格限定根目录 -
避免泄露敏感文件:确保
.git/config、.git/HEAD等不被直接 GET 到;Nginx 的location ~ /\.git拦截必须生效 - 端口选择建议:非标准端口(如 8080、8443)可减少扫描风险,但不能替代认证和防火墙规则
不复杂但容易忽略:Git HTTP 托管本质是「Web 接口 + Git 后端进程」协作,Nginx 只是前端管道。选对后端,配对好权限,端口只是表象。










