Back to articles
Technology Insight

Building a Lightweight Git Server: Self-Hosting Forgejo on Oracle Cloud Infrastructure ARM Free Tier

May 29, 2026

Introduction: The Case for Self-Hosted Git Infrastructure

In the modern software development lifecycle, source code management is the bedrock of productivity. While platforms like GitHub, GitLab, and Bitbucket offer robust features, they come with trade-offs regarding data privacy, vendor lock-in, and escalating tier costs for private repositories and advanced CI/CD runners. For enterprises, startups, and independent developers alike, self-hosting a Git server has emerged as a compelling alternative.

Historically, the barrier to self-hosting was infrastructure cost and resource consumption. Resource-heavy platforms like GitLab require substantial memory and CPU overhead, rendering them expensive to run on public clouds. However, the intersection of two technological shifts has changed this paradigm: the availability of Oracle Cloud Infrastructure (OCI) Always Free ARM instances and the rise of Forgejo, an ultra-lightweight, community-driven fork of Gitea.

This comprehensive guide will walk you through provisioning an enterprise-grade, lightweight Git server using Forgejo on an OCI Ampere ARM VPS, complete with Docker containerization, reverse proxying, and automated SSL encryption.

Why Forgejo and Oracle Cloud ARM?

Before diving into the technical implementation, it is vital to understand why this specific stack represents an optimal balance of performance, cost-efficiency, and control.

Oracle Cloud ARM Free Tier: Unprecedented Value

Oracle Cloud's "Always Free" tier is uniquely generous compared to its competitors. It provides up to 4 ARM Ampere A1 Compute vCPUs and 24 GB of RAM. This resource pool can be allocated to a single powerful Virtual Private Server (VPS) or split among up to four smaller instances. For source code management, even a fraction of this allocation offers computing performance that far exceeds standard micro-instances on other cloud providers, ensuring smooth Git operations, rapid web UI rendering, and ample headroom for lightweight automation.

Forgejo: The Lean Git Platform

Forgejo was established as a community-driven, soft-fork of Gitea, focused on software freedom, transparency, and low resource footprints. Written in Go, Forgejo compiles to a single, highly efficient binary. It delivers a feature set remarkably similar to GitHub—including repository hosting, issue tracking, pull requests, project boards, and an integrated container registry—while consuming a mere fraction of the memory. A typical idle Forgejo instance requires less than 100MB of RAM, making it the perfect candidate for efficient cloud hosting.

Prerequisites and Environment Preparation

To follow this guide successfully, ensure you have access to the following components:

  • An active Oracle Cloud Infrastructure account.
  • A registered domain name (e.g., git.yourcompany.com) with access to its DNS management console.
  • An SSH client and a basic understanding of Linux server administration.

Step 1: Provisioning the OCI Ampere Instance

  1. Navigate to the OCI Console, open the navigation menu, and select Compute > Instances.
  2. Click Create Instance.
  3. In the Image and Shape section, click Edit. Change the image to Ubuntu 22.04 LTS or 24.04 LTS (ARM). Change the shape to Ampere (VM.Standard.A1.Flex). Allocate at least 1 vCPU and 6 GB of RAM (adjust upward depending on your broader infrastructure needs).
  4. Configure the Networking section to assign a public IPv4 address and ensure you download or upload your public SSH keys.
  5. Click Create and wait for the instance provisioning status to turn to Running. Note down your public IP address.

Step 2: Configuring Virtual Cloud Network (VCN) Ingress Rules

By default, Oracle Cloud implements a strict ingress firewall at the network level. You must explicitly permit web traffic to reach your VPS.

Important: Modifying the host-level firewall inside the VPS is insufficient if the OCI Security List blocks incoming packets on ports 80 and 443.

Navigate to your instance details page, click on the attached Virtual Cloud Network (VCN), then click on your Security List. Add the following Ingress Rules:

  • Source CIDR: 0.0.0.0/0 | IP Protocol: TCP | Destination Port Range: 80 (HTTP)
  • Source CIDR: 0.0.0.0/0 | IP Protocol: TCP | Destination Port Range: 443 (HTTPS)
  • Source CIDR: 0.0.0.0/0 | IP Protocol: TCP | Destination Port Range: 2222 (Custom Git SSH port, optional but recommended)

Server Configuration and Docker Installation

Connect to your newly provisioned VPS via SSH using your private key:

ssh ubuntu@your_vps_public_ip

First, update the package repository and upgrade existing system packages to guarantee stability and security patches are applied:

sudo apt update && sudo apt upgrade -y

Adjusting the Host Firewall

Ubuntu instances on OCI include pre-configured iptables or ufw rules that can block public traffic. To ensure our web server operates correctly, run the following commands to open ports 80, 443, and 2222:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 2222/tcp
sudo ufw reload

Installing Docker and Docker Compose

Containerization simplifies dependency management and upgrades for Forgejo. Install Docker Engine and the Docker Compose plugin using the official Docker repository script:

