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 pushfrom 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 gitInstall 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 gitoliteNext, 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
exitThis 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.pubAt 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-adminAfter 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 keysHands-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
alicesend you her SSH public key file (likealice.pub). - Add user: Copy the
alice.pubfile to your localgitolite-admin/keydir/directory. - Configure permissions: Open the
gitolite-admin/conf/gitolite.conffile 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 = adminTip: Gitolite automatically recognizes filenames in the
keydir/directory (minus the.pubsuffix) 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 pushWhen 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-appOther Settings
Migrating Existing Repositories
-
Move repositories to the
/home/git/repositoriesdirectory- 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+ = CREATORTip: 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