Der Pin lag in den Dienstmodulen (hosts/{blunix,pinix}/localServices/
forgejo.nix). Auf pinix verschwand er dadurch mit der Reduktion am
12.09.2026, die forgejo.nix auskommentiert hat -- seitdem scheitert dort
jedes `git fetch` an "Host key verification failed". tnix hatte den Pin
nie, konnte also ebenfalls nicht mit Forgejo sprechen.
Es ist eine Client-Eigenschaft, keine Server-Eigenschaft: jeder Host, der
das Repo klont, braucht sie -- auch die, die Forgejo nicht betreiben.
Deshalb in globalServices, mit blunix als zusaetzlichem Hostnamen neben
der Tailnet-IP, weil die Remote-URL ssh://forgejo@blunix:2222/ lautet.
Key verifiziert am 12.09.2026: /var/lib/forgejo/data/ssh/gitea.rsa.pub auf
blunix, gelesen ueber die bereits gepinnte Port-22-Verbindung, Fingerprint
SHA256:WQro5SOdplFhw8FcMZJBjhYNrOOXCF13Z6oe57NiRXY -- identisch mit dem
ssh-keyscan von tnix und mit dem bisher hinterlegten Schluessel.
Getestet: switch auf tnix, danach `git fetch origin` erfolgreich.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ML1tzf3RKWwetud5S4TRAn
146 lines
7.1 KiB
Nix
146 lines
7.1 KiB
Nix
{ config, pkgs, ...}:
|
|
|
|
let
|
|
forgejoBackgroundCss = pkgs.runCommand "forgejo-0ff-space-background.css" { } ''
|
|
cat ${../../globalServices/branding/0ff-space-background.css} \
|
|
${./branding/forgejo-theme-override.css} \
|
|
> "$out"
|
|
'';
|
|
in
|
|
{
|
|
# Der known-hosts-Pin fuer Forgejos eingebetteten SSH-Server (Port 2222)
|
|
# steht jetzt in hosts/globalServices/forgejo-known-host.nix: ihn braucht
|
|
# jeder Host, der das Repo klont, nicht nur der, der den Dienst betreibt.
|
|
|
|
services.forgejo= {
|
|
enable = true;
|
|
lfs.enable = true;
|
|
dump.enable = true;
|
|
settings = {
|
|
service = {
|
|
ENABLE_INTERNAL_SIGNIN = true;
|
|
DISABLE_REGISTRATION = false;
|
|
ALLOW_ONLY_INTERNAL_REGISTRATION = false;
|
|
ENABLE_REGISTRATION = true;
|
|
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
|
#ENABLE_AUTO_REGISTRATION=true;
|
|
# Reduce platform-y surface area: this instance is a personal code
|
|
# showcase today, maybe a handful of collaborators later, not a
|
|
# forge for teams/CI. Issues, pull requests, and wiki stay on.
|
|
DISABLE_ORGANIZATION_CREATION = true;
|
|
};
|
|
log.level = "Debug";
|
|
# Instance-wide kill switch for mirror sync: the only mirror that
|
|
# exists today (nixos-config -> Codeberg push mirror) fails on every
|
|
# run ("branch master is the default branch and cannot be deleted",
|
|
# see docs/research/full-system-aufit.md, Executive Summary point 3
|
|
# -- not docs/review/reviewer-systemaudit-2026-09-01.md, an unrelated
|
|
# earlier audit a prior commit here mistakenly cited).
|
|
# This is a deliberate "disable, don't repair" -- it would also stop
|
|
# any future pull/push mirror on this instance, acceptable since none
|
|
# else exists yet.
|
|
mirror.DISABLED = true;
|
|
repository = {
|
|
ENABLE_PUSH_CREATE_USER = true;
|
|
DISABLED_REPO_UNITS = "repo.projects,repo.packages,repo.actions";
|
|
};
|
|
pwa = {
|
|
ENABLE_STANDALONE = true;
|
|
};
|
|
server = {
|
|
START_SSH_SERVER = true;
|
|
SSH_PORT = 2222;
|
|
# Bind only the Tailnet interface -- no public exposure, and no
|
|
# Traefik TCP passthrough needed since Forgejo now runs on the same
|
|
# host as Traefik (unlike the old pinix setup, which needed a
|
|
# passthrough to reach across the Tailnet).
|
|
SSH_LISTEN_HOST = config.tailnetIPs.blunix;
|
|
HTTP_ADDR = "127.0.0.1";
|
|
HTTP_PORT = 3000;
|
|
DOMAIN = "git.${config.domain}";
|
|
ROOT_URL = "https://git.${config.domain}/";
|
|
TRUSTED_PROXIES = "127.0.0.1";
|
|
LANDING_PAGE = "login";
|
|
# Forgejo's default (6h) made the robots.txt fix (see this file's
|
|
# tmpfiles.rules) invisible to an external reader's own cache for up
|
|
# to 6h after deploy -- verified live 2026-09-11, "private" cache
|
|
# semantics meant it wasn't even a shared/CDN caching problem to fix
|
|
# server-side, just this TTL being longer than useful whenever a
|
|
# static override here actually changes.
|
|
STATIC_CACHE_TIME = "5m";
|
|
};
|
|
session = {
|
|
PROVIDER = "file";
|
|
COOKIE_SECURE = true;
|
|
};
|
|
security = {
|
|
LOGIN_REMEMBER_DAYS = 10;
|
|
REVERSE_PROXY_TRUSTED_PROXIES = "127.0.0.1";
|
|
};
|
|
# Forgejo calls out to webhook receivers on both blunix itself
|
|
# (website/launcher/tasks auto-pull, co-located now) and pinix
|
|
# (wiki-update, gitpull-calendar-web -- receiver stays on pinix).
|
|
# "external" alone does NOT cover Tailnet (100.64.0.0/10) addresses --
|
|
# found the hard way: the tasks auto-pull hook was silently denied
|
|
# ("webhook can only call allowed HTTP servers") until both Tailnet
|
|
# IPs were listed explicitly.
|
|
webhook.ALLOWED_HOST_LIST = "external,127.0.0.1,${config.tailnetIPs.blunix},${config.tailnetIPs.pinix}";
|
|
oauth2_client = {
|
|
# Never use auto account linking with this, otherwise users cannot change
|
|
# their new user name and they could potentially overtake other users accounts
|
|
# by setting their email address to an existing account.
|
|
# With "login" linking the user must choose a non-existing username first or login
|
|
# with the existing account to link.
|
|
ACCOUNT_LINKING = "login";
|
|
USERNAME = "nickname";
|
|
# This does not mean that you cannot register via oauth, but just that there should
|
|
# be a confirmation dialog shown to the user before the account is actually created.
|
|
# This dialog allows changing user name and email address before creating the account.
|
|
ENABLE_AUTO_REGISTRATION = false;
|
|
REGISTER_EMAIL_CONFIRM = false;
|
|
UPDATE_AVATAR = true;
|
|
};
|
|
};
|
|
};
|
|
|
|
systemd.tmpfiles.rules = [
|
|
"d /var/lib/forgejo/custom/public 0750 forgejo forgejo -"
|
|
"d /var/lib/forgejo/custom/public/assets 0755 forgejo forgejo -"
|
|
"d /var/lib/forgejo/custom/public/assets/img 0755 forgejo forgejo -"
|
|
# L+ (symlink, unconditionally relinked), not C+ (copy): C+ only forces
|
|
# an overwrite when the source is a directory -- for a single regular
|
|
# file it silently degrades to "copy only if the destination doesn't
|
|
# already exist yet", so a changed source would stop reaching disk
|
|
# after the very first deploy. Found the hard way on pinix: the
|
|
# background CSS below kept serving stale content across two redeploys
|
|
# with different store paths until the destination was deleted by hand.
|
|
"L+ /var/lib/forgejo/custom/public/assets/img/logo.svg - forgejo forgejo - ${./branding/spiral-v2.svg}"
|
|
"L+ /var/lib/forgejo/custom/public/assets/img/logo.png - forgejo forgejo - ${./branding/spiral-v2-512.png}"
|
|
"L+ /var/lib/forgejo/custom/public/assets/img/apple-touch-icon.png - forgejo forgejo - ${./branding/spiral-v2-192.png}"
|
|
"L+ /var/lib/forgejo/custom/public/assets/img/favicon.svg - forgejo forgejo - ${./branding/spiral-v2.svg}"
|
|
"L+ /var/lib/forgejo/custom/public/assets/img/favicon.png - forgejo forgejo - ${./branding/spiral-v2-192.png}"
|
|
"d /var/lib/forgejo/custom/public/assets/css 0755 forgejo forgejo -"
|
|
"L+ /var/lib/forgejo/custom/public/assets/css/0ff-space-background.css - forgejo forgejo - ${forgejoBackgroundCss}"
|
|
# Overrides Forgejo's built-in default robots.txt -- see the file's own
|
|
# header comment for why (/*/*/src/ and /*/*/raw/ were blocking an
|
|
# external reader from actually reading any file content, verified
|
|
# live 2026-09-11, once git.0ff.space went external).
|
|
"L+ /var/lib/forgejo/custom/public/robots.txt - forgejo forgejo - ${./branding/forgejo-robots.txt}"
|
|
"d /var/lib/forgejo/custom/templates 0750 forgejo forgejo -"
|
|
"d /var/lib/forgejo/custom/templates/custom 0750 forgejo forgejo -"
|
|
# header.tmpl is Forgejo's documented <head> extension point -- included
|
|
# verbatim on every page, which is how the background stylesheet above
|
|
# actually gets linked in (the public/assets tree above is only served
|
|
# statically, nothing references it on its own).
|
|
"L+ /var/lib/forgejo/custom/templates/custom/header.tmpl - forgejo forgejo - ${./branding/forgejo-header.tmpl}"
|
|
];
|
|
|
|
systemd.services.forgejo.restartTriggers = [
|
|
./branding/spiral-v2.svg
|
|
./branding/spiral-v2-192.png
|
|
./branding/spiral-v2-512.png
|
|
forgejoBackgroundCss
|
|
./branding/forgejo-header.tmpl
|
|
./branding/forgejo-robots.txt
|
|
];
|
|
}
|