forked from aylac.top/nixcfg
this repo has no description

get forgejo out of the container because dealing with it on startup was annoying

aylac.top 9ab8d7af c0d0a665

verified
Changed files
+97 -179
hosts
nanpi
modules
nixos
profiles
backups
services
fail2ban
forgejo
miniflux
postgresql
+3 -3
flake.lock
···
"secrets": {
"flake": false,
"locked": {
-
"lastModified": 1756878317,
-
"narHash": "sha256-pEVF9/ZjyENenEUUqrKGO3qNngqRP1EaLf7mOS/4ol4=",
+
"lastModified": 1756947975,
+
"narHash": "sha256-Wgu/RE90hq9PixuZnlhx7UO5QXNBLWbrMN0PZnJSGX4=",
"owner": "ayla6",
"repo": "secrets",
-
"rev": "9cf93253fccc51a8a22c8fe944d80a50a24d7404",
+
"rev": "9075972fc860180bec1d885a2e00f9aa79944249",
"type": "github"
},
"original": {
+1
hosts/nanpi/secrets.nix
···
{self, ...}: {
age.secrets = {
aylaPassword.file = "${self.inputs.secrets}/ayla/passwordHash.age";
+
postgres-forgejo.file = "${self.inputs.secrets}/postgres/forgejo.age";
pds.file = "${self.inputs.secrets}/pds.age";
resticPassword.file = "${self.inputs.secrets}/restic-passwd.age";
rclone.file = "${self.inputs.secrets}/rclone.age";
+2 -3
modules/nixos/profiles/backups/default.nix
···
paths = [config.services.couchdb.databaseDir];
}
{
-
# damn this is ugly
name = "forgejo";
containerised = true;
-
inherit (config.myNixOS.services.forgejo) enable;
-
paths = ["/var/lib/nixos-containers/forgejo${config.containers.forgejo.config.services.forgejo.stateDir}"];
+
inherit (config.services.forgejo) enable;
+
paths = [config.services.forgejo.stateDir];
backupMode = "none";
}
# {
+17
modules/nixos/services/fail2ban/default.nix
···
source = config.age.secrets.cloudflareFail2ban.path;
};
+
"fail2ban/filter.d/forgejo.conf".text = ''
+
[Definition]
+
failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
+
journalmatch = _SYSTEMD_UNIT=forgejo.service
+
'';
+
"fail2ban/action.d/ntfy.conf".text = ''
[Definition]
actionban = ${mkNotify {
···
bantime-increment.enable = true;
extraPackages = [pkgs.curl pkgs.jq pkgs.uutils-coreutils-noprefix];
jails = {
+
forgejo.settings = {
+
action = ''
+
mycloudflare
+
iptables-allports
+
ntfy'';
+
bantime = 900;
+
filter = "forgejo";
+
findtime = 3600;
+
maxretry = 4;
+
};
+
# HTTP basic-auth failures, 5 tries → 1-day ban
nginx-http-auth = {
settings = {
+71 -154
modules/nixos/services/forgejo/default.nix
···
network = config.mySnippets.aylac-top;
service = network.networkMap.${name};
-
-
mkNotify = {
-
message,
-
channel,
-
priority ? 1,
-
}: ''
-
curl -u $(cat "${config.age.secrets.ntfyAuto.path}") \
-
-H "X-Priority: ${toString priority}" \
-
-d '${message}' \
-
https://${config.mySnippets.aylac-top.networkMap.ntfy.vHost}/${channel}
-
'';
in {
options.myNixOS.services.${name} = {
enable = lib.mkEnableOption "forgejo git forge";
···
config = lib.mkIf cfg.enable {
age.secrets.cloudflareFail2ban.file = "${self.inputs.secrets}/cloudflare/fail2ban.age";
-
-
services.cloudflared.tunnels."${network.cloudflareTunnel}".ingress = lib.mkIf cfg.autoProxy {
-
"${service.vHost}" = "http://${service.hostName}:${toString service.port}";
-
};
myNixOS.services.postgresql = lib.mkIf (cfg.db == "postgresql") {
enable = true;
databases = ["forgejo"];
};
-
containers.forgejo = {
-
autoStart = true;
-
bindMounts = {
-
"${config.age.secrets.cloudflareFail2ban.path}".isReadOnly = true;
-
"${config.age.secrets.ntfyAuto.path}".isReadOnly = true;
+
services = {
+
cloudflared.tunnels."${network.cloudflareTunnel}".ingress = lib.mkIf cfg.autoProxy {
+
"${service.vHost}" = "http://${service.hostName}:${toString service.port}";
};
-
config = {
-
services = {
-
postgresql.enable = lib.mkForce false;
+
forgejo = {
+
enable = true;
-
forgejo = {
-
enable = true;
+
database = lib.mkIf (cfg.db == "postgresql") {
+
createDatabase = true;
+
host = "127.0.0.1";
+
name = "forgejo";
+
passwordFile = config.age.secrets.postgres-forgejo.path;
+
type = "postgres";
+
user = "forgejo";
+
};
-
database = lib.mkIf (cfg.db
-
== "postgresql") {
-
host = "127.0.0.1";
-
name = "forgejo";
-
type = "postgres";
-
user = "forgejo";
-
socket = null;
-
};
+
lfs.enable = true;
+
package = pkgs.forgejo;
-
lfs.enable = true;
-
package = pkgs.forgejo;
+
settings = {
+
actions = {
+
ARTIFACT_RETENTION_DAYS = 15;
+
DEFAULT_ACTIONS_URL = "https://github.com";
+
ENABLED = false;
+
};
-
settings = {
-
actions = {
-
ARTIFACT_RETENTION_DAYS = 15;
-
DEFAULT_ACTIONS_URL = "https://github.com";
-
ENABLED = false;
-
};
+
cron = {
+
ENABLED = true;
+
RUN_AT_START = false;
+
};
-
cron = {
-
ENABLED = true;
-
RUN_AT_START = false;
-
};
+
DEFAULT.APP_NAME = "git.aylac.top";
+
federation.ENABLED = true;
+
indexer.REPO_INDEXER_ENABLED = true;
-
DEFAULT.APP_NAME = "git.aylac.top";
-
federation.ENABLED = true;
-
indexer.REPO_INDEXER_ENABLED = true;
+
log = {
+
ENABLE_SSH_LOG = true;
+
LEVEL = "Debug";
+
};
-
log = {
-
ENABLE_SSH_LOG = true;
-
LEVEL = "Debug";
-
};
+
mailer = {
+
ENABLED = false;
+
};
-
mailer = {
-
ENABLED = false;
-
};
+
migrations = {
+
ALLOW_LOCALNETWORKS = true;
+
};
-
migrations = {
-
ALLOW_LOCALNETWORKS = true;
-
};
+
picture = {
+
AVATAR_MAX_FILE_SIZE = 5242880;
+
ENABLE_FEDERATED_AVATAR = true;
+
};
-
picture = {
-
AVATAR_MAX_FILE_SIZE = 5242880;
-
ENABLE_FEDERATED_AVATAR = true;
-
};
+
repository = {
+
DEFAULT_BRANCH = "main";
+
ENABLE_PUSH_CREATE_ORG = true;
+
ENABLE_PUSH_CREATE_USER = true;
+
PREFERRED_LICENSES = "GPL-3.0";
+
};
-
repository = {
-
DEFAULT_BRANCH = "main";
-
ENABLE_PUSH_CREATE_ORG = true;
-
ENABLE_PUSH_CREATE_USER = true;
-
PREFERRED_LICENSES = "GPL-3.0";
-
};
-
-
security.PASSWORD_CHECK_PWN = true;
-
-
server = {
-
DOMAIN = service.vHost;
-
HTTP_PORT = service.port;
-
LANDING_PAGE = "explore";
-
LFS_START_SERVER = true;
-
ROOT_URL = "https://${service.vHost}/";
-
DISABLE_SSH = true;
-
};
-
-
service = {
-
ALLOW_ONLY_INTERNAL_REGISTRATION = true;
-
DISABLE_REGISTRATION = true;
-
ENABLE_NOTIFY_MAIL = true;
-
};
-
-
session.COOKIE_SECURE = true;
-
-
storage = {
-
STORAGE_TYPE = "local";
-
PATH = "/var/lib/forgejo/data";
-
};
+
security.PASSWORD_CHECK_PWN = true;
-
ui.DEFAULT_THEME = "forgejo-auto";
-
-
"ui.meta" = {
-
AUTHOR = "Ayla";
-
DESCRIPTION = "i can't set up ssh via cloudflare tunnels!";
-
KEYWORDS = "git,source code,forge,forgejo,aylac";
-
};
-
};
+
server = {
+
DOMAIN = service.vHost;
+
HTTP_PORT = service.port;
+
LANDING_PAGE = "explore";
+
LFS_START_SERVER = true;
+
ROOT_URL = "https://${service.vHost}/";
+
DISABLE_SSH = true;
};
-
fail2ban = {
-
enable = true;
-
ignoreIP = ["100.64.0.0/10"];
-
bantime = "24h";
-
bantime-increment.enable = true;
-
extraPackages = [pkgs.curl pkgs.jq pkgs.uutils-coreutils-noprefix];
-
jails.forgejo.settings = {
-
action = ''
-
mycloudflare
-
iptables-allports
-
ntfy'';
-
bantime = 900;
-
filter = "forgejo";
-
findtime = 3600;
-
maxretry = 4;
-
};
+
service = {
+
ALLOW_ONLY_INTERNAL_REGISTRATION = true;
+
DISABLE_REGISTRATION = true;
+
ENABLE_NOTIFY_MAIL = true;
};
-
};
-
environment.etc = {
-
"fail2ban/action.d/mycloudflare.conf" = {
-
user = "root";
-
group = "root";
-
mode = "0640";
-
source = config.age.secrets.cloudflareFail2ban.path;
-
};
+
session.COOKIE_SECURE = true;
-
"fail2ban/action.d/ntfy.conf".text = ''
-
[Definition]
-
actionban = ${mkNotify {
-
message = "Arrested <ip> for trying to rob <name> at ${config.networking.hostName}";
-
channel = "fail2ban";
-
priority = 3;
-
}}
-
actionunban = ${mkNotify {
-
message = "Released <ip> from the jail at ${config.networking.hostName}";
-
channel = "fail2ban";
-
priority = 2;
-
}}
-
'';
+
storage = {
+
STORAGE_TYPE = "local";
+
PATH = "/var/lib/forgejo/data";
+
};
-
"fail2ban/filter.d/forgejo.conf".text = ''
-
[Definition]
-
failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
-
journalmatch = _SYSTEMD_UNIT=forgejo.service
-
'';
-
};
+
ui.DEFAULT_THEME = "forgejo-auto";
-
systemd.services.forgejo = lib.mkIf (cfg.db
-
== "postgresql") {
-
after = lib.mkForce ["network.target" "forgejo-secrets.service"];
-
requires = lib.mkForce ["forgejo-secrets.service"];
+
"ui.meta" = {
+
AUTHOR = "Ayla";
+
DESCRIPTION = "i can't set up ssh via cloudflare tunnels!";
+
KEYWORDS = "git,source code,forge,forgejo,aylac";
+
};
};
-
-
system.stateVersion = "25.11";
};
-
};
-
-
systemd.services."container@forgejo" = {
-
requires = ["postgresql.service"];
-
after = ["postgresql.service"];
};
};
}
+2 -11
modules/nixos/services/miniflux/default.nix
···
config = lib.mkIf cfg.enable {
age.secrets.miniflux.file = "${self.inputs.secrets}/miniflux.age";
-
myNixOS.services.postgresql = {
-
enable = true;
-
databases = ["miniflux"];
-
};
+
myNixOS.services.postgresql.enable = true;
services = {
caddy.virtualHosts."${service.vHost}".extraConfig = lib.mkIf cfg.autoProxy ''
···
miniflux = {
enable = true;
adminCredentialsFile = config.age.secrets.miniflux.path;
-
createDatabaseLocally = false;
+
createDatabaseLocally = true;
config = {
BATCH_SIZE = 100;
CLEANUP_FREQUENCY_HOURS = 48;
LISTEN_ADDR = "${service.hostName}:${toString service.port}";
BASE_URL = "https://${service.vHost}";
-
DATABASE_URL = ''user=miniflux dbname=miniflux sslmode=disable'';
};
};
-
};
-
-
systemd.services."miniflux" = {
-
requires = ["postgresql.service"];
-
after = ["postgresql.service"];
};
};
}
+1 -8
modules/nixos/services/postgresql/default.nix
···
enable = lib.mkEnableOption "${name} server";
databases = lib.mkOption {
type = lib.types.listOf lib.types.str;
-
default = {};
+
default = [];
description = "PostgreSQL databases.";
};
};
···
ensureDBOwnership = true;
})
cfg.databases;
-
-
authentication = lib.concatStringsSep "\n" (
-
lib.map (dbName: ''
-
host ${dbName} ${dbName} samehost trust
-
'')
-
cfg.databases
-
);
};
};
}