flexhub/docs/DEPLOY.md
s8n db1d54ada1 docs: real README + deploy notes for FlexHub branding
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).
2026-05-10 06:18:06 +01:00

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:

  1. Find the upstream template in the Forgejo source tree (templates/...).
  2. Copy its full content into custom/templates/<same path>.tmpl on nullstone, owned 1000:1000.
  3. Edit your override.
  4. Mirror the file into this repo under templates/<same path>.tmpl so 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@file middleware.
  • 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.