GitHub is convenient, but convenience comes with tradeoffs. Microsoft (which acquired GitHub in 2018) can read every repository you store there, including private ones. Your code, commit history, and collaboration patterns are all data points on a platform whose business model includes data licensing agreements. For privacy-conscious developers, Gitea offers a compelling alternative: a full-featured, lightweight Git hosting platform you run on your own infrastructure.
Why Gitea Over GitHub?
GitHub concerns for privacy users:
- Microsoft has access to all repository content, including private repos
- Copilot training on public code (opt-out available but policy-dependent)
- Activity data (commit times, collaboration graphs) feeds platform analytics
- Account requires a phone number for some features
- US-based servers subject to US legal process
Gitea advantages:
- Runs entirely on your hardware or VPS
- No third-party access to your code
- Full control over access, backup, and data retention
- Lightweight: runs comfortably on a $5/month VPS
- Active open-source development with a large community
- Compatible with standard Git workflows — push/pull URLs just change
Prerequisites
- A Linux server or VPS (Ubuntu 22.04 or Debian 12 recommended)
- Docker and Docker Compose installed
- A domain name pointed at your server (optional but recommended)
- SSH access to the server
Step 1: Install Docker and Docker Compose
# Update package index
sudo apt update
# Install Docker
curl -fsSL https://get.docker.com | sudo sh
# Add your user to the docker group
sudo usermod -aG docker $USER
# Install Docker Compose plugin
sudo apt install docker-compose-plugin
# Verify
docker compose version
Log out and back in for the group change to take effect.
Step 2: Create the Docker Compose File
Create a directory for Gitea and write the compose file:
mkdir -p ~/gitea && cd ~/gitea
nano docker-compose.yml
version: "3"
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=sqlite3
- GITEA__database__PATH=/data/gitea/gitea.db
- GITEA__server__DOMAIN=git.yourdomain.com
- GITEA__server__SSH_DOMAIN=git.yourdomain.com
- GITEA__server__HTTP_PORT=3000
- GITEA__server__ROOT_URL=https://git.yourdomain.com/
- GITEA__server__SSH_PORT=22
- GITEA__service__DISABLE_REGISTRATION=true
restart: always
networks:
- gitea
volumes:
- ./gitea-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "2222:22"
Key configuration points:
- SQLite is used here for simplicity — for high-load instances, switch to PostgreSQL
- DISABLE_REGISTRATION=true prevents anyone from creating accounts on your instance
- SSH is mapped to port 2222 on the host (to avoid conflict with your server’s own SSH)
- Replace
git.yourdomain.comwith your actual domain or server IP
Step 3: Start Gitea
docker compose up -d
Gitea downloads the image and starts. Check logs:
docker compose logs -f
Visit http://your-server-ip:3000 in a browser. The first visit triggers the initial configuration wizard.
Step 4: Initial Setup Wizard
The wizard pre-fills most settings from your environment variables. Review and confirm:
- Database settings — SQLite path should already be set
- General settings — site title, repository root
- Admin account — create your admin username, email, and a strong password
Click Install Gitea. After installation completes, you are redirected to your new Gitea instance.
Step 5: Set Up SSH Key Authentication
Gitea supports SSH key-based Git operations — push and pull without typing a password.
Generate an SSH key on your local machine (if you do not have one):
ssh-keygen -t ed25519 -C "gitea-key" -f ~/.ssh/id_ed25519_gitea
Add the public key to Gitea:
- Log into your Gitea instance
- Click your avatar → Settings
- Navigate to SSH / GPG Keys
- Click Add Key
- Paste the contents of
~/.ssh/id_ed25519_gitea.pub - Give it a descriptive name and click Add Key
Configure your SSH client to use this key for your Gitea host:
# ~/.ssh/config
Host git.yourdomain.com
User git
Port 2222
IdentityFile ~/.ssh/id_ed25519_gitea
Test the connection:
ssh -T git@git.yourdomain.com -p 2222
You should see: Hi yourusername! You've successfully authenticated...
Step 6: Create and Use Repositories
Create a repository:
- Click the + icon → New Repository
- Name it, set visibility (Private recommended), add a README
- Click Create Repository
Clone via SSH:
git clone git@git.yourdomain.com:yourusername/your-repo.git
Push an existing local repo:
cd your-project
git remote add origin git@git.yourdomain.com:yourusername/your-repo.git
git push -u origin main
Git workflows work identically to GitHub — only the remote URL changes.
Step 7: Put Gitea Behind a Reverse Proxy with HTTPS
Running Gitea on port 3000 with plain HTTP is fine for testing but not for production. Use Nginx as a reverse proxy with a free Let’s Encrypt certificate:
sudo apt install nginx certbot python3-certbot-nginx
Create an Nginx site config:
server {
listen 80;
server_name git.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name git.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/git.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
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;
}
}
Obtain the certificate:
sudo certbot --nginx -d git.yourdomain.com
Backup Strategies
Your Gitea data lives in the ./gitea-data directory you mounted. Back it up regularly:
# Stop Gitea, create a compressed archive, restart
docker compose stop
tar -czf gitea-backup-$(date +%Y%m%d).tar.gz gitea-data/
docker compose start
For automated daily backups to an offsite location (S3, Backblaze B2, another server via rsync):
# Add to cron: runs at 2am daily
0 2 * * * /home/user/gitea/backup.sh
Gitea also has a built-in backup command:
docker exec -u git gitea gitea admin app-ini-regenerate
docker exec -u git gitea gitea dump -c /data/gitea/conf/app.ini
This produces a zip file in the container you can copy out with docker cp.
Additional Privacy Settings
In your Gitea admin panel under Site Administration → Configuration:
- Disable gravatar — prevents avatars from loading from Gravatar servers (external requests)
- Disable federated avatars — same reasoning
- Enable private repositories by default — new repos are private unless explicitly made public
Gitea gives you a professional Git hosting environment with zero code leaving your control. For teams, freelancers, or individuals who take code privacy seriously, a self-hosted Gitea instance on a trusted VPS is one of the best investments in your privacy infrastructure.