Running your own Git server gives you full control over code, access permissions, and backup policies. Whether you’re protecting proprietary software or simply want an isolated environment for a small team, setting up a private Git server on Linux is a rewarding project. In this guide we’ll walk through everything you need—from installing Git to securing SSH access—so you can have a reliable, self‑hosted repository in under an hour.
What You’ll Need
- A Linux machine (Ubuntu 22.04, Debian 12, CentOS 9, or similar)
- Root or sudo privileges
- Static IP or a domain name pointing to the server
- Basic knowledge of the command line
- SSH client for remote access
Step 1: Install Git and Essential Packages
First, update your package index and install Git. On Debian‑based systems use apt, on RHEL‑based use dnf:
sudo apt update && sudo apt install -y git openssh-server ufw
For CentOS/RHEL:
sudo dnf install -y git openssh-server firewalld
Enable and start the SSH service (if it isn’t already running):
sudo systemctl enable --now sshd
Verify the installation:
git --version
You should see something like git version 2.34.1. If you get an error, double‑check that the package manager completed without issues.
Step 2: Create a Dedicated Git User
Running repositories under a dedicated account isolates permissions and reduces security risk. Create a system user called git without a login shell:
sudo adduser --system --shell /usr/bin/git-shell --group --home /home/git git
This command does three things:
- Creates a system user (UID below 1000)
- Assigns
git-shellas the login shell, which only allows Git commands - Sets
/home/gitas the home directory
Check that the user exists:
id git
If you need to add existing team members, you’ll later grant them SSH keys under this account.
Step 3: Set Up a Bare Repository
A “bare” repository contains only the version history and no working copy—perfect for a central server. Switch to the git user and create the repo:
sudo -u git -H bash -c "mkdir -p /home/git/repositories && cd /home/git/repositories && git init --bare myproject.git"
The directory myproject.git now holds the central repo. You can repeat this command for additional projects, just change the name.
Give the git user ownership of the entire repositories folder (should already be the case, but it’s good practice):
sudo chown -R git:git /home/git/repositories
Step 4: Configure SSH Access for Team Members
Each developer will push and pull over SSH. Collect each team member’s public key (the id_rsa.pub file) and place it in /home/git/.ssh/authorized_keys. You can do this manually or use the ssh-copy-id utility from the developer’s machine:
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
On the server, ensure the .ssh directory and authorized_keys have the correct permissions:
sudo -u git chmod 700 /home/git/.ssh
sudo -u git chmod 600 /home/git/.ssh/authorized_keys
Now a developer can clone the repo with a single command:
git clone [email protected]:/home/git/repositories/myproject.git
If you prefer a friendly URL, you can create a symbolic link in /var/www or configure a custom domain, but the raw SSH path works everywhere.
Step 5: Harden the Server – Firewall and SSH Settings
Security is paramount. First, allow only SSH (port 22) through the firewall and deny everything else:
# For UFW (Ubuntu/Debian)
sudo ufw allow OpenSSH
sudo ufw enable
# For firewalld (CentOS/RHEL)
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload
Next, edit /etc/ssh/sshd_config to tighten access:
sudo nano /etc/ssh/sshd_config
Make sure the following lines are present (or uncommented):
PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
AllowUsers git
Restart SSH to apply changes:
sudo systemctl restart sshd
Now only users with a valid SSH key for the git account can connect—password logins are disabled.
Step 6: Set Up Automatic Backups
Even a private server can suffer hardware failure. A simple backup strategy is to tar the repositories directory nightly and copy it to another server or cloud storage.
sudo -u git crontab -e
Add the following line (adjust the path and remote destination as needed):
0 2 * * * tar -czf /tmp/git-backup-$(date +%F).tar.gz -C /home/git/repositories . && rsync -a /tmp/git-backup-$(date +%F).tar.gz [email protected]:/backups/git/ && rm /tmp/git-backup-$(date +%F).tar.gz
This cron job creates a compressed snapshot at 2 AM, transfers it via rsync, and removes the local temporary file. Test the command manually before relying on it.
Common Mistakes to Avoid
1. **Using a regular shell for the git user** – If you forget the --shell /usr/bin/git-shell flag, users could get a normal shell and potentially alter the server.
2. **Storing private keys on the server** – Never place private keys in /home/git/.ssh; only public keys belong there.
3. **Neglecting permissions** – A mis‑set chmod 777 on the repo folder will let anyone modify history. Keep directories at 750 and files at 640.
4. **Leaving password authentication enabled** – This opens the door to brute‑force attacks. Disable it as shown above.
5. **Skipping backups** – Even a small repository can be catastrophic if lost. Schedule regular backups from day one.
Tips and Tricks
• **Use Gitolite or Gitea** if you need finer‑grained access control, web UI, or issue tracking.
• **Enable HTTP(S) access** with git-http-backend and Nginx for teams that can’t use SSH.
• **Automate user provisioning** by writing a small script that adds a key to authorized_keys and logs the action.
• **Monitor repository health** with git fsck --full on a weekly basis to catch corruption early.
Frequently Asked Questions
Can I host multiple repositories under the same git user?
Absolutely. Just create additional bare repos in /home/git/repositories (e.g., anotherproject.git) and share the corresponding SSH URL with your team.
Do I need a domain name, or is an IP address enough?
An IP works fine, but a domain makes URLs easier to remember and allows you to switch servers without updating every developer’s clone URL. Point a DNS A record to your server’s IP and use [email protected] in the clone command.
How do I change a team member’s access if they leave the project?
Remove their public key from /home/git/.ssh/authorized_keys. If you use a separate key per repository, edit the specific authorized_keys file for that repo. After removal, the user can no longer push or pull.
Conclusion
Setting up a private Git server on Linux is straightforward once you understand the building blocks: Git, a dedicated system user, SSH key authentication, and a few security hardening steps. By following this guide you’ll have a fast, secure, and maintainable central repository that scales with your team. Remember to keep your SSH keys safe, back up regularly, and revisit permissions whenever you add new projects. Happy coding!





