feat(forgejo): remove gitea-mirror, all repos now first-class

GitHub mirroring is no longer needed now that Forgejo is the primary
remote. Drops the gitea-mirror service, its volume, env vars, Caddy
site, and firewall rule; docs updated to match.
This commit is contained in:
Brian Pooe 2026-07-19 13:21:05 +02:00
parent 1549283f19
commit 73ff919b9f
7 changed files with 9 additions and 161 deletions

View file

@ -32,7 +32,7 @@ help:
@echo " deploy-paperless - Deploy Paperless-ngx"
@echo " deploy-vaultwarden - Deploy Vaultwarden"
@echo " deploy-koffan - Deploy Koffan (grocery list)"
@echo " deploy-forgejo - Deploy Forgejo (self-hosted Git + GitHub mirroring)"
@echo " deploy-forgejo - Deploy Forgejo (self-hosted Git)"
@echo ""
@echo "Utility Targets:"
@echo " status - Show status of all deployed stacks"

View file

@ -28,7 +28,7 @@ Each stack guide in `docker-compose-files/<stack>/README.md` explains appdata pl
| [Beszel Hub](docker-compose-files/beszel-hub/README.md) | Beszel monitoring dashboard |
| [Beszel Socket Proxy](docker-compose-files/socket-proxy/README.md) | Restricted Docker API access for Beszel |
| [Caddy](docker-compose-files/caddy/README.md) | Reverse proxy with Cloudflare DNS-01 |
| [Forgejo](docker-compose-files/forgejo/README.md) | Self-hosted Git service with automatic GitHub mirroring |
| [Forgejo](docker-compose-files/forgejo/README.md) | Self-hosted Git service |
| [Gramps Web](docker-compose-files/gramps-web/README.md) | Genealogy web application |
| [Home Assistant](docker-compose-files/homeassistant/README.md) | Home Assistant, Mosquitto, and Zigbee2MQTT |
| [Immich](docker-compose-files/immich/README.md) | Photo and video management with GPU acceleration |

View file

