How to Install and Configure Forgejo / Gitea on Ubuntu (Advanced DevOps & Git Hosting Guide)
Last Updated: July 11th, 2026
This comprehensive guide walks you through setting up a self-hosted Git system on Ubuntu from absolute scratch to an enterprise-grade, hardened infrastructure. We will use Forgejo, the modernized, fully open-source drop-in replacement fork of Gitea. It is built to be fast, highly efficient, and independent of corporate telemetry, making it the perfect choice for private version control.
What Is Forgejo / Gitea?
Forgejo is a lightweight self-hosted software development platform managed by Git. If you rely on public platforms like GitHub or GitLab, you are trusting third-party organizations with your intellectual property, private source code, and deployment scripts. Self-hosting with a platform like Forgejo allows you to host repositories, track issues, review code via pull requests, and orchestrate automated CI/CD pipelines entirely under your own domain and security framework.
Key Platform Advantages
- Minimal Resource Footprint: Written in Go, Forgejo consumes a tiny fraction of the RAM required by platforms like GitLab, scaling flawlessly on everything from a $5 cloud VPS to high-end enterprise clusters.
- 100% Free Software: Completely open source, community-governed, and free of the hidden monetization or restricted enterprise tiers found in proprietary tools.
- Integrated CI/CD Engine: Features built-in action runners fully compatible with GitHub Actions workflows out of the box.
- Comprehensive Security Controls: Native support for SSH key management, Two-Factor Authentication (2FA), FIDO2/WebAuthn keys, and external OAuth/OIDC authenticators.
Requirements & Production Architecture
You will need a clean instance running Ubuntu (22.04, 24.04 LTS, or newer) with sudo privileges, a domain name pointed to your server's IP address via an A record, and an unrestricted local network layer to accept Git over SSH traffic.
Step 1: System Pre-Flight & Database Optimization
While Forgejo supports SQLite for tiny home configurations, production workloads demand a robust SQL database layer. We will install PostgreSQL along with essential networking and security tools:
sudo apt update && sudo apt upgrade -y
sudo apt install -y postgresql postgresql-contrib git curl gnupg ufw fail2ban
Log into your local PostgreSQL instance to isolate a high-performance database and dedicated user account for Git services:
sudo -u postgres psql
Run the following structural SQL commands inside the PostgreSQL prompt, replacing the placeholder password with a highly secure key:
CREATE USER forgejo WITH PASSWORD 'YourExtremelySecureDBPassword123!';
CREATE DATABASE forgejodb OWNER forgejo;
\q
Step 2: Isolate the Dedicated System Environment
For security, Forgejo should never execute under a privileged root shell. Create an isolated system service user called git:
sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
Construct the strict structural directory hierarchy to house configuration variables, metadata, repositories, and logs:
sudo mkdir -p /var/lib/forgejo/{custom,data,log}
sudo chown -R git:git /var/lib/forgejo/
sudo chmod -R 750 /var/lib/forgejo/
sudo mkdir /etc/forgejo
sudo chown -R git:git /etc/forgejo
sudo chmod -R 770 /etc/forgejo
Step 3: Fetch and Install the Forgejo Engine
Navigate to the binary directory, download the latest optimized target binary executable from the official source repo, make it executable, and verify its deployment:
cd /usr/local/bin
sudo curl -Lo forgejo https://codeberg.org/forgejo/forgejo/releases/download/v9.0.1/forgejo-9.0.1-linux-amd64
sudo chmod +x forgejo
forgejo --version
Step 4: Orchestrate the Systemd Daemon Service
To ensure your Git service remains persistent, restarts on unexpected failures, and initializes properly on system boot, map out a custom systemd unit file configuration:
sudo nano /etc/systemd/system/forgejo.service
Paste the following production operational layout directly into the editor:
[Unit]
Description=Forgejo (Git with a cup of tea)
After=network.target syslog.target postgresql.service
[Service]
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/forgejo/
RuntimeDirectory=forgejo
ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/forgejo/
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
Save and close your file, reload the daemon engine tracking infrastructure, start your service, and flag it to start on system boot:
sudo systemctl daemon-reload
sudo systemctl enable --now forgejo
Step 5: Harden Networks and Set Up Reverse Proxy (Nginx)
Secure the perimeter via UFW, allowing web endpoints along with basic Git operations over SSH traffic safely:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable --force
Install and configure Nginx to proxy incoming client connections cleanly onto port 3000 where the app stack natively listens:
sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/git.conf
Apply the server routing blocks tailored for large Git uploads and smooth operations:
server {
listen 80;
server_name git.example.com;
client_max_body_size 512M;
location / {
proxy_pass http://127.0.0.1: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;
}
}
Activate the site config and reload Nginx:
sudo ln -s /etc/nginx/sites-available/git.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Step 6: Deploy Production SSL via Let’s Encrypt
Apply full cryptographic TLS parameters to shield transit assets seamlessly using Certbot:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d git.example.com
Step 7: Web Installation & Advanced Post-Install Hardening
Navigate to https://git.example.com inside your web browser. You will be greeted by the initial web installer screen:
- Database Settings: Choose PostgreSQL, input host address
127.0.0.1:5432, database nameforgejodb, database userforgejo, and enter the password configured during Step 1. - General Settings: Set Site Title, modify the SSH Port values if running standard configurations, and lock down the Base URL parameter to accurately use
https://git.example.com/. - Administrative Profile: Expand the Optional Configuration options, fill out the dedicated Administrator Account parameters completely, and finish the setup.
To safeguard your installation against brute force attacks, finalize the deployment by locking the file permissions of the master system configuration profile:
sudo chmod 660 /etc/forgejo/app.ini
sudo chown git:git /etc/forgejo/app.ini
You now possess a hardened, private version control architecture running on top-tier open-source infrastructure.