2024-11-15 22:00:01 -09:00
|
|
|
{
|
|
|
|
|
config,
|
|
|
|
|
username,
|
|
|
|
|
hostname,
|
|
|
|
|
pkgs,
|
|
|
|
|
lib,
|
|
|
|
|
nix-index-database,
|
|
|
|
|
inputs,
|
|
|
|
|
specialArgs,
|
|
|
|
|
...
|
|
|
|
|
}: let
|
|
|
|
|
ddnsPkg = import ./invoke-ddns {inherit pkgs;};
|
|
|
|
|
|
|
|
|
|
startSeq = builtins.fromJSON ''"\u001b[7m"''; # Start inverted color
|
|
|
|
|
endSeq = builtins.fromJSON ''"\u001b[27m"''; # End inverted color
|
|
|
|
|
motd = "${startSeq} Welcome to the Peterson Mainframe! Look, touch, but DO NOT LICK. ${endSeq}";
|
|
|
|
|
|
|
|
|
|
nixPkgs = specialArgs.nixPkgs;
|
|
|
|
|
ourRustVersion = pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.complete);
|
|
|
|
|
|
|
|
|
|
ourRustPlatform = nixPkgs.makeRustPlatform {
|
|
|
|
|
rustc = ourRustVersion;
|
|
|
|
|
cargo = ourRustVersion;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pullomaticPkg = import ./pullomatic {
|
|
|
|
|
inherit lib pkgs;
|
|
|
|
|
rustPlatform = ourRustPlatform;
|
|
|
|
|
specialArgs = {};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pullomatic = "${pullomaticPkg}/bin/pullomatic";
|
2024-12-06 23:48:02 -09:00
|
|
|
|
2024-11-15 22:00:01 -09:00
|
|
|
in {
|
|
|
|
|
imports = [
|
|
|
|
|
(import ./cloned_repos {inherit pkgs pullomatic lib;})
|
|
|
|
|
(import ./firewall.nix {inherit pkgs;})
|
2024-12-24 02:49:21 -09:00
|
|
|
(import ./nginx.nix {inherit pkgs lib config;})
|
2024-11-15 22:00:01 -09:00
|
|
|
(import ./system/users.nix {inherit pkgs config lib nix-index-database;})
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
time.timeZone = "America/Anchorage";
|
|
|
|
|
|
2024-12-22 02:23:47 -09:00
|
|
|
age.secrets = {
|
|
|
|
|
nearlyfreespeech = {
|
|
|
|
|
file = ./secrets/nearlyfreespeech.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
webdav = {
|
|
|
|
|
file = ./secrets/webdav.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
2026-05-04 13:44:07 -08:00
|
|
|
|
|
|
|
|
anthropic-api-key = {
|
|
|
|
|
file = ./secrets/anthropic-api-key.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
2026-05-23 20:12:53 -08:00
|
|
|
|
|
|
|
|
postmark = {
|
|
|
|
|
file = ./secrets/postmark.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
2026-05-24 23:03:36 -08:00
|
|
|
|
|
|
|
|
forgejo-runner-token = {
|
|
|
|
|
file = ./secrets/forgejo-runner-token.age;
|
2026-05-24 23:31:05 -08:00
|
|
|
owner = "root";
|
2026-05-24 23:03:36 -08:00
|
|
|
};
|
2026-05-25 17:08:15 -08:00
|
|
|
|
|
|
|
|
vnc-password = {
|
|
|
|
|
file = ./secrets/vnc-password.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
vnc-htpasswd = {
|
|
|
|
|
file = ./secrets/vnc-htpasswd.age;
|
|
|
|
|
owner = "nginx";
|
|
|
|
|
};
|
2026-06-05 21:58:17 -08:00
|
|
|
|
|
|
|
|
paperless = {
|
|
|
|
|
file = ./secrets/paperless.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
2026-06-08 03:49:55 -08:00
|
|
|
|
|
|
|
|
coldairnetworks = {
|
|
|
|
|
file = ./secrets/coldairnetworks.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
2026-06-20 08:39:19 -08:00
|
|
|
|
|
|
|
|
openai-api-key = {
|
|
|
|
|
file = ./secrets/openai-api-key.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
2026-06-23 01:40:51 -08:00
|
|
|
|
|
|
|
|
coldairnetworks-db-postgres = {
|
|
|
|
|
file = ./secrets/coldairnetworks-db-postgres.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
coldairnetworks-db-pgadmin = {
|
|
|
|
|
file = ./secrets/coldairnetworks-db-pgadmin.age;
|
|
|
|
|
owner = "root";
|
|
|
|
|
};
|
2024-12-22 02:23:47 -09:00
|
|
|
};
|
2024-11-15 22:00:01 -09:00
|
|
|
|
|
|
|
|
environment.systemPackages = [
|
|
|
|
|
ddnsPkg
|
|
|
|
|
pullomaticPkg
|
|
|
|
|
pkgs.vim
|
|
|
|
|
pkgs.php
|
|
|
|
|
pkgs.rustc
|
|
|
|
|
pkgs.cargo
|
|
|
|
|
pkgs.util-linux
|
|
|
|
|
pkgs.iotop
|
|
|
|
|
pkgs.rust-bin.stable.latest.default
|
2024-12-20 00:24:10 -09:00
|
|
|
pkgs.wget
|
2026-05-24 00:27:15 -08:00
|
|
|
pkgs.tmux
|
2024-12-06 22:44:07 -09:00
|
|
|
|
2026-05-04 13:47:58 -08:00
|
|
|
pkgs.unstable.claude-code
|
2026-05-04 13:44:07 -08:00
|
|
|
|
2024-11-15 22:00:01 -09:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
swapDevices = [
|
|
|
|
|
{
|
|
|
|
|
device = "/swapfile";
|
|
|
|
|
size = 1 * 1024; # 1GB
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
2026-06-10 12:58:17 -08:00
|
|
|
# KDE Plasma on the host — the novnc systemd service (websockify) proxies
|
|
|
|
|
# WebSocket traffic from nginx to the VNC server started here.
|
2026-06-01 02:13:20 -08:00
|
|
|
services.xserver = {
|
|
|
|
|
enable = true;
|
|
|
|
|
desktopManager.plasma5.enable = true;
|
|
|
|
|
};
|
|
|
|
|
# Don't start X via a display manager; the vnc-kde service owns the session.
|
|
|
|
|
services.displayManager.sddm.enable = lib.mkForce false;
|
|
|
|
|
|
|
|
|
|
systemd.services.vnc-kde = {
|
|
|
|
|
description = "KDE Plasma desktop accessible over VNC";
|
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
|
after = [ "network.target" "agenix.service" ];
|
|
|
|
|
|
|
|
|
|
path = with pkgs; [
|
|
|
|
|
tigervnc
|
|
|
|
|
dbus
|
|
|
|
|
xorg.xauth
|
|
|
|
|
plasma5Packages.plasma-workspace
|
|
|
|
|
coreutils
|
|
|
|
|
gnugrep
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
serviceConfig = {
|
|
|
|
|
Type = "simple";
|
|
|
|
|
User = "root";
|
|
|
|
|
Restart = "on-failure";
|
|
|
|
|
RestartSec = "5s";
|
|
|
|
|
TasksMax = "infinity";
|
|
|
|
|
|
|
|
|
|
ExecStart = pkgs.writeShellScript "vnc-kde-start" ''
|
|
|
|
|
set -e
|
|
|
|
|
rm -f /tmp/.X1-lock /tmp/.X11-unix/X1
|
|
|
|
|
|
|
|
|
|
mkdir -p /root/.vnc
|
|
|
|
|
VNC_PASSWORD=$(grep '^VNC_PASSWORD=' /run/agenix/vnc-password | cut -d= -f2-)
|
|
|
|
|
printf '%s' "$VNC_PASSWORD" | vncpasswd -f > /root/.vnc/passwd
|
|
|
|
|
chmod 600 /root/.vnc/passwd
|
|
|
|
|
|
|
|
|
|
Xvnc :1 \
|
|
|
|
|
-rfbport 5901 \
|
|
|
|
|
-SecurityTypes VncAuth \
|
|
|
|
|
-PasswordFile /root/.vnc/passwd \
|
|
|
|
|
-geometry 1920x1080 \
|
|
|
|
|
-depth 24 \
|
|
|
|
|
-AlwaysShared &
|
|
|
|
|
|
|
|
|
|
export DISPLAY=:1
|
|
|
|
|
sleep 2
|
|
|
|
|
|
|
|
|
|
exec dbus-run-session -- startplasma-x11
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-25 14:29:58 -08:00
|
|
|
virtualisation.arion = {
|
2026-05-25 17:25:54 -08:00
|
|
|
backend = "podman-socket";
|
2026-05-25 14:29:58 -08:00
|
|
|
projects.forgejo.settings = import ./arion/arion-compose.nix;
|
|
|
|
|
projects.riverside.settings = import ./arion-riverside/arion-compose.nix;
|
2026-06-04 18:20:57 -08:00
|
|
|
projects.pluto.settings = import ./arion-pluto/arion-compose.nix;
|
2026-06-05 21:58:17 -08:00
|
|
|
projects.paperless.settings = import ./arion-paperless/arion-compose.nix;
|
2026-06-11 22:23:10 -08:00
|
|
|
projects.openclaw.settings = import ./arion-openclaw/arion-compose.nix;
|
2026-05-14 14:23:42 -08:00
|
|
|
};
|
|
|
|
|
|
2026-05-25 18:58:08 -08:00
|
|
|
# The arion NixOS module sets backend = "podman-socket" but doesn't inject
|
|
|
|
|
# DOCKER_HOST into the service units; docker CLI falls back to /var/run/docker.sock
|
|
|
|
|
# (no daemon). Point it at the podman-compatible socket instead.
|
|
|
|
|
systemd.services.arion-forgejo.environment.DOCKER_HOST = "unix:///run/podman/podman.sock";
|
|
|
|
|
systemd.services.arion-riverside.environment.DOCKER_HOST = "unix:///run/podman/podman.sock";
|
2026-06-04 18:20:57 -08:00
|
|
|
systemd.services.arion-pluto.environment.DOCKER_HOST = "unix:///run/podman/podman.sock";
|
2026-06-05 21:58:17 -08:00
|
|
|
systemd.services.arion-paperless.environment.DOCKER_HOST = "unix:///run/podman/podman.sock";
|
2026-06-11 22:23:10 -08:00
|
|
|
systemd.services.arion-openclaw.environment.DOCKER_HOST = "unix:///run/podman/podman.sock";
|
2026-05-25 18:58:08 -08:00
|
|
|
|
2026-06-10 12:58:17 -08:00
|
|
|
systemd.services.novnc = {
|
|
|
|
|
description = "noVNC WebSocket proxy for VNC desktop";
|
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
|
after = [ "vnc-kde.service" "network.target" ];
|
2026-05-25 19:14:53 -08:00
|
|
|
serviceConfig = {
|
2026-06-10 12:58:17 -08:00
|
|
|
Type = "simple";
|
|
|
|
|
Restart = "on-failure";
|
|
|
|
|
RestartSec = "3s";
|
|
|
|
|
ExecStart = "${pkgs.python3Packages.websockify}/bin/websockify --web ${pkgs.novnc}/share/webapps/novnc 127.0.0.1:6080 localhost:5901";
|
2026-05-25 19:14:53 -08:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-24 23:03:36 -08:00
|
|
|
services.gitea-actions-runner.instances."ubuntu" = {
|
|
|
|
|
enable = true;
|
2026-05-24 23:31:05 -08:00
|
|
|
name = "ubuntu";
|
2026-05-24 23:03:36 -08:00
|
|
|
url = "http://localhost:3000";
|
|
|
|
|
tokenFile = config.age.secrets.forgejo-runner-token.path;
|
|
|
|
|
labels = [
|
2026-05-24 23:41:07 -08:00
|
|
|
"ubuntu-latest:host"
|
|
|
|
|
"ubuntu-22.04:host"
|
|
|
|
|
"ubuntu-20.04:host"
|
2026-05-24 23:03:36 -08:00
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-24 23:46:25 -08:00
|
|
|
users.users.gitea-runner = {
|
|
|
|
|
isSystemUser = true;
|
|
|
|
|
group = "gitea-runner";
|
2026-05-25 17:27:24 -08:00
|
|
|
extraGroups = [ "podman" ];
|
2026-05-24 23:46:25 -08:00
|
|
|
home = "/var/lib/gitea-runner";
|
|
|
|
|
createHome = true;
|
|
|
|
|
};
|
|
|
|
|
users.groups.gitea-runner = {};
|
|
|
|
|
|
|
|
|
|
systemd.services.gitea-runner-ubuntu = {
|
2026-05-25 18:58:08 -08:00
|
|
|
after = [ "arion-forgejo.service" ];
|
|
|
|
|
wants = [ "arion-forgejo.service" ];
|
2026-05-24 23:46:25 -08:00
|
|
|
environment.PATH = lib.mkForce (
|
2026-06-11 21:37:48 -08:00
|
|
|
"${pkgs.podman}/bin:${pkgs.git}/bin:${pkgs.nodejs}/bin:/run/wrappers/bin:/run/current-system/sw/bin"
|
2026-05-24 23:46:25 -08:00
|
|
|
);
|
|
|
|
|
serviceConfig = {
|
|
|
|
|
DynamicUser = lib.mkForce false;
|
|
|
|
|
User = lib.mkForce "gitea-runner";
|
|
|
|
|
Group = lib.mkForce "gitea-runner";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2026-06-25 00:28:53 -08:00
|
|
|
systemd.services.coldairnetworks-postgres-ssl-init = {
|
|
|
|
|
description = "Generate self-signed SSL cert for coldairnetworks PostgreSQL";
|
|
|
|
|
wantedBy = [ "podman-coldairnetworks-postgres.service" ];
|
|
|
|
|
before = [ "podman-coldairnetworks-postgres.service" ];
|
|
|
|
|
serviceConfig = {
|
|
|
|
|
Type = "oneshot";
|
|
|
|
|
RemainAfterExit = true;
|
|
|
|
|
};
|
|
|
|
|
path = [ pkgs.openssl ];
|
|
|
|
|
script = ''
|
|
|
|
|
SSL_DIR=/var/coldairnetworks-db/ssl
|
2026-06-25 02:26:19 -08:00
|
|
|
NEEDS_REGEN=0
|
2026-06-25 00:28:53 -08:00
|
|
|
if [ ! -f "$SSL_DIR/server.crt" ]; then
|
2026-06-25 02:26:19 -08:00
|
|
|
NEEDS_REGEN=1
|
|
|
|
|
elif ! openssl x509 -in "$SSL_DIR/server.crt" -text -noout 2>/dev/null | grep -q "db.coldairnetworks.com"; then
|
|
|
|
|
NEEDS_REGEN=1
|
|
|
|
|
fi
|
|
|
|
|
if [ "$NEEDS_REGEN" = "1" ]; then
|
2026-06-25 00:28:53 -08:00
|
|
|
openssl req -new -x509 -days 3650 -nodes \
|
|
|
|
|
-subj "/CN=mainframe.philippeterson.com" \
|
2026-06-25 02:26:19 -08:00
|
|
|
-addext "subjectAltName=DNS:mainframe.philippeterson.com,DNS:db.coldairnetworks.com" \
|
2026-06-25 00:28:53 -08:00
|
|
|
-keyout "$SSL_DIR/server.key" \
|
|
|
|
|
-out "$SSL_DIR/server.crt"
|
2026-06-25 00:46:57 -08:00
|
|
|
chmod 600 "$SSL_DIR/server.key"
|
2026-06-25 00:28:53 -08:00
|
|
|
chmod 644 "$SSL_DIR/server.crt"
|
|
|
|
|
chown 999:999 "$SSL_DIR/server.key" "$SSL_DIR/server.crt"
|
|
|
|
|
fi
|
|
|
|
|
'';
|
|
|
|
|
};
|
|
|
|
|
|
2024-11-15 22:00:01 -09:00
|
|
|
systemd.tmpfiles.rules = [
|
|
|
|
|
"d /home/ironmagma/.config 0755 ${username} users"
|
|
|
|
|
"d /root/.config 0755 ${username} users"
|
2026-06-04 18:20:57 -08:00
|
|
|
"d /var/pluto/notebooks 0755 root root"
|
|
|
|
|
"d /var/pluto/julia-depot 0755 root root"
|
2026-06-05 21:58:17 -08:00
|
|
|
"d /var/paperless/data 0755 root root"
|
|
|
|
|
"d /var/paperless/media 0755 root root"
|
|
|
|
|
"d /var/paperless/export 0755 root root"
|
|
|
|
|
"d /var/paperless/consume 0755 root root"
|
|
|
|
|
"d /var/paperless/postgres 0755 root root"
|
|
|
|
|
"d /var/paperless/redis 0755 root root"
|
2026-06-14 02:30:13 -08:00
|
|
|
"d /var/openclaw/gateway 0755 root root"
|
2026-05-14 14:23:42 -08:00
|
|
|
"d /var/riverside/files 0755 root root"
|
|
|
|
|
"d /var/riverside/postgres 0755 root root"
|
2026-05-24 23:48:13 -08:00
|
|
|
"d /var/lib/gitea-runner/ubuntu 0755 gitea-runner gitea-runner"
|
2026-06-23 01:40:51 -08:00
|
|
|
"d /var/coldairnetworks-db/postgres 0755 root root"
|
|
|
|
|
"d /var/coldairnetworks-db/pgadmin 0700 5050 5050"
|
2026-06-25 00:28:53 -08:00
|
|
|
"d /var/coldairnetworks-db/ssl 0755 root root"
|
2024-11-15 22:00:01 -09:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
networking.hostName = "${hostname}";
|
|
|
|
|
|
|
|
|
|
# FIXME: change your shell here if you don't want zsh
|
|
|
|
|
programs.zsh.enable = true;
|
2026-05-04 13:52:47 -08:00
|
|
|
programs.zsh.shellInit = ''
|
2026-05-04 13:44:07 -08:00
|
|
|
export ANTHROPIC_API_KEY=$(cat ${config.age.secrets.anthropic-api-key.path})
|
|
|
|
|
'';
|
2024-11-15 22:00:01 -09:00
|
|
|
environment.pathsToLink = ["/share/zsh"];
|
|
|
|
|
environment.shells = [pkgs.zsh];
|
|
|
|
|
|
|
|
|
|
environment.enableAllTerminfo = true;
|
|
|
|
|
|
|
|
|
|
security.sudo.wheelNeedsPassword = false;
|
|
|
|
|
|
|
|
|
|
users.motd = motd;
|
|
|
|
|
|
|
|
|
|
system.stateVersion = "22.05";
|
|
|
|
|
|
2024-12-06 22:48:27 -09:00
|
|
|
virtualisation.podman = {
|
|
|
|
|
enable = true;
|
2024-12-06 22:49:57 -09:00
|
|
|
defaultNetwork.settings.dns_enabled = true;
|
2026-06-11 22:22:42 -08:00
|
|
|
autoPrune = {
|
|
|
|
|
enable = true;
|
|
|
|
|
flags = [ "--all" ];
|
|
|
|
|
dates = "daily";
|
|
|
|
|
};
|
2024-12-06 22:48:27 -09:00
|
|
|
};
|
|
|
|
|
|
2026-05-25 19:53:28 -08:00
|
|
|
# KDE Plasma spawns many threads (and obexd loops without Bluetooth hardware).
|
|
|
|
|
# The libpod scope for each container inherits systemd's DefaultTasksMax (~9286);
|
|
|
|
|
# raise machine.slice to infinity so podman scopes aren't capped.
|
|
|
|
|
systemd.slices.machine.sliceConfig.TasksMax = "infinity";
|
|
|
|
|
virtualisation.containers.containersConf.settings.containers.pids_limit = 0;
|
2026-05-25 19:36:36 -08:00
|
|
|
|
2024-11-15 22:00:01 -09:00
|
|
|
virtualisation.oci-containers = {
|
2026-05-25 17:27:24 -08:00
|
|
|
backend = "podman";
|
2024-11-15 22:00:01 -09:00
|
|
|
|
|
|
|
|
containers = {
|
2024-12-07 01:54:11 -09:00
|
|
|
# Example:
|
|
|
|
|
# "hello" = {
|
|
|
|
|
# autoStart = true;
|
|
|
|
|
# image = "nginxdemos/hello";
|
|
|
|
|
# #user = "root:jellyfin";
|
|
|
|
|
# volumes = [
|
|
|
|
|
# ];
|
|
|
|
|
# ports = ["8081:80"];
|
|
|
|
|
# };
|
2024-11-15 22:00:01 -09:00
|
|
|
|
2026-06-23 01:40:51 -08:00
|
|
|
"coldairnetworks-postgres" = {
|
|
|
|
|
autoStart = true;
|
|
|
|
|
image = "postgres:16";
|
|
|
|
|
ports = [ "5432:5432" ];
|
2026-06-25 00:28:53 -08:00
|
|
|
volumes = [
|
|
|
|
|
"/var/coldairnetworks-db/postgres:/var/lib/postgresql/data"
|
|
|
|
|
"/var/coldairnetworks-db/ssl:/run/ssl:ro"
|
|
|
|
|
];
|
2026-06-23 01:40:51 -08:00
|
|
|
environmentFiles = [ config.age.secrets.coldairnetworks-db-postgres.path ];
|
2026-06-25 00:28:53 -08:00
|
|
|
cmd = [
|
|
|
|
|
"postgres"
|
|
|
|
|
"-c" "ssl=on"
|
|
|
|
|
"-c" "ssl_cert_file=/run/ssl/server.crt"
|
|
|
|
|
"-c" "ssl_key_file=/run/ssl/server.key"
|
|
|
|
|
];
|
2026-06-23 01:40:51 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
"coldairnetworks-pgadmin" = {
|
|
|
|
|
autoStart = true;
|
|
|
|
|
image = "dpage/pgadmin4";
|
|
|
|
|
ports = [ "127.0.0.1:5050:80" ];
|
|
|
|
|
volumes = [ "/var/coldairnetworks-db/pgadmin:/var/lib/pgadmin" ];
|
|
|
|
|
environmentFiles = [ config.age.secrets.coldairnetworks-db-pgadmin.path ];
|
|
|
|
|
};
|
|
|
|
|
|
2024-11-15 22:00:01 -09:00
|
|
|
"navidrome" = {
|
|
|
|
|
autoStart = true;
|
|
|
|
|
environment = {
|
|
|
|
|
"TZ" = "America/Anchorage";
|
|
|
|
|
"PUID" = "1000";
|
|
|
|
|
"PGID" = "100";
|
|
|
|
|
|
|
|
|
|
"ND_SCANSCHEDULE" = "1h";
|
|
|
|
|
"ND_LOGLEVEL" = "info";
|
|
|
|
|
"ND_SESSIONTIMEOUT" = "24h";
|
|
|
|
|
"ND_BASEURL" = "";
|
|
|
|
|
};
|
|
|
|
|
ports = ["4533:4533"];
|
|
|
|
|
volumes = [
|
|
|
|
|
"/var/navidrome/data:/data"
|
|
|
|
|
"/var/navidrome/music:/music:ro"
|
|
|
|
|
];
|
|
|
|
|
image = "deluan/navidrome";
|
|
|
|
|
};
|
|
|
|
|
|
2025-01-14 20:43:46 -09:00
|
|
|
"nextcloud" = {
|
|
|
|
|
autoStart = true;
|
2025-01-14 21:13:17 -09:00
|
|
|
image = "quineglobal/ubuntu-with-ssh@sha256:64210887d48fae65bc4552503bf2d21a750ba0417ada530fd31254a8cc916746";
|
|
|
|
|
# image = "nextcloud/28-apache@sha256:ed95d344718ec86df96886b4b3465a9ce553c08b44b47306d399f0f201b04cb3";
|
2025-01-14 20:43:46 -09:00
|
|
|
volumes = [ ];
|
|
|
|
|
environment = { };
|
|
|
|
|
ports = ["8087:80"];
|
|
|
|
|
};
|
|
|
|
|
|
2025-01-14 21:13:17 -09:00
|
|
|
# "ubuntu" = {
|
|
|
|
|
# autoStart = true;
|
|
|
|
|
# image = "quineglobal/ubuntu-with-ssh@sha256:64210887d48fae65bc4552503bf2d21a750ba0417ada530fd31254a8cc916746";
|
|
|
|
|
# volumes = [ ];
|
|
|
|
|
# environment = {};
|
|
|
|
|
# ports = ["222:22"];
|
|
|
|
|
# };
|
2024-12-21 03:53:58 -09:00
|
|
|
|
|
|
|
|
"sync.io" = {
|
|
|
|
|
autoStart = true;
|
|
|
|
|
image = "quineglobal/sync.io@sha256:cbb180301fde42d8d22c26c952a4d4a487469d6491465302d8d79ebf194813b3";
|
2024-12-21 04:03:58 -09:00
|
|
|
volumes = [
|
|
|
|
|
"/var/syncio-cache:/sync.io-cache"
|
|
|
|
|
];
|
2024-12-21 03:53:58 -09:00
|
|
|
environment = {};
|
|
|
|
|
ports = ["9090:8080"];
|
2024-12-21 04:03:58 -09:00
|
|
|
user = "0"; # run as root
|
2024-12-21 03:53:58 -09:00
|
|
|
};
|
2025-01-04 01:12:38 -09:00
|
|
|
|
|
|
|
|
"blog-quine" = {
|
|
|
|
|
autoStart = true;
|
2026-05-30 02:13:40 -08:00
|
|
|
image = "quineglobal/blog-quine@sha256:88097e4867a99a375db490bf7a989c122653cdb48bfdf6d9ad5e2f6a0bfb2d38";
|
2025-01-04 01:12:38 -09:00
|
|
|
volumes = [];
|
|
|
|
|
environment = {};
|
|
|
|
|
ports = ["3010:8080"];
|
|
|
|
|
};
|
2026-05-14 14:03:03 -08:00
|
|
|
|
2026-05-25 23:13:54 -08:00
|
|
|
"hyper-quineglobal-com" = {
|
|
|
|
|
autoStart = true;
|
2026-05-29 02:21:47 -08:00
|
|
|
image = "forge.quinefoundation.com/ironmagma/hyper-quineglobal-com@sha256:d90132b3b60eb2ae73aa463b1b09677c1bc9b33b62c3e18430d47eb192f105eb";
|
2026-05-25 23:13:54 -08:00
|
|
|
volumes = [];
|
|
|
|
|
environment = {};
|
2026-05-25 23:23:11 -08:00
|
|
|
ports = ["3013:8081"];
|
2026-05-25 23:13:54 -08:00
|
|
|
};
|
|
|
|
|
|
2026-05-23 20:12:53 -08:00
|
|
|
"coldairnetworks" = {
|
|
|
|
|
autoStart = true;
|
2026-06-08 03:57:45 -08:00
|
|
|
image = "quineglobal/coldairnetworks-com@sha256:36f16006502171d82a107b1bd67517b9d602b54de31630a4861fba1e78250857";
|
2026-05-23 20:12:53 -08:00
|
|
|
volumes = [];
|
2026-05-23 22:30:47 -08:00
|
|
|
environment = {
|
|
|
|
|
POSTMARK_SERVER_TOKEN = "e718a146-c590-4550-a750-a3b925056e29";
|
2026-06-08 04:00:29 -08:00
|
|
|
BETTER_AUTH_URL = "https://coldairnetworks.com";
|
2026-06-08 03:49:55 -08:00
|
|
|
NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
2026-05-23 22:30:47 -08:00
|
|
|
};
|
2026-06-08 03:49:55 -08:00
|
|
|
environmentFiles = [ config.age.secrets.postmark.path config.age.secrets.coldairnetworks.path ];
|
2026-06-08 04:05:28 -08:00
|
|
|
ports = ["3012:3000"];
|
2026-05-23 20:12:53 -08:00
|
|
|
};
|
|
|
|
|
|
2024-11-15 22:00:01 -09:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
nix = {
|
|
|
|
|
settings = {
|
|
|
|
|
trusted-users = [username];
|
|
|
|
|
|
|
|
|
|
accept-flake-config = true;
|
|
|
|
|
auto-optimise-store = true;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
registry = {
|
|
|
|
|
nixpkgs = {
|
|
|
|
|
flake = inputs.nixpkgs;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
nixPath = [
|
|
|
|
|
"nixpkgs=${inputs.nixpkgs.outPath}"
|
|
|
|
|
"nixos-config=/etc/nixos/configuration.nix"
|
|
|
|
|
"/nix/var/nix/profiles/per-user/root/channels"
|
|
|
|
|
];
|
|
|
|
|
|
2026-05-04 05:31:21 -08:00
|
|
|
package = pkgs.nixVersions.stable;
|
2024-11-15 22:00:01 -09:00
|
|
|
extraOptions = ''experimental-features = nix-command flakes'';
|
|
|
|
|
|
|
|
|
|
gc = {
|
|
|
|
|
automatic = true;
|
|
|
|
|
options = "--delete-older-than 7d";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
# HTTPS
|
|
|
|
|
|
|
|
|
|
security.acme = {
|
|
|
|
|
acceptTerms = true;
|
|
|
|
|
defaults.email = "peterson@sent.com";
|
|
|
|
|
certs."philippeterson.com" = {
|
|
|
|
|
dnsProvider = "nearlyfreespeech";
|
|
|
|
|
environmentFile = config.age.secrets."nearlyfreespeech".path;
|
|
|
|
|
webroot = null;
|
|
|
|
|
};
|
2024-12-22 02:47:07 -09:00
|
|
|
|
|
|
|
|
certs."webdav.philippeterson.com" = {
|
|
|
|
|
dnsProvider = "nearlyfreespeech";
|
|
|
|
|
environmentFile = config.age.secrets."nearlyfreespeech".path;
|
|
|
|
|
webroot = null;
|
|
|
|
|
};
|
2026-06-04 18:20:57 -08:00
|
|
|
|
|
|
|
|
certs."pluto.philippeterson.com" = {
|
|
|
|
|
dnsProvider = "nearlyfreespeech";
|
|
|
|
|
environmentFile = config.age.secrets."nearlyfreespeech".path;
|
|
|
|
|
webroot = null;
|
2026-06-04 19:39:29 -08:00
|
|
|
group = config.services.nginx.group;
|
2026-06-04 18:20:57 -08:00
|
|
|
};
|
2026-06-05 21:58:17 -08:00
|
|
|
|
|
|
|
|
certs."paperless.philippeterson.com" = {
|
|
|
|
|
dnsProvider = "nearlyfreespeech";
|
|
|
|
|
environmentFile = config.age.secrets."nearlyfreespeech".path;
|
|
|
|
|
webroot = null;
|
|
|
|
|
group = config.services.nginx.group;
|
|
|
|
|
};
|
2024-11-15 22:00:01 -09:00
|
|
|
};
|
2026-05-25 18:58:08 -08:00
|
|
|
|
|
|
|
|
# Break the systemd ordering cycle that deadlocks nixos-rebuild switch.
|
|
|
|
|
# The cycle: nginx → After → acme-{philippeterson,webdav}.com (DNS challenge)
|
|
|
|
|
# → Wants → nginx-config-reload → After → acme-coldairnetworks (HTTP webroot)
|
|
|
|
|
# → After → nginx
|
|
|
|
|
# DNS-challenge certs don't need nginx running to provision; nginx only needs the
|
|
|
|
|
# selfsigned fallback cert before real certs arrive. Remove the real ACME services
|
|
|
|
|
# from nginx's After so the HTTP-webroot chain doesn't complete the loop.
|
|
|
|
|
systemd.services.nginx.after = lib.mkForce [
|
|
|
|
|
"network.target"
|
|
|
|
|
"acme-selfsigned-coldairnetworks.com.service"
|
2026-05-28 15:47:02 -08:00
|
|
|
"acme-selfsigned-www.coldairnetworks.com.service"
|
2026-05-25 18:58:08 -08:00
|
|
|
"acme-selfsigned-forge.quinefoundation.com.service"
|
2026-05-25 23:19:34 -08:00
|
|
|
"acme-selfsigned-hyper.quineglobal.com.service"
|
2026-05-25 18:58:08 -08:00
|
|
|
"acme-selfsigned-pdxdestiny.com.service"
|
2026-05-28 15:44:30 -08:00
|
|
|
"acme-selfsigned-www.pdxdestiny.com.service"
|
2026-05-25 18:58:08 -08:00
|
|
|
"acme-selfsigned-philippeterson.com.service"
|
2026-05-28 15:47:02 -08:00
|
|
|
"acme-selfsigned-www.philippeterson.com.service"
|
2026-05-25 18:58:08 -08:00
|
|
|
"acme-selfsigned-riverside.coldairnetworks.com.service"
|
|
|
|
|
"acme-selfsigned-vnc.quinefoundation.com.service"
|
2026-06-10 12:58:17 -08:00
|
|
|
"acme-selfsigned-claw.quineglobal.com.service"
|
2026-05-25 18:58:08 -08:00
|
|
|
"acme-selfsigned-webdav.philippeterson.com.service"
|
2026-06-04 18:20:57 -08:00
|
|
|
"acme-selfsigned-pluto.philippeterson.com.service"
|
2026-06-05 21:58:17 -08:00
|
|
|
"acme-selfsigned-paperless.philippeterson.com.service"
|
2026-06-23 01:40:51 -08:00
|
|
|
"acme-selfsigned-db.coldairnetworks.com.service"
|
2026-05-25 18:58:08 -08:00
|
|
|
];
|
2024-11-15 22:00:01 -09:00
|
|
|
}
|