@ -180,11 +180,6 @@ git.{{CADDY_BASE_DOMAIN:-home.example.com}} {
reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.18:3000
}
git-mirror.{{CADDY_BASE_DOMAIN:-home.example.com}} {
import common
reverse_proxy {{CADDY_OFFICE_PREFIX:-10.0.10}}.18:4321
}
# Hermes Agent web dashboard (LXC 113, not docker — systemd service)
hermes.{{CADDY_BASE_DOMAIN:-home.example.com}} {
import common

View file

@ -20,34 +20,3 @@ FORGEJO_DATA_ROOT=/mnt/unas/forgejo_data
# `docker exec forgejo forgejo admin user create ...` instead.
FORGEJO_DISABLE_REGISTRATION=true
FORGEJO_REQUIRE_SIGNIN_VIEW=false
# --- gitea-mirror: auto-syncs GitHub repos into Forgejo ---
GITEA_MIRROR_VERSION=latest
GITEA_MIRROR_PORT=4321
GITEA_MIRROR_BIND_IP=0.0.0.0
GITEA_MIRROR_MEM_LIMIT=256m
# Full URL where gitea-mirror's own UI is reachable
GITEA_MIRROR_PUBLIC_URL=https://git-mirror.home.example.com
# Generate with: openssl rand -base64 32
GITEA_MIRROR_AUTH_SECRET=<random-secret>
# GitHub source — a classic PAT with repo (+ read:org if mirroring orgs) scope
GITHUB_USERNAME=<your-github-username>
GITHUB_TOKEN=<github-personal-access-token>
GITEA_MIRROR_SKIP_FORKS=false
GITEA_MIRROR_PRIVATE_REPOS=true
GITEA_MIRROR_STARRED=false
GITEA_MIRROR_ORGANIZATIONS=false
GITEA_MIRROR_ISSUES=false
GITEA_MIRROR_WIKI=false
# Forgejo destination — GITEA_MIRROR_FORGEJO_TOKEN can only be created after
# Forgejo is up and you've logged in once (Settings -> Applications ->
# Generate New Token, scopes: repo, admin:org). See README "GitHub mirroring".
GITEA_MIRROR_FORGEJO_USERNAME=<your-forgejo-username>
GITEA_MIRROR_FORGEJO_TOKEN=<forgejo-api-token>
GITEA_MIRROR_ORG=github-mirrors
GITEA_MIRROR_ORG_VISIBILITY=private
GITEA_MIRROR_INTERVAL=8h

View file

@ -1,8 +1,6 @@
# Forgejo
Self-hosted Git service (soft fork of Gitea) with Postgres, plus
[gitea-mirror](https://github.com/RayLabsHQ/gitea-mirror) to automatically
pull all your GitHub repositories in as mirrors.
Self-hosted Git service (soft fork of Gitea) with Postgres.
## Persistent Data
@ -29,9 +27,6 @@ The share binds use `create_host_path: false`, so the stack refuses to start
if the share is not mounted, rather than silently writing into an empty
directory that later needs merging back in.
`gitea_mirror_data` (local named volume) holds gitea-mirror's own small
SQLite state DB — negligible size, not worth splitting out.
## Installation
1. Create `.env` if it does not exist:
@ -42,8 +37,7 @@ SQLite state DB — negligible size, not worth splitting out.
2. Set the required values in `docker-compose-files/forgejo/.env` — at
minimum `FORGEJO_ROOT_URL`, `FORGEJO_DOMAIN`, `FORGEJO_DB_PASSWORD`, and
`FORGEJO_DATA_ROOT`. Leave the `GITEA_MIRROR_*` GitHub/Forgejo-token vars
for step 6 — Forgejo needs to exist before those tokens can be generated.
`FORGEJO_DATA_ROOT`.
3. Add the UNAS share and bind-mount it into the LXC, following
[nfs-mounts.md](../../docs/unas/nfs-mounts.md) (add `forgejo_data` to the
@ -67,49 +61,15 @@ SQLite state DB — negligible size, not worth splitting out.
```bash
./substitute_env.sh docker-compose-files/forgejo/template.yaml docker-compose.forgejo.yml .env docker-compose-files/forgejo/.env
docker compose -f docker-compose.forgejo.yml config --quiet
docker compose -f docker-compose.forgejo.yml up -d forgejo-db forgejo
docker compose -f docker-compose.forgejo.yml up -d
```
`gitea-mirror` is intentionally left out of the first `up` — see step 6.
5. Open `http://<host-ip>:3000`, create the first (admin) account, and
confirm repo creation/push/clone works before wiring up mirroring.
## GitHub Mirroring
`gitea-mirror` is a separate small app, not a Forgejo built-in — Forgejo
itself has no config option to bulk-pull an entire GitHub account. Once you
have a Forgejo login:
1. In Forgejo: **Settings → Applications → Generate New Token**, scopes
`repo` + `admin:org` (needed to auto-create the `github-mirrors`
destination org). Put the token in `GITEA_MIRROR_FORGEJO_TOKEN`.
2. Create a GitHub classic PAT with `repo` scope (add `read:org` if you set
`GITEA_MIRROR_ORGANIZATIONS=true`). Put it in `GITHUB_TOKEN`.
3. Start the mirror service:
```bash
docker compose -f docker-compose.forgejo.yml up -d gitea-mirror
```
With `AUTO_IMPORT_REPOS=true`, `AUTO_MIRROR_REPOS=true`, and
`SCHEDULE_ENABLED=true` (all defaulted on in the template), it imports every
repo from `GITHUB_USERNAME` on first startup and re-syncs every
`GITEA_MIRROR_INTERVAL` (default `8h`) after that — no manual per-repo setup.
Fine-tune what gets pulled via `GITEA_MIRROR_PRIVATE_REPOS`,
`GITEA_MIRROR_STARRED`, `GITEA_MIRROR_ORGANIZATIONS`, `GITEA_MIRROR_SKIP_FORKS`.
`CLEANUP_DELETE_IF_NOT_IN_GITHUB` stays `false` by default — a repo you
delete on GitHub won't get deleted in Forgejo automatically. Flip that on
deliberately if you want mirrors pruned to match GitHub exactly.
Its own UI is at `http://<host-ip>:4321` for monitoring sync status and
tweaking mirror settings beyond what's templated here.
confirm repo creation/push/clone works.
## Reverse Proxy
Add blocks for `git.<domain>` (port `FORGEJO_HTTP_PORT`) and optionally
`git-mirror.<domain>` (port `GITEA_MIRROR_PORT`) to
Add a block for `git.<domain>` (port `FORGEJO_HTTP_PORT`) to
`docker-compose-files/caddy/Caddyfile_template`, then `make reload-caddy`.
Git-over-SSH (`FORGEJO_SSH_PORT`) is not proxyable through Caddy — expose that
port directly if you want SSH clone/push from outside the LAN.
@ -128,7 +88,6 @@ port directly if you want SSH clone/push from outside the LAN.
```bash
# Tail logs
docker compose -f docker-compose.forgejo.yml logs -f forgejo
docker compose -f docker-compose.forgejo.yml logs -f gitea-mirror
# Create an additional user without open registration
docker exec -it forgejo forgejo admin user create --username <name> --email <email> --random-password

View file

@ -1,5 +1,4 @@
# Forgejo self-hosted Git service, backed by Postgres, with automatic
# mirroring of GitHub repositories via gitea-mirror.
# Forgejo self-hosted Git service, backed by Postgres.
#
# Storage split (see docs/unas/nfs-mounts.md):
# - forgejo_data (local named volume): app config, SSH host keys, session
@ -150,79 +149,6 @@ services:
max-file: "{{DOCKERLOGGING_MAXFILE}}"
max-size: "{{DOCKERLOGGING_MAXSIZE}}"
# Auto-syncs GitHub repos into Forgejo as mirrors. Forgejo itself has no
# "pull all my repos" config option — this is a separate open-source tool
# (https://github.com/RayLabsHQ/gitea-mirror) that provides exactly that,
# driven entirely by env vars below plus a one-time Forgejo API token (see
# README "GitHub mirroring" section — the token can't exist until Forgejo
# has an admin account, so it can't be templated here).
gitea-mirror:
image: ghcr.io/raylabshq/gitea-mirror:{{GITEA_MIRROR_VERSION:-latest}}
container_name: gitea-mirror
restart: unless-stopped
depends_on:
forgejo:
condition: service_healthy
environment:
NODE_ENV: production
DATABASE_URL: file:data/gitea-mirror.db
HOST: 0.0.0.0
PORT: "4321"
BASE_URL: "/"
BETTER_AUTH_SECRET: "{{GITEA_MIRROR_AUTH_SECRET}}"
BETTER_AUTH_URL: "{{GITEA_MIRROR_PUBLIC_URL}}"
PUBLIC_BETTER_AUTH_URL: "{{GITEA_MIRROR_PUBLIC_URL}}"
# GitHub source
GITHUB_USERNAME: "{{GITHUB_USERNAME}}"
GITHUB_TOKEN: "{{GITHUB_TOKEN}}"
SKIP_FORKS: "{{GITEA_MIRROR_SKIP_FORKS:-false}}"
PRIVATE_REPOSITORIES: "{{GITEA_MIRROR_PRIVATE_REPOS:-true}}"
MIRROR_STARRED: "{{GITEA_MIRROR_STARRED:-false}}"
MIRROR_ORGANIZATIONS: "{{GITEA_MIRROR_ORGANIZATIONS:-false}}"
MIRROR_ISSUES: "{{GITEA_MIRROR_ISSUES:-false}}"
MIRROR_WIKI: "{{GITEA_MIRROR_WIKI:-false}}"
# Forgejo destination — internal service name, no need to hairpin
# through the reverse proxy.
GITEA_URL: "http://forgejo:3000"
GITEA_TOKEN: "{{GITEA_MIRROR_FORGEJO_TOKEN}}"
GITEA_USERNAME: "{{GITEA_MIRROR_FORGEJO_USERNAME}}"
GITEA_ORGANIZATION: "{{GITEA_MIRROR_ORG:-github-mirrors}}"
GITEA_ORG_VISIBILITY: "{{GITEA_MIRROR_ORG_VISIBILITY:-private}}"
# Auto-import every repo on startup and keep mirroring on a schedule —
# this is the "pull all my GitHub repos via config" behavior.
AUTO_IMPORT_REPOS: "true"
AUTO_MIRROR_REPOS: "true"
SCHEDULE_ENABLED: "true"
GITEA_MIRROR_INTERVAL: "{{GITEA_MIRROR_INTERVAL:-8h}}"
CLEANUP_DELETE_IF_NOT_IN_GITHUB: "false"
CLEANUP_DRY_RUN: "true"
networks:
- forgejo_network
ports:
- "{{GITEA_MIRROR_BIND_IP:-0.0.0.0}}:{{GITEA_MIRROR_PORT:-4321}}:4321"
volumes:
- /etc/localtime:/etc/localtime:ro
- gitea_mirror_data:/app/data
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4321/api/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
deploy:
resources:
limits:
memory: "{{GITEA_MIRROR_MEM_LIMIT:-256m}}"
reservations:
memory: 64M
security_opt:
- no-new-privileges:true
logging:
driver: json-file
options:
max-file: "{{DOCKERLOGGING_MAXFILE}}"
max-size: "{{DOCKERLOGGING_MAXSIZE}}"
networks:
forgejo_network:
driver: bridge
@ -231,4 +157,3 @@ networks:
volumes:
forgejo_db_data:
forgejo_data:
gitea_mirror_data:

View file

@ -99,7 +99,7 @@ Every policy in this table uses:
| `ALLOW CADDY to Bento PDF` | `10.0.10.6` | `8080` | Bento PDF |
| `ALLOW CADDY to Koffan` | `10.0.10.12` | `8080` | Koffan (LXC 111) |
| `ALLOW CADDY to Hermes` | `10.0.10.19` | `9119` | Hermes Agent dashboard (LXC 113) |
| `ALLOW CADDY to Forgejo` | `10.0.10.18` | `3000,4321` | Forgejo (LXC 114) and gitea-mirror |
| `ALLOW CADDY to Forgejo` | `10.0.10.18` | `3000` | Forgejo (LXC 114) |
---