README documents what FlexHub is (rebrand of git.s8n.ru), the git.s8n.ru/flexhub.s8n.ru hostname split, and the layout of the Forgejo custom/ tree. docs/DEPLOY.md covers updating the homepage template, theme CSS, app.ini, image assets, and the Traefik file provider router on nullstone. Repo previously contained only a one-line README + the home.tmpl override; this fills in the operator-facing docs so flexhub becomes the canonical project page (referenced as a mirror by ARRFLIX).
5.7 KiB
Deploying FlexHub customisations
These notes cover updating an already-running FlexHub. If you're
standing up Forgejo from scratch on a new host, follow the
operator-internal runbook at _github/infra/forgejo/DEPLOY.md in the
ai-lab repo first, then come back here for the rebrand layer.
All paths below are on nullstone (the host running the Forgejo
container). The container is named forgejo. Host UID 1000 owns the
data tree.
Layout on nullstone
/opt/docker/forgejo/
└── docker-compose.yml ← image tag, env, traefik labels
/home/docker/forgejo/
├── data/
│ └── gitea/
│ └── custom/ ← Forgejo "override" tree
│ ├── conf/app.ini ← APP_NAME, DEFAULT_THEME, THEMES
│ ├── templates/
│ │ └── home.tmpl ← homepage (mirror of this repo)
│ └── public/assets/
│ ├── css/theme-flexhub.css
│ └── img/ ← logos + favicons
└── config/ ← Forgejo-managed; don't hand-edit
custom/ is the only path you ever edit by hand. Everything in this
repo maps 1:1 into that tree.
Update the homepage template
Edit templates/home.tmpl here, then on nullstone:
ssh nullstone bash <<'EOF'
sudo cp /tmp/home.tmpl /home/docker/forgejo/data/gitea/custom/templates/home.tmpl
sudo chown 1000:1000 /home/docker/forgejo/data/gitea/custom/templates/home.tmpl
EOF
Forgejo hot-reloads templates — no container restart needed. Hit https://flexhub.s8n.ru/ and hard-refresh (Ctrl+Shift+R) to confirm.
If the page renders blank, check the Forgejo log for a template parse error:
ssh nullstone 'docker logs --tail 50 forgejo 2>&1 | grep -i template'
The wrapping {{template "base/head" .}} and {{template "base/footer" .}}
calls are mandatory — drop them and you get a half-page.
Update the theme CSS
Edit public/assets/css/theme-flexhub.css, copy to nullstone:
ssh nullstone bash <<'EOF'
sudo cp /tmp/theme-flexhub.css \
/home/docker/forgejo/data/gitea/custom/public/assets/css/theme-flexhub.css
sudo chown 1000:1000 \
/home/docker/forgejo/data/gitea/custom/public/assets/css/theme-flexhub.css
EOF
CSS is served static — no reload needed. The theme is selected
per-user via DEFAULT_THEME = flexhub in app.ini (see next section)
and is overridable in user settings.
The brand palette is orange #FF9000 / black #000 / white #FFF.
Don't drift.
Bump APP_NAME or theme list
app.ini lives at /home/docker/forgejo/data/gitea/custom/conf/app.ini
on nullstone (Forgejo merges custom values over its built-in defaults).
The relevant keys:
APP_NAME = FlexHub
DEFAULT_THEME = flexhub
THEMES = forgejo-auto,forgejo-light,forgejo-dark,flexhub,veilor
After editing app.ini you must restart the container — env-style
INI is read at boot only:
ssh nullstone 'cd /opt/docker/forgejo && docker compose restart forgejo'
Watch the log come back clean:
ssh nullstone 'docker logs -f --tail 30 forgejo'
You're good when you see Listen: http://0.0.0.0:3000. The web UI
should now show the new title bar / theme list.
Add a new template override
Forgejo template hierarchy: https://forgejo.org/docs/latest/admin/customization/#changing-the-look-of-forgejo. The general flow:
- Find the upstream template in the Forgejo source tree
(
templates/...). - Copy its full content into
custom/templates/<same path>.tmplon nullstone, owned1000:1000. - Edit your override.
- Mirror the file into this repo under
templates/<same path>.tmplso the repo stays the source of truth.
Hot-reload applies — no container restart.
If the override stops rendering after a Forgejo version bump, diff your override against the new upstream template — base layout slots sometimes get renamed across major versions.
Add a new image asset
scp my-asset.png nullstone:/tmp/
ssh nullstone bash <<'EOF'
sudo cp /tmp/my-asset.png \
/home/docker/forgejo/data/gitea/custom/public/assets/img/my-asset.png
sudo chown 1000:1000 \
/home/docker/forgejo/data/gitea/custom/public/assets/img/my-asset.png
EOF
Reachable at https://flexhub.s8n.ru/assets/img/my-asset.png. No
container restart.
When replacing favicons specifically, also clear the browser cache — favicons are aggressively cached.
Traefik routing for flexhub.s8n.ru
The FlexHub-branded hostname is wired in via a file-provider router
(/opt/docker/traefik/config/dynamic.yml on nullstone), not via the
docker-provider labels on the Forgejo compose file. This is intentional:
git.s8n.ru— docker-provider router,no-guest@filemiddleware.flexhub.s8n.ru— file-provider router, public, rate-limit only.
The file-provider router defines its own service
(flexhub-svc) pointing at http://forgejo:3000 directly, rather than
referencing forgejo@docker. This works around a startup race where
file-provider routers can resolve before docker-provider services are
populated, leaving the router permanently broken with
the service "forgejo@docker" does not exist.
If you change the Forgejo container name or move it off the proxy
network, update flexhub-svc.loadBalancer.servers[0].url in
dynamic.yml to match.
Rollback
The customisations are pure overlay files. To revert FlexHub branding:
ssh nullstone bash <<'EOF'
sudo mv /home/docker/forgejo/data/gitea/custom /home/docker/forgejo/data/gitea/custom.disabled
EOF
ssh nullstone 'cd /opt/docker/forgejo && docker compose restart forgejo'
Forgejo falls back to vanilla theme + homepage. Nothing in the data
store changes. Restore by renaming custom.disabled back to custom.