nix/profiles/forgejo.nix

143 lines
No EOL
5 KiB
Nix

{ 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}";
};
"markup.asciidoctor" = {
ENABLED = true;
NEED_POSTPROCESS = true;
FILE_EXTENSIONS = ".adoc,.asciidoc";
RENDER_COMMAND = "asciidoctor --embedded --safe-mode=secure --out-file=- -";
IS_INPUT_FILE = false;
};
};
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.path = [ pkgs.asciidoctor ];
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 ];
}