Ownership Starts with Your Code: Why Forgejo is the Ultimate Homelab Git Host

Ownership Starts with Your Code: Why Forgejo is the Ultimate Homelab Git Host

In the homelab community, we obsess over self-hosting. We host our own media, our own DNS, and our own password managers. Yet, many of us still push the configuration files (YAML, scripts, Dockerfiles) that define that infrastructure up to Github or GitLab.

If your goal is true data sovereignty and local reliability, your code—the blueprint of your laboratory—needs a local home.

Meet Forgejo: Git with a Homelab Heart

Forgejo (a soft-fork of Gitea) is a lightweight, all-in-one Git hosting solution that is perfectly tuned for self-hosting. It provides a clean, web-based UI that feels instantly familiar to anyone coming from major public platforms, offering repositories, issue tracking, pull requests, and a robust wiki.

graph TD
    A[Your Workstation] -- Git Push --> B(Forgejo LXC/Docker)
    B -- Stores Repos --> C[Local ZFS/NFS]
    B -- Triggers Actions --> D{Woodpecker CI}
    D -- Deploys to --> E[Proxmox Cluster]

How It Transforms Your Homelab

  1. Air-Gapped Reliability: If your internet connection drops, you can still commit, branch, and merge your infrastructure-as-code. Your ability to manage your servers is never dependent on someone else's cloud uptime.
  2. Resource Efficiency: Unlike GitLab, which is a powerhouse but heavy on RAM, Forgejo can comfortably run inside a tiny LXC container or a single 512MB Docker container. It is ideal for low-power nodes or older hardware you are repurposing.
  3. Integrated CI/CD: Modern homelabs thrive on automation. Forgejo works seamlessly with lightweight CI/CD engines (like Woodpecker CI). When you push a change to a Dockerfile, your local pipeline can automatically build the new image and deploy it to your local cluster.
  4. Local Secrets Stays Local: You don't need to commit sensitive API keys or SSH configurations to public repositories, even private ones. Everything stays locked inside your private LAN.

How to Set Forgejo Up With Docker:

Create your .env file and copy this code snippet:

DATABASE_TYPE=postgres
DATABASE_HOST=db
DATABASE_PORT=5432
DATABASE_USER=forgejo
DATABASE_PASSWORD=VotreMotDePasseSuperSecurise
DATABASE_NAME=forgejo
ROOT_URL=https://dots.linuxpad.blog
LFS_ENABLED=true
OFFLINE_MODE=false

Finally copy this code and paste in your generated compose.yaml file:


services:
  db:
    image: postgres:15-alpine
    container_name: dots-db
    volumes:
      - forgejo_db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: ${DATABASE_USER}
      POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
      POSTGRES_DB: ${DATABASE_NAME}
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USER} -d ${DATABASE_NAME}"]
      interval: 5s
      timeout: 5s
      retries: 5
      start_period: 10s
  dots:
    image: codeberg.org/dots/dots:1.21
    container_name: dots
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "3000:3000" # Port pour l'interface web
      - "2222:22"   # Port pour SSH (optionnel)
    volumes:
      - forgejo_data:/data
      - ./config/app.ini:/etc/dots/app.ini

    networks:
      - traefik
    environment:
      DATABASE_TYPE: ${DATABASE_TYPE}
      DATABASE_HOST: db
      DATABASE_PORT: ${DATABASE_PORT}
      DATABASE_USER: ${DATABASE_USER}
      DATABASE_PASSWORD: ${DATABASE_PASSWORD}
      DATABASE_NAME: ${DATABASE_NAME}
      ROOT_URL: ${ROOT_URL}
      LFS_ENABLED: ${LFS_ENABLED}
      OFFLINE_MODE: ${OFFLINE_MODE}
    restart: unless-stopped


    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.routers.dots-http.entrypoints=http"
      - "traefik.http.routers.dots-http.middlewares=redir-https"
      - "traefik.http.routers.dots-http.rule=Host(`dots.linuxpad.blog`)"
      - "traefik.http.routers.dots-http.service=noop@internal"
      - "traefik.http.routers.dots-https.entrypoints=https"
      - "traefik.http.routers.dots-https.tls=true"
      - "traefik.http.routers.dots-https.middlewares=gzip"
      - "traefik.http.routers.dots-https.rule=Host(`dots.linuxpad.blog`)"
      - "traefik.http.services.dots-backend.loadbalancer.server.scheme=http"
      - "traefik.http.services.dots-backend.loadbalancer.server.port=3000"
      - "traefik.http.routers.dots-https.middlewares=authelia@docker"

volumes:
  forgejo_db_data:
  forgejo_data:



networks:
  traefik:
    name: traefik
    external: true #do not expose external for security risk
 

Forgejo bridges the gap between tinkering and infrastructure management. If you are serious about treating your homelab like data center, start by hosting the code that runs it.


🛡️ Security Notice: All commits for my Home-Lab project are cryptographically signed using GPG Key ID FF0825B4A1F7B871. You can verify my public key signature directly via my main site profile.