Taking Your Code Off the Cloud
GitHub is convenient until it isn’t. Rate limits, outages, policy changes, and the quiet discomfort of storing proprietary code on a platform you don’t control have pushed a growing number of developers toward self-hosted alternatives. Forgejo sits at the top of that list – a community-driven fork of Gitea that offers nearly identical functionality to GitHub, including repositories, pull requests, Actions-compatible CI/CD, and user management, all running on hardware you own.
The setup process is straightforward enough that a single afternoon gets you from a blank server to a fully operational Git host. This guide walks through installing Forgejo on a Linux server using Docker Compose, configuring it behind a reverse proxy, and locking it down with basic security settings. Whether you’re hosting personal projects or moving a small team off GitHub, the steps are the same.

What You Need Before You Start
Forgejo runs comfortably on modest hardware. A server or VPS with 1 GB of RAM and 10 GB of storage handles small teams without strain. You’ll want a clean Ubuntu 22.04 or Debian 12 install, Docker and Docker Compose already installed, and a domain name with DNS pointed at your server’s IP. If you’re running this at home rather than on a VPS, port forwarding on ports 80, 443, and 22 (or a custom SSH port) needs to be configured on your router before anything else.
You’ll also want Nginx installed and ready to act as a reverse proxy, along with Certbot for TLS certificates. A working email server or SMTP relay is optional but worth setting up early – Forgejo uses it for account registration confirmations, password resets, and notification emails. Without it, you’ll be managing user accounts manually through the admin panel.
If you’re already running a home server with virtualization set up through Proxmox VE, spinning Forgejo up inside a dedicated container or VM is the cleanest approach – it keeps the service isolated and makes snapshots easy.

Installing Forgejo with Docker Compose
Create a directory for the project and set up your Compose file. A basic docker-compose.yml for Forgejo looks like this:
- Define a
forgejoservice using thecodeberg.org/forgejo/forgejo:latestimage - Mount two volumes: one for application data (
./forgejo:/data) and one for the host’s timezone (/etc/timezone:/etc/timezone:ro) - Expose port
3000for HTTP and port2222for SSH (avoid using 22 on the host if your server uses it for admin access) - Set environment variables:
USER_UID=1000,USER_GID=1000, and optionallyFORGEJO__database__DB_TYPE=sqlite3for a simple single-node install
Run docker compose up -d and Forgejo will pull the image and start. Within about 30 seconds, the web installer is accessible at http://your-server-ip:3000. The installer walks through database selection (SQLite works fine for personal use, PostgreSQL is better for teams), site URL, admin account creation, and optional SMTP settings. Fill these in carefully – the site URL in particular affects how clone URLs, webhook callbacks, and email links are generated. Getting it wrong means reconfiguring later.
For the reverse proxy layer, create an Nginx server block that proxies requests to port 3000 and handles HTTPS termination. Run certbot --nginx -d your.domain.com to get a certificate and let Certbot modify the Nginx config automatically. Once that’s done, your Forgejo instance is accessible over HTTPS with a valid certificate. SSH-based Git operations go through port 2222 on the host, so users will need to specify the port in their SSH config or clone URLs using the ssh://git@your.domain.com:2222/user/repo.git format.
Locking It Down and Making It Useful
Fresh installs of Forgejo are open by default – anyone who reaches the web interface can register an account. If this is a private instance, disable public registration immediately. Navigate to the admin panel under Site Administration, then User Management, and set the registration policy to invitation-only or disabled entirely. You can create accounts for your team manually or send invite links from the admin panel.
SSH key management in Forgejo works exactly as it does on GitHub. Users add their public keys under Settings > SSH/GPG Keys, and from that point forward, Git operations authenticate without passwords. For teams, the Organization feature mirrors GitHub’s org structure – you create an org, add members, and assign repository permissions by team. A developer on the “backend” team might have write access to three repos and read access to everything else. The permission model is granular enough for most small organizations without becoming bureaucratic.
Forgejo Actions deserves attention here. It’s a CI/CD system that accepts the same YAML workflow syntax as GitHub Actions, which means many existing workflows migrate with little or no editing. To use it, you register a runner – a separate process that executes jobs. The runner can live on the same server or a separate machine. Download the Forgejo runner binary, register it against your instance using an API token from the admin panel, and start it as a systemd service. Once registered, any repository with a .forgejo/workflows/ directory and a valid workflow file will trigger jobs automatically on push or pull request events.
The one area where Forgejo genuinely trails GitHub is ecosystem breadth. There are no third-party marketplace actions to pull from directly, and some GitHub-specific API integrations won’t map cleanly. Teams that rely heavily on GitHub Apps or the GitHub Package Registry will need to find alternatives or host their own. Container images can go to Forgejo’s built-in package registry, which supports Docker, npm, PyPI, and several other formats – but the setup requires enabling the packages feature in the app config and pointing your Docker client or package manager at the Forgejo registry URL instead of the default public ones. That reconfiguration step catches teams off guard more often than the initial install does.
Frequently Asked Questions
Is Forgejo compatible with GitHub Actions workflows?
Forgejo Actions accepts the same YAML syntax as GitHub Actions, so most workflows migrate with minimal changes, though GitHub Marketplace actions are not directly available.
What database should I use for Forgejo?
SQLite works well for personal or small single-user setups. For teams or heavier workloads, PostgreSQL is the better choice for performance and reliability.





