Forgejo on Docker: The Lean Way to Self-Host Your Private Git Server

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

Owning Your Infrastructure

Tying every side project to Big Tech platforms feels convenient until it isn’t. Terms of service change, outages happen, and eventually, you realize you don’t actually own your workflow. If you are running a HomeLab, you probably want a Git server that lives on your hardware and doesn’t swallow 4GB of RAM just to sit idle. GitHub and GitLab are excellent, but they are overkill for many self-hosted setups.

I hit my breaking point when a GitLab instance started choking my VPS. I needed a tool that felt like GitHub but ran with the efficiency of a native binary. That is where Forgejo shines. It is a community-driven fork of Gitea, created in late 2022 to ensure the project remains truly open-source. In my testing, Forgejo handles dozens of repositories while consuming less than 500MB of RAM, making it perfect for modest hardware.

Why Forgejo Instead of Gitea or GitLab?

You might wonder why we are picking Forgejo over Gitea. After Gitea transitioned to a commercial model, the community launched Forgejo to prioritize users over corporate interests. It maintains 100% compatibility with Gitea but stays focused on the “Free Software” mission.

Compared to GitLab, Forgejo is a lightweight champion. While GitLab is a powerful beast requiring significant CPU and memory, Forgejo delivers the essentials—issue tracking, pull requests, wikis, and basic CI/CD (Actions)—at a fraction of the cost. It runs perfectly on a Raspberry Pi 4 or a basic $5-per-month cloud instance.

Preparing the Environment

Before jumping into the terminal, ensure you have Docker and Docker Compose ready. We will use PostgreSQL instead of the default SQLite. While SQLite is fine for one-person setups, PostgreSQL handles concurrent connections much better as your repository count grows. It also makes your backup strategy more professional.

Start by creating a structured directory to keep your configuration and data together:

mkdir -p ~/homelab/forgejo
cd ~/homelab/forgejo
mkdir data db

The Docker Compose Configuration

We will define two services: the Forgejo application and a PostgreSQL 15 database. This separation is a standard DevOps practice. It ensures your data lives in a managed environment, making updates and migrations significantly safer.

Create your docker-compose.yml file:

services:
  server:
    image: code.forgejo.org/forgejo/forgejo:latest
    container_name: forgejo
    restart: always
    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=your_secure_password
    networks:
      - forgejo
    volumes:
      - ./data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "2222:22"
    depends_on:
      - db

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

networks:
  forgejo:
    external: false

Crucial Config Notes

  • USER_UID/GID: Set these to match your Linux user (usually 1000) to prevent permission errors when Forgejo tries to write to your ./data folder.
  • SSH Mapping: We map port 2222 to the container’s port 22. This prevents conflicts with your host machine’s primary SSH service.
  • Database: The alpine image variant keeps your total disk footprint under 300MB.

Launching the Server

Spinning up the server takes a single command. Run this and wait for the containers to initialize:

docker compose up -d

Once the command finishes, keep an eye on the logs to ensure the database connection is healthy:

docker compose logs -f

Now, point your browser to http://[your-server-ip]:3000. You will see the setup screen. Because we defined the database credentials in the environment variables, Forgejo will pre-fill most of the technical fields for you.

The “Must-Fix” First Steps

Do not just blast through the installation. A few small tweaks now will save you hours of troubleshooting later:

  1. SSH Port: Change the SSH server port in the UI to 2222. This ensures the clone URLs match our Docker setup.
  2. Root URL: Use your actual domain or local IP (e.g., http://git.home.arpa:3000). If you leave this as localhost, clone links won’t work from other computers.
  3. Admin User: Set up your primary account here. In Forgejo, the very first user created is granted full administrator privileges.

Configuring SSH for Fast Commits

Pushing code via HTTPS gets annoying quickly. SSH is faster and more secure. Since Forgejo is listening on port 2222, you should tell your local Git client how to find it. Update your ~/.ssh/config file:

Host forgejo
    HostName 192.168.1.100
    User git
    Port 2222
    IdentityFile ~/.ssh/id_rsa

With this config, you can clone using git clone forgejo:username/project.git. It eliminates the need for passwords and makes the workflow feel identical to GitHub.

Backups and Maintenance

Backing up your server is simple because we used Docker volumes. Just stop the containers and compress the forgejo directory. I recommend a nightly cron job to rsync these folders to an external drive or NAS.

Updates are just as easy. Pull the new image and restart the containers:

docker compose pull
docker compose up -d

Forgejo manages database migrations automatically. I have jumped through three major version updates without a single database error. It is remarkably stable.

Final Thoughts

Building your own Forgejo server is one of the most practical HomeLab projects you can tackle. You gain total control over your code, a familiar interface for collaboration, and a system that respects your hardware. Whether you are storing private scripts or complex dev projects, owning your Git server is a massive win for digital sovereignty.

Try it for a week. The speed of a local Git server and the peace of mind that comes with local storage are hard to give up once you have experienced them.

Share: