Privacy Tools #Gitea#self-hosted#Git

Self-Hosted Gitea: Run Your Own Private Git Server with Docker

Set up Gitea via Docker for a private self-hosted Git server. Covers installation, SSH key auth, repo creation, backups, and why it beats GitHub for privacy.

7 min read

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.com with 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:

  1. Log into your Gitea instance
  2. Click your avatar → Settings
  3. Navigate to SSH / GPG Keys
  4. Click Add Key
  5. Paste the contents of ~/.ssh/id_ed25519_gitea.pub
  6. 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:

  1. Click the + icon → New Repository
  2. Name it, set visibility (Private recommended), add a README
  3. 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.

#code repository #privacy #Docker #Git #self-hosted #Gitea