Want to host your own code without relying on GitHub or GitLab? Forgejo is a community-driven fork of Gitea — lightweight, fast, and designed to stay free forever. It’s everything you need for private repos, CI/CD, and team collaboration on your own hardware.

Why Forgejo Over Gitea?

Forgejo forked from Gitea in 2022 after governance concerns. The key differences:

  • Community-governed — no single company controls it
  • Guaranteed free — committed to staying FOSS, no enterprise bait-and-switch
  • Federation support — working toward ActivityPub integration (follow repos across instances)
  • Same codebase — if you know Gitea, you know Forgejo
  • Drop-in replacement — migrate from Gitea with zero data loss

Prerequisites

  • Docker and Docker Compose
  • ~256MB RAM (runs great on a Pi)
  • A domain (optional but recommended)

Step 1: Setup

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

Step 2: Docker Compose

Create docker-compose.yml:

services:
  forgejo:
    image: codeberg/forgejo:9
    container_name: forgejo
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - FORGEJO__server__ROOT_URL=http://localhost:3000
      - FORGEJO__database__DB_TYPE=sqlite3
      - FORGEJO__service__DISABLE_REGISTRATION=false
    volumes:
      - ./data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "2222:22"
    restart: unless-stopped

Step 3: Launch

docker compose up -d

Open http://your-server-ip:3000. The first-run wizard appears:

  1. Database: SQLite is fine for personal use (PostgreSQL for teams)
  2. Site Title: Your instance name
  3. Admin Account: Create your admin user
  4. Click Install Forgejo

Step 4: Create Your First Repository

  1. Click +New Repository
  2. Name it, add a description, choose visibility
  3. Initialize with a README if starting fresh

Push Existing Code

cd ~/my-project
git remote add forgejo http://your-server-ip:3000/username/my-project.git
git push -u forgejo main

SSH Access

Add your public key at Settings → SSH/GPG Keys, then:

git remote add forgejo ssh://git@your-server-ip:2222/username/my-project.git

Step 5: Mirror GitHub Repos

Forgejo can mirror your GitHub repos automatically:

  1. New MigrationGitHub
  2. Enter the GitHub repo URL
  3. Check Mirror Repository
  4. Set sync interval

Your Forgejo instance stays in sync with GitHub — perfect as a backup or for moving off GitHub gradually.

Step 6: Built-in CI/CD (Forgejo Actions)

Forgejo has GitHub Actions-compatible CI/CD built in:

Enable Actions

Add to your compose environment:

environment:
  - FORGEJO__actions__ENABLED=true

Add a Runner

  runner:
    image: code.forgejo.org/forgejo/runner:6
    container_name: forgejo-runner
    depends_on:
      - forgejo
    environment:
      - FORGEJO_INSTANCE_URL=http://forgejo:3000
      - FORGEJO_RUNNER_REGISTRATION_TOKEN=your-token
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

Get the registration token from Site Administration → Runners.

Create a Workflow

Create .forgejo/workflows/ci.yml in your repo:

on: [push]
jobs:
  test:
    runs-on: docker
    steps:
      - uses: actions/checkout@v4
      - run: echo "Hello from Forgejo CI!"
      - run: npm test

Yes — it uses the same syntax as GitHub Actions. Most GitHub Actions work unmodified.

Step 7: Package Registry

Forgejo includes a built-in package registry for Docker images, npm, PyPI, and more:

# Push a Docker image to Forgejo
docker login your-server-ip:3000
docker tag myapp your-server-ip:3000/username/myapp:latest
docker push your-server-ip:3000/username/myapp:latest
# Publish an npm package
npm config set registry http://your-server-ip:3000/api/packages/username/npm/
npm publish

Step 8: Reverse Proxy

For production with HTTPS:

Caddy:

g}it.yroeuvredrosmea_ipnr.ocxoyml{ocalhost:3000

Update the ROOT_URL in your compose:

- FORGEJO__server__ROOT_URL=https://git.yourdomain.com

Restart after changing:

docker compose down && docker compose up -d

Step 9: Backups

# Forgejo has a built-in backup command
docker exec forgejo forgejo dump -c /data/gitea/conf/app.ini

# Or just backup the data directory
tar -czf ~/backups/forgejo-$(date +%Y%m%d).tar.gz -C ~/forgejo data/

Migrating from Gitea

Since Forgejo is a fork, migration is seamless:

  1. Stop Gitea
  2. Copy your Gitea data/ directory
  3. Replace the Gitea image with codeberg/forgejo:9
  4. Start Forgejo — it reads the same data format
# Literally just change the image
sed -i 's|gitea/gitea:latest|codeberg/forgejo:9|' docker-compose.yml
docker compose up -d

Forgejo vs Alternatives

FeatureForgejoGiteaGitLabGitHub
Self-hosted
RAM usage~100MB~100MB~4GBN/A
CI/CD
Package registry
Federation🔜
LicenseGPLMIT*PartialProprietary
GovernanceCommunityCompanyCompanyCompany

*Gitea changed to a company-controlled model, which prompted the Forgejo fork.

Troubleshooting

Can’t push via SSH

  • Verify port 2222 is mapped and open
  • Check your SSH key is added in Forgejo settings
  • Test: ssh -T git@your-server-ip -p 2222

Actions not running

  • Ensure FORGEJO__actions__ENABLED=true is set
  • Check runner is registered: Admin → Runners
  • View runner logs: docker compose logs runner

Slow on large repos

  • Switch from SQLite to PostgreSQL for better concurrent access
  • Enable Git LFS for large files
  • Increase container memory limit

Resource Usage

MetricUsage
RAM~100-150MB
CPUMinimal
Disk~200MB + repos
Image size~100MB

Conclusion

Forgejo gives you everything GitHub does — repos, issues, PRs, CI/CD, packages — on your own server for free. It’s lightweight enough for a Raspberry Pi, powerful enough for a team, and committed to staying open source forever.

If you’re already self-hosting anything, there’s no reason your code shouldn’t be self-hosted too. Forgejo makes it easy.