machines/nix/systems/aarch64-linux/kas.codes/forgejo/default.nix
Kaare Hoff Skovgaard 8e21df1764
All checks were successful
/ dev-shell (push) Successful in 33s
/ rust-packages (push) Successful in 38s
/ terraform-providers (push) Successful in 1m1s
/ check (push) Successful in 2m7s
/ systems (push) Successful in 3m52s
Add some more alerting and fail2ban rules
2025-07-22 15:17:17 +02:00

223 lines
6.3 KiB
Nix

{ config, pkgs, ... }:
let
home_forgejo = pkgs.writeText "home_forgejo.tmpl" ''
<div class="ui stackable middle very relaxed page grid">
<div class="eight wide center column">
<h1 class="hero ui icon header">
{{svg "octicon-person"}}
</h1>
<p class="large">
This is just a personal self hosted software forge for my projects. I might publish a few things here for public consumption.
</p>
</div>
<div class="eight wide center column">
<h1 class="hero ui icon header">
{{svg "octicon-code"}}
</h1>
<p class="large">
This server is running <a target="_blank" rel="noopener noreferrer" href="https://forgejo.org">Forgejo</a>. Click the link to learn more.
</p>
</div>
</div>
'';
# This simply has the <h2> tag removed.
home = pkgs.writeText "home.tmpl" ''
{{template "base/head" .}}
<div role="main" aria-label="{{if .IsSigned}}{{ctx.Locale.Tr "dashboard"}}{{else}}{{ctx.Locale.Tr "home"}}{{end}}" class="page-content home">
<div class="tw-mb-8 tw-px-8">
<div class="center">
<img class="logo" width="220" height="220" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}">
<div class="hero">
<h1 class="ui icon header title">
{{AppDisplayName}}
</h1>
</div>
</div>
</div>
{{template "home_forgejo" .}}
</div>
{{template "base/footer" .}}
'';
in
{
imports = [ ./oauth.nix ];
khscodes.services.vault-agent.templates = [
{
contents = ''
{{- with secret "forgejo/data/mailserver/users/forgejo" -}}
{{ .Data.data.password }}
{{- end -}}
'';
destination = "/var/lib/vault-agent/forgejo/mailserver/forgejo.passwd";
perms = "0600";
owner = "git";
group = "git";
restartUnits = [
"forgejo.service"
];
}
];
systemd.services.forgejo = {
unitConfig = {
ConditionPathExists = [ "/var/lib/vault-agent/forgejo/mailserver/forgejo.passwd" ];
};
};
services.forgejo = {
enable = true;
user = "git";
group = "git";
settings = {
DEFAULT = {
APP_NAME = "KAS: Codes";
};
metrics = {
ENABLED = true;
};
server = rec {
DOMAIN = "kas.codes";
ROOT_URL = "https://${DOMAIN}";
};
session = {
COOKIE_SECURE = true;
};
service = {
DISABLE_REGISTRATION = true;
ENABLE_INTERNAL_SIGNIN = false;
};
repository = {
DEFAULT_REPO_UNITS = "repo.code,repo.releases,repo.issues,repo.packages,repo.actions";
};
mailer = {
ENABLED = true;
SMTP_ADDR = "kas.codes";
FROM = "forgejo@kas.codes";
USER = "forgejo@kas.codes";
};
"ui.meta" = {
AUTHOR = "Kaare Hoff Skovgaard <kaare@kaareskovgaard.net>";
DESCRIPTION = "A self-hosted software forge for KAS/KHS";
KEYWORDS = "khs,kas,kastermester,code";
};
actions = {
DEFAULT_ACTIONS_URL = "https://kas.codes";
};
oauth2_client = {
ENABLE_AUTO_REGISTRATION = true;
USERNAME = "nickname";
ACCOUNT_LINKING = "disabled";
REGISTER_EMAIL_CONFIRM = false;
};
};
secrets.mailer.PASSWD = "/var/lib/vault-agent/forgejo/mailserver/forgejo.passwd";
lfs = {
enable = true;
};
database = {
type = "postgres";
user = "git";
name = "git";
};
dump = {
enable = true;
file = "forgejo-dump";
};
};
systemd.services.write-forgejo-templates = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
before = [ "forgejo.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = pkgs.lib.getExe (
pkgs.writeShellApplication {
name = "write-forgejo-templates";
runtimeInputs = [ pkgs.uutils-coreutils-noprefix ];
text = ''
if [ ! -d /var/lib/forgejo/custom/templates ]; then
mkdir /var/lib/forgejo/custom/templates
fi
ln -sf ${home_forgejo} /var/lib/forgejo/custom/templates/home_forgejo.tmpl
ln -sf ${home} /var/lib/forgejo/custom/templates/home.tmpl
'';
}
);
};
};
users.users.forgejo-backup = {
isNormalUser = true;
home = "/home/forgejo-backup";
group = "forgejo-backup";
createHome = true;
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ/hn4Q1+5KpViol+Kk7bUvWrka2hhKEXqUJVY0quQLu forgejo-backup@truenas.kaareskovgaard.net"
];
};
users.groups.forgejo-backup = { };
systemd.timers.forgejo-dump = {
timerConfig = {
Unit = "forgejo-copy-dump.service";
};
};
systemd.services.forgejo-copy-dump = {
requires = [ "forgejo-dump.service" ];
after = [ "forgejo-dump.service" ];
wantedBy = [ "timers.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = pkgs.lib.getExe (
pkgs.writeShellApplication {
name = "forgejo-copy-dump";
runtimeInputs = [ pkgs.uutils-coreutils-noprefix ];
text = ''
mv /var/lib/forgejo/dump/forgejo-dump.zip /home/forgejo-backup/dump.zip
chown forgejo-backup:forgejo-backup /home/forgejo-backup/dump.zip
chmod 0640 /home/forgejo-backup/dump.zip
'';
}
);
};
};
khscodes.services.nginx = {
enable = true;
virtualHosts = {
"kas.codes" = {
extraConfig = ''
client_max_body_size 32M;
'';
locations."/" = {
proxyPass = "http://localhost:3000";
};
locations."/metrics" = {
return = "404";
};
};
};
};
users.users.git = {
isSystemUser = true;
group = "git";
home = config.services.forgejo.stateDir;
useDefaultShell = true;
};
users.groups.git = { };
environment.etc."alloy/forgejo_prometheus.alloy" = {
text = ''
prometheus.scrape "forgejo_exporter" {
scrape_interval = "1m"
targets = [
{
"__address__" = "127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}",
},
]
metrics_path = "/metrics"
forward_to = [otelcol.receiver.prometheus.default.receiver]
}
'';
};
}