initial commit
This commit is contained in:
commit
90cff4f16a
59 changed files with 6855 additions and 0 deletions
409
Hetzner/axiomania.nix
Normal file
409
Hetzner/axiomania.nix
Normal file
|
|
@ -0,0 +1,409 @@
|
|||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [ ./common.nix ];
|
||||
|
||||
networking.hostName = "axiomania";
|
||||
|
||||
# ============================================================================
|
||||
# Firewall
|
||||
# ============================================================================
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 22 80 443 2222 ];
|
||||
allowedUDPPorts = [ 51820 53 ]; # Wireguard, Adguard DNS
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Forgejo
|
||||
# ============================================================================
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
database.type = "sqlite3";
|
||||
settings = {
|
||||
DEFAULT.APP_NAME = "Axiomania Git";
|
||||
|
||||
server = {
|
||||
DOMAIN = "git.axiomania.org";
|
||||
ROOT_URL = "https://git.axiomania.org/";
|
||||
HTTP_ADDR = "127.0.0.1";
|
||||
HTTP_PORT = 3000;
|
||||
SSH_DOMAIN = "git.axiomania.org";
|
||||
SSH_PORT = 2222;
|
||||
START_SSH_SERVER = true;
|
||||
};
|
||||
|
||||
service = {
|
||||
DISABLE_REGISTRATION = true;
|
||||
DEFAULT_KEEP_EMAIL_PRIVATE = true;
|
||||
};
|
||||
|
||||
repository = {
|
||||
DEFAULT_PRIVATE = "private";
|
||||
};
|
||||
|
||||
api = {
|
||||
ENABLE_SWAGGER = false;
|
||||
};
|
||||
|
||||
session = {
|
||||
COOKIE_SECURE = true;
|
||||
};
|
||||
|
||||
actions = {
|
||||
ENABLED = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Forgejo Actions Runner
|
||||
# ============================================================================
|
||||
# Requires a registration token from Forgejo.
|
||||
# Generate one: ssh root@178.104.15.221, then:
|
||||
# forgejo-runner register (follow prompts)
|
||||
# Or via Forgejo web UI: Site Administration > Runners > Create Runner
|
||||
# Then put the token in /var/lib/forgejo-runner/token
|
||||
services.gitea-actions-runner.instances.default = {
|
||||
enable = true;
|
||||
name = "axiomania";
|
||||
url = "https://git.axiomania.org";
|
||||
tokenFile = "/var/lib/forgejo-runner/token";
|
||||
labels = [ "native:host" ];
|
||||
hostPackages = with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
curl
|
||||
gawk
|
||||
git
|
||||
gnused
|
||||
nodejs
|
||||
nix
|
||||
];
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Vaultwarden (Bitwarden-compatible password manager)
|
||||
# ============================================================================
|
||||
services.vaultwarden = {
|
||||
enable = true;
|
||||
config = {
|
||||
DOMAIN = "https://vault.axiomania.org";
|
||||
SIGNUPS_ALLOWED = false;
|
||||
ROCKET_ADDRESS = "127.0.0.1";
|
||||
ROCKET_PORT = 8222;
|
||||
};
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Navidrome (music streaming)
|
||||
# ============================================================================
|
||||
services.navidrome = {
|
||||
enable = true;
|
||||
settings = {
|
||||
Address = "127.0.0.1";
|
||||
Port = 4533;
|
||||
MusicFolder = "/var/lib/navidrome/music";
|
||||
};
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Syncthing (file sync)
|
||||
# ============================================================================
|
||||
services.syncthing = {
|
||||
enable = true;
|
||||
openDefaultPorts = true;
|
||||
dataDir = "/var/lib/syncthing";
|
||||
settings.gui.insecureSkipHostcheck = true;
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Attic (Nix binary cache)
|
||||
# ============================================================================
|
||||
# Requires a secret generated on the server:
|
||||
# openssl genrsa -traditional 4096 | base64 -w0 > /var/lib/atticd/token-secret
|
||||
# echo "ATTIC_SERVER_TOKEN_RS256_SECRET_BASE64=$(cat /var/lib/atticd/token-secret)" > /etc/atticd.env
|
||||
services.atticd = {
|
||||
enable = true;
|
||||
environmentFile = "/etc/atticd.env";
|
||||
settings = {
|
||||
listen = "[::]:8080";
|
||||
storage = {
|
||||
type = "local";
|
||||
path = "/var/lib/atticd/storage";
|
||||
};
|
||||
garbage-collection = {
|
||||
default-retention-period = "3 months";
|
||||
};
|
||||
chunking = {
|
||||
nar-size-threshold = 65536;
|
||||
min-size = 16384;
|
||||
avg-size = 65536;
|
||||
max-size = 262144;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Kavita (ebook library)
|
||||
# ============================================================================
|
||||
# Generate token on the server:
|
||||
# openssl rand -hex 128 > /var/lib/kavita/token-key
|
||||
services.kavita = {
|
||||
enable = true;
|
||||
settings.Port = 5000;
|
||||
tokenKeyFile = "/var/lib/kavita/token-key";
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Audiobookshelf
|
||||
# ============================================================================
|
||||
services.audiobookshelf = {
|
||||
enable = true;
|
||||
port = 8234;
|
||||
host = "127.0.0.1";
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Paperless-ngx (document management)
|
||||
# ============================================================================
|
||||
services.paperless = {
|
||||
enable = true;
|
||||
port = 28981;
|
||||
address = "127.0.0.1";
|
||||
domain = "docs.axiomania.org";
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Adguard Home (DNS ad blocker)
|
||||
# ============================================================================
|
||||
# Use as DNS server via Wireguard: set DNS = 10.100.0.1 in client config
|
||||
services.adguardhome = {
|
||||
enable = true;
|
||||
port = 3300;
|
||||
host = "127.0.0.1";
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# SearXNG (private search engine)
|
||||
# ============================================================================
|
||||
# Generate secret on the server:
|
||||
# echo "SEARX_SECRET=$(openssl rand -hex 32)" > /etc/searx/secrets.env
|
||||
services.searx = {
|
||||
enable = true;
|
||||
redisCreateLocally = true;
|
||||
settings = {
|
||||
server = {
|
||||
bind_address = "127.0.0.1";
|
||||
port = 8888;
|
||||
secret_key = "$SEARX_SECRET";
|
||||
};
|
||||
};
|
||||
environmentFile = "/etc/searx/secrets.env";
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Homepage (services dashboard)
|
||||
# ============================================================================
|
||||
services.homepage-dashboard = {
|
||||
enable = true;
|
||||
listenPort = 8082;
|
||||
allowedHosts = "home.axiomania.org";
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Matrix Conduit (encrypted messaging)
|
||||
# ============================================================================
|
||||
services.matrix-conduit = {
|
||||
enable = true;
|
||||
settings.global = {
|
||||
server_name = "axiomania.org";
|
||||
port = 6167;
|
||||
address = "127.0.0.1";
|
||||
allow_registration = false;
|
||||
};
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Gokapi (file sharing) — disabled due to CVEs in stable
|
||||
# ============================================================================
|
||||
# services.gokapi = {
|
||||
# enable = true;
|
||||
# environment = {
|
||||
# GOKAPI_PORT = 53842;
|
||||
# };
|
||||
# };
|
||||
|
||||
# ============================================================================
|
||||
# Wireguard VPN
|
||||
# ============================================================================
|
||||
# Generate keys on the server:
|
||||
# wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
|
||||
networking.wireguard.interfaces.wg0 = {
|
||||
ips = [ "10.100.0.1/24" ];
|
||||
listenPort = 51820;
|
||||
privateKeyFile = "/etc/wireguard/private.key";
|
||||
peers = [
|
||||
{
|
||||
# Minisforum V3 SE (local NixOS machine)
|
||||
publicKey = "rEsHqzJVnv9AoOIEVTrdEF3x4G6rWxXqHLXTzAx88gc=";
|
||||
allowedIPs = [ "10.100.0.2/32" ];
|
||||
}
|
||||
{
|
||||
# Pixel 5
|
||||
publicKey = "jP+rYdc8qKdNY4l3PDFmGiOA31SnJRgcmQIVu6AJ9EM=";
|
||||
allowedIPs = [ "10.100.0.3/32" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
# NAT for Wireguard clients to access the internet
|
||||
networking.nat = {
|
||||
enable = true;
|
||||
externalInterface = "ens3";
|
||||
internalInterfaces = [ "wg0" ];
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Nginx reverse proxy + ACME
|
||||
# ============================================================================
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
|
||||
# ── Public services ──
|
||||
virtualHosts."git.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:3000";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."matrix.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:6167";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."cache.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://[::1]:8080";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
|
||||
# ── VPN-only services (WireGuard clients only) ──
|
||||
virtualHosts."vault.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8222";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."music.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:4533";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."sync.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8384";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."books.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:5000";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."audio.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8234";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."docs.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:28981";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."search.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8888";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."home.axiomania.org" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:8082";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;";
|
||||
};
|
||||
};
|
||||
|
||||
# virtualHosts."share.axiomania.org" = {
|
||||
# enableACME = true;
|
||||
# forceSSL = true;
|
||||
# locations."/" = {
|
||||
# proxyPass = "http://127.0.0.1:53842";
|
||||
# proxyWebsockets = true;
|
||||
# };
|
||||
# };
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "gamma.kinematics@gmail.com";
|
||||
};
|
||||
|
||||
# ============================================================================
|
||||
# Packages
|
||||
# ============================================================================
|
||||
environment.systemPackages = with pkgs; [
|
||||
git
|
||||
vim
|
||||
htop
|
||||
wireguard-tools
|
||||
];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue