Merge branch 'master' of git.federez.net:federez/nix

This commit is contained in:
jeltz 2025-07-06 23:05:03 +02:00
commit c8a1985d96
Signed by: jeltz
GPG key ID: 800882B66C0C3326
35 changed files with 1100 additions and 754 deletions

134
profiles/forgejo.nix Normal file
View file

@ -0,0 +1,134 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.forgejo;
secrets = config.age.secrets;
domain = "federez.net";
fqdn = "git.${domain}";
hasValidLastOctet =
config ? vogon.networking.last-octet &&
builtins.length config.vogon.networking.last-octet >= 2;
lastOctetValues =
if hasValidLastOctet
then config.vogon.networking.last-octet
else abort ''Forgejo can only be deploy on vogon for now,
and it requires two public ip address, the first one
for ssh access from wan, and the second for the
forgejo dedicated ssh server'';
sys-ip = "193.54.193.${toString (builtins.elemAt lastOctetValues 0)}";
git-ip = "193.54.193.${toString (builtins.elemAt lastOctetValues 1)}";
in
{
age.secrets = lib.mapAttrs
(_: f: { file = f; owner = cfg.user; group = cfg.group; })
{
forgejo-db-pass = ../secrets/forgejo-db-pass.age;
forgejo-wizard-user-pass = ../secrets/forgejo-wizard-user-pass.age;
forgejo-mailbox-pass = ../secrets/forgejo-mailbox-pass.age;
};
backups = {
directories = [ cfg.stateDir ];
postgresqlDatabases = [ cfg.database.name ];
};
services.openssh.startWhenNeeded = false;
services.forgejo = {
enable = true;
user = "forgejo";
package = pkgs.forgejo;
stateDir = "/var/lib/forgejo";
database = {
name = "forgejo";
type = "postgres";
socket = "/var/run/postgresql";
passwordFile = secrets.forgejo-db-pass.path;
};
# Enable support for Git Large File Storage
lfs.enable = true;
settings = {
server = {
DOMAIN = "${fqdn}";
ROOT_URL = "https://${fqdn}/";
HTTP_PORT = 3000;
SSH_LISTEN_HOST = "${git-ip}";
SSH_PORT = 22;
SSH_LISTEN_PORT = 22;
START_SSH_SERVER = true;
# Forgejo is installed under the forgejo user
# The builtin ssh server user must match this
BUILTIN_SSH_SERVER_USER = "${cfg.user}";
};
service = {
# Disable internal registration only
DISABLE_REGISTRATION = true;
ALLOW_ONLY_EXTERNAL_REGISTRATION = false;
ENABLE_INTERNAL_SIGNIN = true;
ENABLE_BASIC_AUTHENTICATION = true;
ENABLE_NOTIFY_MAIL = true;
# Privacy
DEFAULT_KEEP_EMAIL_PRIVATE = true;
DEFAULT_USER_VISIBILITY = "private";
};
repository = {
# Enable git clone over HTTP
DISABLE_HTTP_GIT = false;
};
mailer = {
ENABLED = true;
SMTP_ADDR = "${domain}";
SMTP_PORT = 465;
FROM = "forge@${domain}";
USER = "forge@${domain}";
};
};
secrets = {
mailer = {
PASSWD = secrets.forgejo-mailbox-pass.path;
};
};
};
systemd.services.forgejo.preStart = let
adminCmd = "${lib.getExe cfg.package} admin user";
pwd = secrets.forgejo-wizard-user-pass.path;
# Note, Forgejo doesn't allow creation of an account named "admin"
# Note: that username MUST be unpickable by a user signin-up to re2o endpoint
# WARN: Never change the username without deleting manually the account (it will otherwise continue to exists)
user = "wizard";
in ''
# || true -> avoid systemd to crash on that command if user already exist by forcing a 0 return value
${adminCmd} create --admin --email "admin@federez.net" --username ${user} --password "$(tr -d '\n' < ${pwd})" || true
${adminCmd} change-password --username ${user} --password "$(tr -d '\n' < ${pwd})" || true
'';
systemd.services.forgejo.serviceConfig = {
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
PrivateUsers = lib.mkForce false;
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"git.federez.net" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://localhost:${toString cfg.settings.server.HTTP_PORT}";
extraConfig = ''
client_max_body_size 1G;
'';
};
};
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
}

