Docs / Self-Hosted Applications / Self-Hosting Gitea as GitHub Alternative

Self-Hosting Gitea as GitHub Alternative

By Admin · Feb 19, 2026 · Updated Apr 23, 2026 · 7 views · 4 min read

Self-Hosting Gitea as GitHub Alternative is a common requirement for VPS administrators. This guide provides practical instructions that you can follow on Ubuntu 22.04/24.04 or Debian 12, though most steps apply to other distributions as well.

Prerequisites

  • A VPS running Ubuntu 22.04 or later (2GB+ RAM recommended)
  • Basic familiarity with the Linux command line
  • Docker and Docker Compose installed

Docker Compose Setup

Performance benchmarks show that properly tuned gitea can handle significantly more concurrent connections than the default configuration. The key improvements come from adjusting worker processes and connection pooling.


# docker-compose.yml
version: '3.8'
services:
  gitea:
    image: gitea/gitea:latest
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - gitea_data:/data
      - gitea_config:/config
    environment:
      - TZ=UTC
      - PUID=1000
      - PGID=1000
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=gitea
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=changeme

volumes:
  gitea_data:
  gitea_config:
  db_data:

Note that file paths may vary depending on your Linux distribution. The examples here are for Debian/Ubuntu; adjust paths accordingly for RHEL/CentOS-based systems.

Important Notes

Security should be a primary consideration when configuring gitea. Always use strong passwords, keep software updated, and restrict network access to only the necessary ports and IP addresses.

  • Scale vertically before scaling horizontally
  • Use connection pooling for database connections
  • Profile before optimizing - measure first

Initial Configuration

The git component plays a crucial role in the overall architecture. Understanding how it interacts with gitea will help you make better configuration decisions.


# Reverse proxy configuration
server {
    listen 443 ssl http2;
    server_name gitea.example.com;

    ssl_certificate /etc/letsencrypt/live/gitea.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/gitea.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
        proxy_buffering off;
        client_max_body_size 0;
    }
}

The output should show the service running without errors. If you see any warning messages, address them before proceeding to the next step.

Reverse Proxy Integration

When scaling this setup, consider vertical scaling (adding more RAM/CPU) first, as it's simpler to implement. Horizontal scaling adds complexity but may be necessary for high-traffic applications.


# docker-compose.yml
version: '3.8'
services:
  gitea:
    image: gitea/gitea:latest
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - gitea_data:/data
      - gitea_config:/config
    environment:
      - TZ=UTC
      - PUID=1000
      - PGID=1000
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=gitea
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=changeme

volumes:
  gitea_data:
  gitea_config:
  db_data:

Each line in the configuration serves a specific purpose. The comments explain the reasoning behind each setting, making it easier to customize for your specific use case.

Data Persistence

It's recommended to test this configuration in a staging environment before deploying to production. This helps identify potential compatibility issues and allows you to benchmark performance differences.


# Reverse proxy configuration
server {
    listen 443 ssl http2;
    server_name gitea.example.com;

    ssl_certificate /etc/letsencrypt/live/gitea.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/gitea.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
        proxy_buffering off;
        client_max_body_size 0;
    }
}

Note that file paths may vary depending on your Linux distribution. The examples here are for Debian/Ubuntu; adjust paths accordingly for RHEL/CentOS-based systems.

Next Steps

With gitea now set up and running, consider implementing monitoring to track performance metrics over time. Regularly review your configuration as your workload changes and scale resources accordingly.

Was this article helpful?