Host a Secure Private Git Repository on Your VPS — Step-by-Step Setup

Host a Secure Private Git Repository on Your VPS — Step-by-Step Setup

Hosting a private Git repository on your VPS gives you control over backups, access policies, and compliance. This friendly step-by-step guide walks through architecture, security hardening, and setup so you can run a secure, cost-effective self-hosted service.

Running a private Git repository on a VPS gives teams full control over code hosting, access policies, backups, and compliance. For site owners, enterprises, and developers, a self-hosted solution hosted on a reliable virtual private server can be more secure and cost-effective than third-party SaaS for sensitive projects. This article walks through the principles, common use cases, security and architecture considerations, and a detailed step-by-step setup that results in a secure, private Git service on your VPS.

Why host your own private Git repository?

Before we dive into the setup, it’s important to understand the benefits and trade-offs of self-hosting:

  • Control and compliance — You control backups, encryption policies, and where data resides, which matters for regulatory and internal compliance.
  • Cost predictability — For multiple repositories and users, a single VPS with a fixed cost can be cheaper than tiered SaaS plans.
  • Custom integrations — Easier to integrate with internal CI/CD, LDAP/AD, or on-premise tools.
  • Performance — Faster in-network clones/pushes when your VPS is in the same region as your team or CI runners.
  • Trade-offs include operational overhead (patching, monitoring, backups) and the need to secure the host properly.

Core principles and architecture

At its simplest, a Git server exposes repositories over SSH or HTTPS and enforces authentication and authorization. A robust setup includes:

  • User authentication — SSH key-based access or HTTPS with TLS client/server auth and application-level accounts.
  • Authorization — Per-repository or per-branch permissions (managed by a Git server like Gitea/GitLab or lightweight tools like Gitolite).
  • Transport security — SSH for secure connections or HTTPS with a valid TLS certificate for web/REST/API access.
  • Hardening — Firewall rules, up-to-date software, Fail2Ban, and limited user privileges.
  • Backups — Automation for repository snapshots and configuration backups.
  • Monitoring and logging — Access logs, intrusion detection, and alerting.

Typical components

  • VPS OS (Ubuntu/Debian/CentOS)
  • SSH server (OpenSSH)
  • Reverse proxy (Nginx) for HTTPS and TLS termination
  • Git service: Gitea for lightweight needs, GitLab CE for a full-featured platform, or Gitolite for SSH-only control
  • Certificate manager (Certbot for Let’s Encrypt)
  • Security tooling: UFW/iptables, Fail2Ban, automatic updates

When to choose which solution

Choose based on feature needs and VPS resources:

  • Gitea — Lightweight, fast, easy to install, low memory/CPU footprint. Good for small-to-medium teams.
  • Gitolite — Minimal and ideal for SSH-only scenarios where you need fine-grained repo permissions without a web UI.
  • GitLab CE — Full platform (issue tracking, CI/CD, container registry). Requires more RAM and CPU; suitable for teams needing built-in CI and richer features.

Step-by-step secure setup on a VPS (example with Gitea + Nginx + Let’s Encrypt)

The following walkthrough uses Ubuntu as the VPS OS and configures a secure Gitea instance accessible via HTTPS, with SSH access for Git operations. Replace domain names and user names with your values.

1) Provision and harden the VPS

Choose a VPS with enough resources (Gitea: 1 GB RAM minimum, 2+ GB recommended for multi-user). Update and secure the system:

sudo apt update && sudo apt upgrade -y

Create a non-root admin user and disable password login for root:

sudo adduser gitadmin
sudo usermod -aG sudo gitadmin

Edit /etc/ssh/sshd_config and set PermitRootLogin no and PasswordAuthentication no to enforce SSH key logins. Restart OpenSSH:

sudo systemctl restart sshd

2) Open minimal firewall ports

Use UFW to expose only necessary ports (SSH, HTTP, HTTPS):

sudo apt install ufw -y
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

3) Install Git and Gitea

Install Git and other prerequisites:

sudo apt install git sqlite3 nginx certbot python3-certbot-nginx -y

Create a dedicated git user for Gitea:

sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git

Download the latest Gitea binary and install it as a systemd service (Gitea docs provide the latest URL). Example steps (adjust to current version):

sudo -u git wget -O /home/git/gitea https://dl.gitea.io/gitea/1.XX.X/gitea-1.XX.X-linux-amd64
sudo chmod +x /home/git/gitea

Create directories and set ownership:

sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo chown -R git:git /var/lib/gitea /home/git/gitea

Create a systemd service file /etc/systemd/system/gitea.service and start the service. Ensure the service runs under the git user and listens on a local port (e.g., 3000).

4) Configure Nginx as a reverse proxy and obtain TLS cert

Create an Nginx server block for your domain (example: git.example.com) forwarding traffic to Gitea on localhost:3000. Key settings:

  • listen 80 and 443
  • proxy_set_header Host, X-Real-IP, X-Forwarded-For, X-Forwarded-Proto
  • client_max_body_size large enough for pushes (e.g., 100M)

Use Certbot to request a certificate and configure HTTPS automatically:

sudo certbot --nginx -d git.example.com

After TLS is in place, set Gitea’s ROOT_URL to https://git.example.com/ in its app.ini or setup UI so links and redirects use HTTPS.

5) Enable SSH for Git operations

Gitea can manage SSH or you can use OS-level SSH. A secure approach:

  • Keep OpenSSH running for admin SSH access on a dedicated user (e.g., gitadmin).
  • Configure Gitea to use an internal SSH server or set app.ini to allow Gitea-managed SSH keys and an internal SSH port (e.g., 2222) so repository pushes still occur over SSH but Gitea can validate keys.

Alternatively, for Gitolite-style setups, create a git system user and restrict the shell to the Git application. Ensure SSH key uploads in the web UI are validated and stored with proper permissions.

6) Secure the application and OS

  • Keep the system and Gitea binary patched. Consider automatic security updates for packages (unattended-upgrades).
  • Install and configure Fail2Ban to ban repeated failed login attempts for SSH and the Gitea login endpoint.
  • Enforce strong password policies for web accounts; prefer SSH key logins or OAuth/SSO where possible.
  • Limit access to administrative features to a small set of accounts and consider two-factor authentication (Gitea supports 2FA).
  • Run Gitea behind the Nginx reverse proxy and disable direct public access to the Gitea port by firewall rules: sudo ufw deny 3000.

7) Backups and disaster recovery

Design backups for both Git data and application state:

  • Regularly back up repository data: clone or tar /var/lib/gitea/data and the Gitea git repositories directory.
  • Back up database and custom configuration files.
  • Automate backups via cron and sync to an offsite location (another VPS, S3-compatible storage, or local NAS).
  • Test restores periodically to ensure backups are usable.

8) Monitoring and auditing

Collect logs from Gitea and the system. Integrate with a simple monitoring solution (Prometheus + Grafana or hosted monitoring) to track resource usage, disk space, and suspicious activity. Enable Gitea’s built-in logging and consider sending logs to a centralized log collector.

Additional operational tips and best practices

  • Limit repository size and set a per-repo limit. Consider Git LFS for large binary assets and host LFS objects on the VPS with controlled access.
  • Enforce branch protection and code review workflows via your Git server to reduce risk of accidental direct pushes to protected branches.
  • Use SSO (LDAP/AD/OAuth) if you have an enterprise identity provider to centralize authentication and reduce password fatigue.
  • Encrypt backups at rest and ensure transport to offsite backup targets is done over TLS or SSH.
  • Plan capacity — monitor disk growth from repository history, CI artifacts, and logs. Set alerts for disk usage thresholds.

Why a reliable VPS matters

Self-hosting requires a stable network, predictable performance, and fast recovery when incidents occur. Choosing a VPS provider with multiple datacenter locations, good network peering, and responsive support reduces operational risk. If your team is U.S.-based or requires US-hosted data, consider a provider that offers US VPS options and clear SLAs.

For example, VPS.DO provides flexible USA VPS plans that can be provisioned quickly and scaled as your repository hosting needs grow. See their USA VPS offerings here: https://vps.do/usa/

Summary

Hosting a private Git repository on your VPS gives you full control over data, security, and integrations. A secure production-ready setup should combine HTTPS (Let’s Encrypt), SSH access with key-based authentication, a hardened OS, firewall rules, Fail2Ban, regular backups, and monitoring. For most teams, Gitea strikes a strong balance of features and resource usage; larger organizations with built-in CI needs may prefer GitLab CE. Whatever stack you choose, enforce strong access controls, automate updates and backups, and test restore procedures to ensure availability and data integrity.

When selecting a VPS host, factor in geographic location, available resources, and support. Reliable VPS hosting will make managing your self-hosted Git service far easier and more secure — consider starting with a small US VPS and scaling as needed: VPS.DO USA VPS.

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!