--- title: cgit on nginx date: 2025-09-19 --- # cgit on nginx Just some notes on enabling smart http with nginx as well as authentication on push for repos on debian13 ## install git, cgit and apache2-utils (for authentication) ```bash apt install git cgit apache2-utils fcgiwrap ``` ## create a git user ```bash adduser git su git cd mkdir .ssh && chmod 700 .ssh touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys ``` ## append ssh keys to the authorized keys file TODO: add steps ## change back to root user ```bash exit ``` ## As root, create location to store repos and change permissions ```bash mkdir -p /srv/git ln -s /srv/git /git # optional but I like it so the repos are available on /git if you're ssh cloning cd /srv chown -R git:git git/ ``` ## Configuring nginx file `/etc/nginx/git-http-backend.conf` ```ini fastcgi_pass unix:/run/fcgiwrap.socket; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; fastcgi_param GIT_HTTP_EXPORT_ALL ""; fastcgi_param GIT_PROJECT_ROOT /srv/git; fastcgi_param PATH_INFO $1; fastcgi_param REMOTE_USER $remote_user; ``` file `/etc/nginx/sites-available/git.domain.com` ```nginx server { listen 80; listen [::]:80; server_name git.domain.com www.git.domain.com; access_log /var/log/nginx/cgit-access.log; error_log /var/log/nginx/cgit-error.log debug; root /usr/share/cgit; try_files $uri @cgit; location @cgit { include fastcgi_params; fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi; fastcgi_param DOCUMENT_ROOT /usr/lib/git-core; fastcgi_pass unix:/run/fcgiwrap.socket; fastcgi_param PATH_INFO $uri; fastcgi_param QUERY_STRING $args; fastcgi_param HTTP_HOST $server_name; fastcgi_param GIT_HTTP_EXPORT_ALL ""; fastcgi_param GIT_PROJECT_ROOT /srv/git; if ($arg_service = git-receive-pack) { rewrite (/.*) /git_write/$1 last; } if ($uri ~ ^/.*/git-receive-pack$) { rewrite (/.*) /git_write/$1 last; } if ($arg_service = git-upload-pack) { rewrite (/.*) /git_read/$1 last; } if ($uri ~ ^/.*/git-upload-pack$) { rewrite (/.*) /git_read/$1 last; } } location ~ /git_read/(.*) { include git-http-backend.conf; } ## require auth to upload location ~ /git_write/(.*) { auth_basic "Pushing to Git repositories is restricted"; auth_basic_user_file /etc/nginx/htpasswd; include git-http-backend.conf; } } ``` ## enable the configuration ```bash # relative (recommended) cd /etc/nginx/sites-enabled/ ln -s ../sites-available/git.domain.com . # fullpath ln -s /etc/nginx/sites-available/git.domain.com /etc/nginx/sites-enabled/ ``` ## Create an http user (with write access) `username` is the username you want to use for auth ```bash htpasswd -c /etc/nginx/htpasswd username ``` ## configure cgit accordingly at file `/etc/cgitrc` ```ini css=/cgit.css logo=/cgit.png virtual-root=/ scan-path=/srv/git ``` ## Create your repository ```bash su git cd /srv/git mkdir myrepo.git cd myrepo.git git init --bare ``` ## As root update permissions to be able to push via http ```bash chown -R git:www-data /srv/git/ chmod -R ug+rwX /srv/git/ ``` ## To configure the git:// protocol file `/etc/systemd/system/git-daemon.service` ```ini [Unit] Description=Start Git Daemon [Service] ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/srv/git/ /srv/git/ Restart=always RestartSec=500ms StandardOutput=syslog StandardError=syslog SyslogIdentifier=git-daemon User=git Group=git [Install] WantedBy=multi-user.target ``` ## enable and start the unit ```bash systemctl enable --now git-daemon.service ``` ## You will then want to create a git-daemon-export-ok file inside all of the repos you want git-daemon to check ```bash cd /srv/git/myrepo.git/ touch git-daemon-export-ok ``` ## Finally, allow port 9418 for git:// protocol (as root) ```bash # nftables nft add rule inet filter input tcp dport 9418 accept comment "allow git daemon protocol" # or ufw ufw allow 9418 ``` --- [index](./index.md)