How to Set Up a Private Git Server on a VPS with Gitea
GitHub and GitLab are excellent services — until you hit their pricing tiers, need air-gapped infrastructure, want to keep proprietary code off third-party servers, or simply prefer to own your development infrastructure. Gitea is the lightweight, open-source Git service that delivers the GitHub experience on a VPS you control: repositories, pull requests, code review, CI/CD hooks, and team management — all self-hosted.
This guide installs Gitea on Ubuntu VPS behind Nginx with SSL, configures SSH-based Git operations, and sets up team access management.
Why Gitea Over GitLab?
| Gitea | GitLab CE | |
|---|---|---|
| RAM usage | ~100–200 MB | 4–8 GB minimum |
| Setup time | ~15 minutes | 30–60 minutes |
| VPS requirement | 1 GB RAM, 1 vCPU | 4 GB+ RAM, 2+ vCPU |
| Single binary | ✅ Yes | Complex package |
| CI/CD built-in | Gitea Actions (GitHub-compatible) | GitLab CI (powerful) |
| Best for | Small teams, resource-constrained VPS | Large enterprises |
For individuals, small teams, and any VPS under 4 GB RAM, Gitea is the right choice.
💡 VPS.DO Tip: Gitea runs comfortably on VPS.DO’s entry-level plans. A 2 vCPU / 4 GB RAM VPS hosts Gitea alongside other applications easily. View Plans →
Step 1: Update System and Install Dependencies
sudo apt update && sudo apt upgrade -y
sudo apt install git nginx certbot python3-certbot-nginx sqlite3 -y
Step 2: Create a Dedicated Git User
sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' \
--group --disabled-password --home /home/git git
Step 3: Download and Install Gitea
# Get latest version number from https://github.com/go-gitea/gitea/releases
GITEA_VERSION="1.22.3"
# Download Gitea binary
sudo wget -O /usr/local/bin/gitea \
"https://github.com/go-gitea/gitea/releases/download/v${GITEA_VERSION}/gitea-${GITEA_VERSION}-linux-amd64"
# Make executable
sudo chmod +x /usr/local/bin/gitea
# Verify
gitea --version
Step 4: Create Required Directories
sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo mkdir -p /etc/gitea
sudo chown -R git:git /var/lib/gitea /etc/gitea
sudo chmod -R 750 /var/lib/gitea
sudo chmod 770 /etc/gitea
Step 5: Create Systemd Service
sudo nano /etc/systemd/system/gitea.service
[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target network.target
Wants=mariadb.service mysqld.service postgresql.service memcached.service redis.service
[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable gitea
sudo systemctl start gitea
sudo systemctl status gitea
Step 6: Configure Nginx Reverse Proxy
sudo nano /etc/nginx/sites-available/gitea
server {
listen 80;
server_name git.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Required for Git operations over HTTP
proxy_read_timeout 300s;
client_max_body_size 512M; # Allow large repository pushes
}
}
sudo ln -s /etc/nginx/sites-available/gitea /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# Add SSL
sudo certbot --nginx -d git.yourdomain.com
Step 7: Complete Gitea Web Installation
Open https://git.yourdomain.com in your browser. You’ll see the Gitea installation wizard.
Database settings
- Database Type: SQLite3 (simplest for small teams) or PostgreSQL for larger installs
- Path:
/var/lib/gitea/data/gitea.db
General settings
- Site Title: Your organization name
- Repository Root Path:
/home/git/repositories - Git LFS Root Path:
/var/lib/gitea/data/lfs - Run As Username:
git - SSH Server Domain:
git.yourdomain.com - Gitea HTTP Listen Port:
3000 - Gitea Base URL:
https://git.yourdomain.com
Administrator account
Create your admin username and password. Click Install Gitea.
✅ Gitea is now running at https://git.yourdomain.com
Step 8: Configure SSH for Git Operations
SSH-based Git (faster and more reliable than HTTPS for large repos):
On your local machine, generate and add an SSH key
ssh-keygen -t ed25519 -C "your-email@example.com" -f ~/.ssh/gitea_key
# Copy the public key
cat ~/.ssh/gitea_key.pub
Add key to Gitea
- Log in to Gitea
- Go to User Settings → SSH / GPG Keys → Add Key
- Paste your public key and save
Configure SSH client
nano ~/.ssh/config
Host git.yourdomain.com
HostName git.yourdomain.com
User git
IdentityFile ~/.ssh/gitea_key
Port 22
Test SSH connection
ssh -T git@git.yourdomain.com
# Should return: Hi username! You've successfully authenticated...
Step 9: Create Your First Repository
# Create a new repo via Gitea web UI, then:
git clone git@git.yourdomain.com:username/myproject.git
cd myproject
echo "# My Project" > README.md
git add .
git commit -m "Initial commit"
git push origin main
Or mirror an existing GitHub repository:
- Gitea → + New Repository → Migration
- Select GitHub as source
- Enter the GitHub repo URL
- Enable Mirror for automatic sync
Step 10: Set Up Teams and Organizations
Create an organization
Gitea → + → New Organization → Set name and visibility
Create teams with different permissions
| Team | Permission | Use case |
|---|---|---|
| Owners | Full admin | Founders/leads |
| Developers | Write | Core team — push and pull |
| Contributors | Read | External reviewers, view-only |
| CI/CD | Read + deploy key | Automated deployment systems |
Step 11: Set Up Gitea Actions (CI/CD)
Gitea 1.19+ includes Gitea Actions — GitHub Actions-compatible syntax, running on your VPS:
Install an Actions runner
# Download the runner
wget https://github.com/nektos/act/releases/latest/download/act_Linux_x86_64.tar.gz
tar xzf act_Linux_x86_64.tar.gz
sudo mv act /usr/local/bin/
# Register the runner in Gitea
# Gitea → Site Administration → Runners → Create Runner
# Copy the registration token, then:
sudo -u git /usr/local/bin/act_runner register \
--instance https://git.yourdomain.com \
--token REGISTRATION_TOKEN \
--name my-runner \
--no-interactive
Create a workflow file
mkdir -p .gitea/workflows
nano .gitea/workflows/test.yml
name: Run Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm test
This is identical GitHub Actions syntax — migrate workflows by changing .github/workflows/ to .gitea/workflows/.
Step 12: Automated Gitea Backups
nano ~/backup-gitea.sh
#!/bin/bash
DATE=$(date +%Y-%m-%d)
BACKUP_DIR="/var/backups/gitea"
mkdir -p $BACKUP_DIR
# Stop Gitea briefly for consistent backup
sudo systemctl stop gitea
# Backup data directory and database
tar -czf $BACKUP_DIR/gitea-data-$DATE.tar.gz /var/lib/gitea/
tar -czf $BACKUP_DIR/gitea-repos-$DATE.tar.gz /home/git/repositories/
sudo systemctl start gitea
# Remove backups older than 30 days
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
echo "Gitea backup complete: $DATE"
chmod +x ~/backup-gitea.sh
crontab -e
# 0 3 * * * /bin/bash /root/backup-gitea.sh
Final Thoughts
Gitea on a VPS gives you a complete GitHub-equivalent experience for your team — private repositories, pull requests, code review, and CI/CD — with no per-user fees, no data on third-party servers, and complete control over access and retention policies. The entire stack runs on as little as 1 GB RAM, making it one of the most cost-efficient developer tools you can self-host.