View file

@ -12,6 +12,9 @@ in
gitlab-otp-secret = ../secrets/gitlab-otp-secret.age;
gitlab-db-secret = ../secrets/gitlab-db-secret.age;
gitlab-jws-secret = ../secrets/gitlab-jws-secret.age;
gitlab-arpk-secret = ../secrets/gitlab-arpk-secret.age;
gitlab-ardk-secret = ../secrets/gitlab-ardk-secret.age;
gitlab-ars-secret = ../secrets/gitlab-ars-secret.age;
gitlab-db-password = ../secrets/gitlab-db-password.age;
gitlab-initial-root-password = ../secrets/gitlab-initial-root-password.age;
gitlab-ldap-password = ../secrets/gitlab-ldap-password.age;
@ -22,9 +25,15 @@ in
postgresqlDatabases = [ cfg.databaseName ];
};
# If you ever want to update gitlab, even despite Forgejo being in deployment:
# 1. Make a proper gitlab backup
# 2. Uncomment all commented line below
# 3. Run colmena
# 4. Restore the backup previously saved
services.gitlab = {
enable = true;
host = "gitlab2.federez.net";
port = 443;
https = true;
databasePasswordFile = secrets.gitlab-db-password.path;
initialRootPasswordFile = secrets.gitlab-initial-root-password.path;
@ -33,6 +42,9 @@ in
otpFile = secrets.gitlab-otp-secret.path;
dbFile = secrets.gitlab-db-secret.path;
jwsFile = secrets.gitlab-jws-secret.path;
# activeRecordPrimaryKeyFile = secrets.gitlab-arpk-secret.path;
# activeRecordDeterministicKeyFile = secrets.gitlab-ardk-secret.path;
# activeRecordSaltFile = secrets.gitlab-ars-secret.path;
};
extraConfig.ldap = {
enabled = true;
@ -55,6 +67,11 @@ in
};
};
# services.postgresql = {
# enable = true;
# package = pkgs.postgresql_16;
# };
services.nginx = {
enable = true;
recommendedProxySettings = true;

View file

@ -1,40 +1,58 @@
{ config, lib, ... }:
{ config, lib, network, name, ... }:
let
inherit (lib) mkOption types;
cfg = config.vogon;
node = network.infra.nodes.${name};
in
{
options.vogon = {
networking = {
last-octet = mkOption {
type = types.ints.between 161 174;
description = '''
Dernier octet de l'IPv4 de la machine.
type = types.listOf (types.ints.between 161 174);
description = ''
Liste des derniers octets de l'IPv4 de la machine.
'';
example = 163;
example = [ 163 165 ];
};
wan-mac = mkOption {
type = types.str;
description = '''
description = ''
Adresse MAC de l'interface réseau WAN
qui portera l'IPv4 interne.
'';
example = "BC:24:11:B7:AE:80";
};
ssh-octets = mkOption {
type = types.listOf (types.ints.between 161 174);
default = [ (builtins.head cfg.networking.last-octet) ];
defaultText = "[ (first element of last-octet) ]";
description = ''
Liste des octets à utiliser pour la configuration SSH.
Par défaut, utilise le premier élément de last-octet.
'';
example = [ 163 165 ];
};
};
};
config.systemd.network = {
links."10-wan" = {
matchConfig.MACAddress = cfg.networking.wan-mac;
linkConfig.Name = "wan";
};
networks."10-wan" = {
matchConfig.Name = "wan";
address = [ "193.54.193.${toString cfg.networking.last-octet}/28" ];
routes = [ { Gateway = "193.54.193.174"; } ];
linkConfig.RequiredForOnline = "routable";
config = {
systemd.network = {
links."10-wan" = {
matchConfig.MACAddress = cfg.networking.wan-mac;
linkConfig.Name = "wan";
};
networks."10-wan" = {
matchConfig.Name = "wan";
address = map (octet: "193.54.193.${toString octet}/28") cfg.networking.last-octet;
routes = [ { Gateway = "193.54.193.174"; } ];
linkConfig.RequiredForOnline = "routable";
};
};
services.openssh.listenAddresses = [
{ addr = node.ipv4; port = 22; }
{ addr = node.ipv6; port = 22; }
] ++ map (octet: { addr = "193.54.193.${toString octet}"; port = 22; }) cfg.networking.ssh-octets;
};
}