curl -fsSL [https://get.docker.com](https://get.docker.com) -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker

Verify the installation by checking the Docker version: docker version and docker compose version.

Deploying Forgejo with Docker Compose

We will construct an isolated environment using Docker Compose, pairing Forgejo with a PostgreSQL database container for robust, transactional data management.

Create a dedicated directory for your Git infrastructure and navigate into it:

mkdir -p ~/forgejo-stack && cd ~/forgejo-stack

Create a file named docker-compose.yml and populate it with the following configuration architecture:

version: '3.8'

networks:
  forgejo-network:
    driver: bridge

services:
  server:
    image: codeberg.org/forgejo/forgejo:8
    container_name: forgejo
    restart: always
    networks:
      - forgejo-network
    environment:
        - USER_UID=1000
        - USER_GID=1000
        - FORGEJO__database__DB_TYPE=postgres
        - FORGEJO__database__HOST=db:5432
        - FORGEJO__database__NAME=forgejo
        - FORGEJO__database__USER=forgejo
        - FORGEJO__database__PASSWD=secure_db_password_here
    volumes:
      - ./data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "127.0.0.1:3000:3000"
      - "2222:22"
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    container_name: forgejo-db
    restart: always
    networks:
      - forgejo-network
    environment:
      - POSTGRES_USER=forgejo
      - POSTGRES_PASSWORD=secure_db_password_here
      - POSTGRES_DB=forgejo
    volumes:
      - ./db-data:/var/lib/postgresql/data

Make sure to replace secure_db_password_here with a strong, randomly generated alphanumeric string. In this layout, Forgejo’s web interface is mapped to port 3000 locally, and SSH traffic is forwarded through port 2222 to avoid conflicts with your host VPS SSH service.

Launch the stack in detached mode:

docker compose up -d

Securing Traffic with Nginx and Let's Encrypt SSL

Exposing a Git application over HTTP is insecure, leaving authentication tokens and code repositories vulnerable to interception. We will use Nginx as a reverse proxy coupled with Let's Encrypt to enforce TLS 1.3 encryption.

DNS Configuration

Before proceeding, log in to your DNS registrar and add an A Record pointing your chosen subdomain (e.g., git.yourcompany.com) to the public IPv4 address of your OCI ARM instance.

Nginx Setup

Install Nginx on the host server:

sudo apt install nginx -y

Create an Nginx server block configuration for your domain: sudo nano /etc/nginx/sites-available/forgejo. Insert the following server block:

server {
    listen 80;
    server_name git.yourcompany.com;

    location / {
        proxy_pass [http://127.0.0.1:3000](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;

        # Extended timeouts for large repository pushes
        client_max_body_size 512M;
        proxy_connect_timeout 600s;
        proxy_send_timeout 600s;
        proxy_read_timeout 600s;
    }
}

Enable the site configuration and restart Nginx:

sudo ln -s /etc/nginx/sites-available/forgejo /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Automating SSL with Certbot

Install Certbot and the Nginx plugin to automatically handle SSL certification acquisition and renewal:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d git.yourcompany.com

Follow the interactive prompts, ensure you consent to redirecting all HTTP traffic to HTTPS, and let Certbot rewrite the Nginx rules safely.

Initial Forgejo Optimization and Best Practices

Open your web browser and navigate to [https://git.yourcompany.com](https://git.yourcompany.com). You will be greeted by the initial Forgejo configuration wizard. Since we configured environment variables in the Docker Compose file, the database settings will be pre-populated.

Crucial Settings in the Web UI:

  • SSH Server Port: Set this to 2222 (matching our container port forwarding).
  • Forgejo Base URL: Change this to your exact domain domain: [https://git.yourcompany.com/](https://git.yourcompany.com/).
  • Administrator Account: Scroll down to the bottom and explicitly define your primary administrator credentials. The first user created automatically inherits system admin privileges.

Performance and Maintenance Best Practices

Operating a self-hosted Git system requires a disciplined approach to maintenance:

  1. Backups: Establish a nightly cron job to back up the ~/forgejo-stack/data directory and generate a PostgreSQL database dump using docker exec -t forgejo-db pg_dumpall. Store these snapshots offsite, such as on OCI Object Storage.
  2. Updates: Periodically pull down updated Docker images to apply security patches. Upgrading Forgejo is as simple as executing docker compose pull followed by docker compose up -d.
  3. Resource Monitoring: Utilize simple command-line tools like htop and docker stats to observe system trends. Thanks to the ARM architecture and Forgejo's low-resource nature, you will observe exceptionally low CPU and RAM consumption even during continuous active usage.

Conclusion

By leveraging Forgejo on the Oracle Cloud OCI ARM Free Tier, you have successfully built a private, blazing-fast, and deeply secure Git service without incurring capital expenditures. This infrastructure grants you absolute autonomy over your code repositories, shields your workflow from upstream platform pricing changes, and maximizes the capability of cutting-edge ARM hardware. As your team grows, this environment remains flexible, scalable, and entirely yours to control.

Building a Lightweight Git Server: Self-Hosting Forgejo on Oracle Cloud Infrastructure ARM Free Tier | DPTCloud