Building Your Own Private Git Server With Gitolite
AI generated + manually edited
Some time ago, I wrote about Building Your Private Git Server with Caddy and Containers (Git Over HTTPS). Since I had a more complex requirement—creating repositories on push—I needed a more flexible Git server, so I decided to explore Gitolite.
Why Choose Gitolite?
Among the many Git service solutions, Gitolite stands out. It’s not an “all-in-one” solution like GitLab, but rather a focused “permission manager.”
- Ultra-lightweight: It’s just a series of Perl scripts, requiring no database, no web server, with extremely low system resource consumption.
- Security: All users authenticate through SSH public keys, and they cannot gain shell access to the server.
- Fine-grained permission control: You can control who can read/write which branches of which repositories, and even prevent someone from force pushing or deleting branches.
- Managing Git with Git: All user, repository, and permission configurations are stored in a special Git repository called
gitolite-admin
. You just need togit push
from your own computer to complete all management operations. Cool, right?
Ready? Let’s get started!
Server-side Initialization
This part of the operation is all done on your server, and only needs to be done once.
Create a Dedicated git
User
For security reasons, we never use the root user to run services. Creating a dedicated git
user is a best practice.
# Create a user named 'git' and create a home directory for it
sudo useradd -m -s /bin/bash git
# If the git user already exists, use the following command to modify its home directory
# sudo mkdir -p /home/git # if the home directory doesn't exist
# sudo usermod -d /home/git -s /bin/bash git
# (Recommended) Lock the user's password, forcing all operations to go through SSH keys
sudo passwd -l git
Install Gitolite and Upload Your Admin Public Key
I use Arch Linux and install using the pacman
package manager. Please adjust the commands for other distributions. You can refer to the official documentation Quick Install.
# Update your package database and install gitolite
sudo pacman -Syu gitolite
Next, you need to set yourself as the supreme administrator of Gitolite. This is accomplished by uploading your SSH public key. There are many ways to upload files, choose according to your situation. The following example assumes the uploaded path is /tmp/admin.pub
.
Initialize Gitolite
This is the most critical step. We will use the public key we just uploaded to start the Gitolite service.
Run on your server:
# Switch to git user identity
sudo -u git -i
# Use your public key as administrator to initialize Gitolite
# Some distributions use gitolite3 instead of gitolite, please refer to the official documentation
gitolite setup -pk /tmp/admin.pub
# After seeing output similar to "Initialized...", exit the git user
exit
This command will automatically create the ~/repositories
and ~/.gitolite
directories, and configure the core gitolite-admin
management repository. Most importantly, it will take over the ~git/.ssh/authorized_keys
file. From now on, please do not manually edit this file!
Cleanup
After installation, the temporary public key file on the server is no longer needed.
sudo rm /tmp/admin.pub
At this point, the server is like a well-prepared precision machine, waiting for your commands.
Managing Everything Locally
From now on, you’ll experience the ingenious design of Gitolite. All management work is done on your own computer through Git commands.
Clone the gitolite-admin
Management Repository
This is your “central control room.”
On your local machine, find a place to clone it:
# Replace YOUR_SERVER_IP with your server's IP address
git clone git@YOUR_SERVER_IP:gitolite-admin
After successful cloning, you’ll see this clean structure:
gitolite-admin/
├── conf/
│ └── gitolite.conf # Permission and repository definition file
└── keydir/
└── admin.pub # Storage location for all users' public keys
Hands-on Practice: Adding New Users and Projects
Suppose a new team member alice
joins your team, and you’re starting an exciting new project my-awesome-app
.
- Get the public key: Have
alice
send you her SSH public key file (likealice.pub
). - Add user: Copy the
alice.pub
file to your localgitolite-admin/keydir/
directory. - Configure permissions: Open the
gitolite-admin/conf/gitolite.conf
file and add the following at the end:
# ... existing configuration ...
# Create a repository definition for the new project my-awesome-app
repo my-awesome-app
# RW+ = read, write, force push permissions
# Grant these permissions to user 'alice'
RW+ = alice
# R = read-only permission
# Administrator 'admin' has read-only permission (you can also give yourself RW+)
R = admin
Tip: Gitolite automatically recognizes filenames in the
keydir/
directory (minus the.pub
suffix) as usernames.
Commit and Push to Make Configuration Take Effect
It’s time to work the magic. In the gitolite-admin
repository directory, execute the standard Git workflow:
# Add all your changes to the staging area
git add .
# Commit with a clear commit message
git commit -m "Add user alice and create repo my-awesome-app"
# Push to the server!
git push
When you press enter, Gitolite’s hook scripts will be triggered on the server, automatically creating the my-awesome-app.git
bare repository and applying all the permission rules you just set. The entire process flows seamlessly.
Notify Your New Colleague to Get Started
Now you can tell alice
that her new project is ready. She just needs to run on her computer:
git clone git@YOUR_SERVER_IP:my-awesome-app
Other Settings
Migrating Existing Repositories
-
Move repositories to the
/home/git/repositories
directory- Ensure they are all bare repositories
- All repository names end with
.git
- All files and directories are owned and writable by git
- No symbolic links are left behind, regardless of where the files came from
-
Run the following three commands under git identity:
gitolite compile gitolite setup --hooks-only gitolite trigger POST_COMPILE
-
Edit the conf/gitolite.conf file to add new repositories to the gitolite.conf file
Allow Users to Create Repositories on Push
Edit the conf/gitolite.conf file and add the following:
repo [a-zA-Z0-9].*
C = @all
RW+ = CREATOR
Tip: You cannot use
.*
directly here, but need to use[a-zA-Z0-9].*
.
Reference Documentation
Common Issues
Podman Group Permission Issue
Reference article: Podman Rootless Trick: Using --group-add keep-groups
to Solve Volume Group Permission Issues