migrate services

This commit is contained in:
TheWanderingCrow 2025-07-02 10:01:00 -04:00
parent f0b3b2a4b4
commit 891be2b165
15 changed files with 1136 additions and 0 deletions

View file

@ -0,0 +1,10 @@
{
config,
lib,
...
}: {
services.glances = {
enable = true;
};
}

View file

@ -0,0 +1,57 @@
{
lib,
config,
...
}: {
sops = {
secrets."attic/server_token" = {};
secrets."cloudflare/r2/access_key" = {};
secrets."cloudflare/r2/secret_key" = {};
templates."attic-env".content = ''
ATTIC_SERVER_TOKEN_RS256_SECRET_BASE64=${config.sops.placeholder."attic/server_token"}
AWS_ACCESS_KEY_ID=${config.sops.placeholder."cloudflare/r2/access_key"}
AWS_SECRET_ACCESS_KEY=${config.sops.placeholder."cloudflare/r2/secret_key"}
'';
};
services = {
atticd = {
enable = true;
mode = "monolithic";
environmentFile = config.sops.templates."attic-env".path;
settings = {
listen = "[::]:8080";
api-endpoint = "https://cache.wanderingcrow.net/";
jwt = {};
chunking = {
nar-size-threshold = 64 * 1024; # 64 KiB
min-size = 16 * 1024; # 16 KiB
avg-size = 64 * 1024; # 64 KiB
max-size = 256 * 1024; # 256 KiB
};
storage = {
type = "s3";
region = "";
bucket = "wce-attic-cache";
endpoint = "https://68c4b3ab47c1a97037ab5a938f772d69.r2.cloudflarestorage.com";
};
};
};
nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"cache.wanderingcrow.net" = {
forceSSL = true;
extraConfig = ''
client_max_body_size 0;
'';
useACMEHost = "cache.wanderingcrow.net";
locations."/" = {
proxyPass = "http://localhost:8080";
proxyWebsockets = true;
};
};
};
};
};
}

View file

@ -0,0 +1,109 @@
let
volumePath = "/overseer/services";
in
{
lib,
config,
...
}: {
###########
# SECRETS #
###########
sops = {
# Meilisearch secrets
secrets."meilisearch/masterkey" = {};
templates."meilisearch-environment".content = ''
MEILI_MASTER_KEY=${config.sops.placeholder."meilisearch/masterkey"}
'';
# Bar Assistant secrets
templates."bar_assistant-env".content = ''
MEILISEARCH_KEY=${config.sops.placeholder."meilisearch/masterkey"}
'';
};
systemd.tmpfiles.rules = [
"d ${volumePath}/bar-assistant 770 33 33"
"d ${volumePath}/meilisearch"
];
###########
# Routing #
###########
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"bar.wanderingcrow.net" = {
extraConfig = ''
allow 192.168.0.0/16;
allow 10.8.0.0/24;
allow 172.220.132.255;
deny all;
'';
forceSSL = true;
useACMEHost = "bar.wanderingcrow.net";
locations = {
"/search/" = {
proxyPass = "http://10.88.0.3:7700/";
priority = 1;
};
"/api/" = {
proxyPass = "http://10.88.0.4:8080/";
priority = 1;
};
"/" = {
proxyPass = "http://10.88.0.5:8080/";
};
};
};
};
};
###########
# Service #
###########
virtualisation.oci-containers = {
backend = "podman";
containers = {
"meilisearch" = {
image = "getmeili/meilisearch:v1.8";
volumes = ["${volumePath}/meilisearch:/meili_data"];
extraOptions = ["--ip=10.88.0.3"];
environmentFiles = [config.sops.templates."meilisearch-environment".path];
environment = {
MEILI_ENV = "production";
MEILI_NO_ANALYTICS = "true";
};
};
"bar-assistant" = {
image = "barassistant/server:v4";
volumes = ["${volumePath}/bar-assistant:/var/www/cocktails/storage/bar-assistant"];
dependsOn = ["meilisearch"];
extraOptions = ["--ip=10.88.0.4"];
environmentFiles = [config.sops.templates."bar_assistant-env".path];
environment = {
APP_URL = "https://bar.wanderingcrow.net/api";
MEILISEARCH_HOST = "https://bar.wanderingcrow.net/search";
CACHE_DRIVER = "file";
SESSION_DRIVER = "file";
ALLOW_REGISTRATION = "true";
};
};
"salt-rim" = {
image = "barassistant/salt-rim:v3";
dependsOn = ["bar-assistant"];
extraOptions = ["--ip=10.88.0.5"];
ports = ["3001:8080"];
environment = {
API_URL = "https://bar.wanderingcrow.net/api";
MEILIESEARCH_URL = "https://bar.wanderingcrow.net/search";
};
};
};
};
}

View file

@ -0,0 +1,9 @@
{
config,
lib,
...
}: {
services.calibre-web = {
enable = true;
};
}

View file

@ -0,0 +1,66 @@
{
lib,
config,
...
}: let
volumePath = "/overseer/services";
in {
systemd.tmpfiles.rules = [
"d ${volumePath}/ferdium-server/data"
"d ${volumePath}/ferdium-server/app/recipes"
];
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"ferdium.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "ferdium.wanderingcrow.net";
locations = {
"/" = {
proxyPass = "http://10.88.0.13:3333";
proxyWebsockets = true;
};
};
};
};
};
virtualisation.oci-containers = {
backend = "podman";
containers = {
"ferdium-api" = {
image = "ferdium/ferdium-server:latest";
volumes = [
"${volumePath}/ferdium-server/data:/data"
"${volumePath}/ferdium-server/app/recipes:/app/recipes"
];
extraOptions = ["--ip=10.88.0.13"];
environment = {
NODE_ENV = "production";
APP_URL = "ferdium.wanderingcrow.net";
DB_CONNECTION = "sqlite";
DB_HOST = "127.0.0.1";
DB_PORT = "3306";
DB_USER = "root";
DB_PASSWORD = "password"; # Do I need to change this for sqlite I dont think so
DB_DATABASE = "ferdium";
DB_SSL = "false";
MAIL_CONNECTION = "smtp";
SMTP_HOST = "127.0.0.1";
SMTP_PORT = "2525";
MAIL_SSL = "false";
MAIL_USERNAME = "username";
MAIL_PASSWORD = "password";
MAIL_SENDER = "noreply@mail.wanderingcrow.net";
IS_CREATION_ENABLED = "true";
IS_DASHBOARD_ENABLED = "true";
IS_REGISTRATION_ENABLED = "true";
CONNECT_WITH_FRANZ = "false";
DATA_DIR = "/data";
JWT_USE_PEM = "true";
};
};
};
};
}

View file

@ -0,0 +1,220 @@
let
volumePath = "/overseer/services";
in
{
pkgs,
lib,
config,
...
}: let
frigateConfig = pkgs.writeText "config.yaml" (lib.generators.toYAML {} {
auth.reset_admin_password = true; # roll the admin password every restart, depend on user accounts for long-lived access
tls.enabled = false; # off because we're doing ssl through nginx
mqtt = {
# TODO: add mqtt broker
enabled = false;
};
notifications = {
enabled = true;
email = "frigate@wanderingcrow.net";
};
###################
# go2rtc restream #
###################
go2rtc = {
streams = {
wce-0001 = [
"rtsp://thingino:thingino@192.168.150.1:554/ch0"
];
wce-0001_sub = [
"rtsp://thingino:thingino@192.168.150.1:554/ch1"
];
wce-0002 = [
"rtsp://thingino:thingino@192.168.150.2:554/ch0"
];
wce-0002_sub = [
"rtsp://thingino:thingino@192.168.150.2:554/ch1"
];
wce-0003 = [
"rtsp://thingino:thingino@192.168.150.3:554/ch0"
];
wce-0003_sub = [
"rtsp://thingino:thingino@192.168.150.3:554/ch1"
];
};
};
#############
# Detectors #
#############
detectors = {
ov_0 = {
type = "openvino";
device = "CPU";
};
};
model = {
width = 300;
height = 300;
input_tensor = "nhwc";
input_pixel_format = "bgr";
path = "/openvino-model/ssdlite_mobilenet_v2.xml";
labelmap_path = "/openvino-model/coco_91cl_bkgr.txt";
};
objects = {
track = [
"person"
"cat"
"car"
"dog"
];
};
review = {
alerts = {
labels = [
"person"
"cat"
];
};
};
####################
# Data Persistence #
####################
record = {
enabled = true;
retain.days = 0; # as per official documentation
alerts = {
retain.days = 14;
};
detections = {
retain.days = 14;
};
};
#################
# Camera config #
#################
cameras = {
wce-0001 = {
ffmpeg = {
inputs = [
{
path = "rtsp://127.0.0.1:8554/wce-0001";
roles = ["record"];
}
{
path = "rtsp://127.0.0.1:8554/wce-0001_sub";
roles = ["detect"];
}
];
};
live.stream_name = "wce-0001_sub";
motion = {
enabled = true;
mask = [
"0,0,0.196,0.002,0.195,0.045,0,0.043" # timestamp
"0.898,0,0.896,0.045,1,0.048,0.999,0.002" # uptime
];
};
detect.enabled = true;
};
wce-0002 = {
ffmpeg = {
inputs = [
{
path = "rtsp://127.0.0.1:8554/wce-0002";
roles = ["record"];
}
{
path = "rtsp://127.0.0.1:8554/wce-0002_sub";
roles = ["detect"];
}
];
};
live.stream_name = "wce-0002_sub";
motion = {
enabled = true;
mask = [
"0,0,0.196,0.002,0.195,0.045,0,0.043" # timestamp
"0.898,0,0.896,0.045,1,0.048,0.999,0.002" # uptime
];
};
detect.enabled = true;
};
wce-0003 = {
ffmpeg = {
inputs = [
{
path = "rtsp://127.0.0.1:8554/wce-0003";
roles = ["record"];
}
{
path = "rtsp://127.0.0.1:8554/wce-0003_sub";
roles = ["detect"];
}
];
};
live.stream_name = "wce-0003_sub";
motion = {
enabled = true;
mask = [
"0,0,0.196,0.002,0.195,0.045,0,0.043" # timestamp
"0.898,0,0.896,0.045,1,0.048,0.999,0.002" # uptime
];
};
detect.enabled = true;
};
};
});
in {
sops = {
templates."frigate_env".content = ''
FRIGATE_JWT_SECRET=${config.sops.placeholder."frigate/jwt"}
'';
secrets = {
"frigate/jwt" = {};
};
};
systemd.tmpfiles.rules = [
"d ${volumePath}/frigate"
"d ${volumePath}/frigate/media/frigate"
"d ${volumePath}/frigate/db"
"f ${volumePath}/frigate/db/frigate.db"
];
###########
# Service #
###########
virtualisation.oci-containers = {
backend = "podman";
containers = {
"frigate" = {
image = "ghcr.io/blakeblackshear/frigate:stable";
environmentFiles = [config.sops.templates."frigate_env".path];
volumes = [
"/etc/localtime:/etc/localtime:ro"
"${volumePath}/frigate/media/frigate:/media/frigate"
"${frigateConfig}:/config/config.yaml:ro"
"${volumePath}/frigate/db/frigate.db:/config/frigate.db"
];
extraOptions = [
"--shm-size=612m"
"--ip=10.88.0.10"
];
};
};
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"frigate.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "frigate.wanderingcrow.net";
locations."/" = {
proxyPass = "http://10.88.0.10:8971";
proxyWebsockets = true;
};
};
};
};
}

View file

@ -0,0 +1,42 @@
let
volumePath = "/overseer/services";
in
{
lib,
config,
...
}: {
systemd.tmpfiles.rules = [
"d ${volumePath}/barcodebuddy"
];
services.nginx.virtualHosts = {
"grocy.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "grocy.wanderingcrow.net";
};
"barcodebuddy.grocy.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "barcodebuddy.grocy.wanderingcrow.net";
locations."/" = {
proxyPass = "http://10.88.0.11:80";
proxyWebsockets = true;
};
};
};
services.grocy = {
enable = true;
hostName = "grocy.wanderingcrow.net";
nginx.enableSSL = false;
};
virtualisation.oci-containers.containers = {
barcodebuddy = {
image = "f0rc3/barcodebuddy:latest";
volumes = ["${volumePath}/barcodebuddy:/config"];
extraOptions = ["--ip=10.88.0.11"];
};
};
}

View file

@ -0,0 +1,35 @@
{
lib,
config,
...
}: {
services = {
nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"homebox.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "homebox.wanderingcrow.net";
locations."/" = {
extraConfig = ''
allow 192.168.0.0/16;
allow 10.8.0.0/24;
allow 172.220.132.255;
deny all;
'';
proxyPass = "http://localhost:7745";
proxyWebsockets = true;
};
};
};
};
homebox = {
enable = true;
settings = {
HBOX_OPTIONS_ALLOW_REGISTRATION = "true";
};
};
};
}

View file

@ -0,0 +1,260 @@
{
lib,
inputs,
config,
...
}: let
s = inputs.nix-secrets;
in {
# Homepage.dev secrets
sops = {
secrets = {
"homepage/openmeteo/lat" = {};
"homepage/openmeteo/long" = {};
"lubelogger/user" = {};
"lubelogger/pass" = {};
};
templates."homepage-environment".content = ''
HOMEPAGE_VAR_LAT = ${config.sops.placeholder."homepage/openmeteo/lat"}
HOMEPAGE_VAR_LONG = ${config.sops.placeholder."homepage/openmeteo/long"}
HOMEPAGE_VAR_LUBELOGGERUSER = ${config.sops.placeholder."lubelogger/user"}
HOMEPAGE_VAR_LUBELOGGERPASS = ${config.sops.placeholder."lubelogger/pass"}
HOMEPAGE_ALLOWED_HOSTS = home.wanderingcrow.net
'';
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"home.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "home.wanderingcrow.net";
locations."/" = {
extraConfig = ''
allow 192.168.0.0/16;
allow 10.8.0.0/24;
allow 172.220.134.108;
deny all;
'';
proxyPass = "http://localhost:8089";
proxyWebsockets = true;
};
};
};
};
services = {
homepage-dashboard = {
enable = true;
listenPort = 8089;
environmentFile = config.sops.templates."homepage-environment".path;
settings = {
theme = "dark";
};
services = [
{
"Services" = [
{
"Garage" = {
icon = "https://garage.wanderingcrow.net/favicon.ico";
href = "https://garage.wanderingcrow.net";
description = "Vehicle management";
widget = {
type = "lubelogger";
url = "https://garage.wanderingcrow.net";
username = "{{HOMEPAGE_VAR_LUBELOGGERUSER}}";
password = "{{HOMEPAGE_VAR_LUBELOGGERPASS}}";
};
};
}
];
}
];
widgets = [
{
search = {
provider = "duckduckgo";
target = "_blank";
};
}
{
openmeteo = {
timezone = "America/New_York";
units = "imperial";
cache = "5";
latitude = "{{HOMEPAGE_VAR_LAT}}";
longitude = "{{HOMEPAGE_VAR_LONG}}";
};
}
{
glances = {
url = "http://localhost:61208";
version = 4;
disk = "/";
label = "Overseer";
};
}
];
bookmarks = [
{
WCE = [
{
Grocy = [
{
icon = "grocy.svg";
href = "https://grocy.wanderingcrow.net";
}
];
}
{
Homebox = [
{
icon = "https://homebox.wanderingcrow.net/favicon.svg";
href = "https://homebox.wanderingcrow.net";
}
];
}
{
Bar = [
{
icon = "https://bar.wanderingcrow.net/favicon.svg";
href = "https://bar.wanderingcrow.net";
}
];
}
];
}
{
"Day to Day" = [
{
Messages = [
{
icon = "google-messages.svg";
href = "https://messages.google.com/web";
}
];
}
{
YouTube = [
{
icon = "youtube.svg";
href = "https://youtube.com";
}
];
}
{
"Proton Mail" = [
{
icon = "proton-mail.svg";
href = "https://mail.proton.me";
}
];
}
{
Crunchyroll = [
{
icon = "https://www.crunchyroll.com/build/assets/img/favicons/favicon-v2-32x32.png";
href = "https://crunchyroll.com";
}
];
}
{
Instagram = [
{
icon = "instagram.svg";
href = "https://instagram.com";
}
];
}
{
Aetolia = [
{
icon = "https://aetolia.com/wp-content/uploads/2020/04/favicon.ico";
href = "https://aetolia.com";
}
];
}
{
Amazon = [
{
icon = "amazon.svg";
href = "https://amazon.com";
}
];
}
];
}
{
Work = [
{
Jira = [
{
icon = "jira.svg";
href = "https://home.atlassian.com/";
}
];
}
{
AWS = [
{
icon = "aws.svg";
href = "https://console.aws.amazon.com/";
}
];
}
{
Email = [
{
icon = "gmail.svg";
href = "https://mail.google.com/mail/u/1/#inbox";
}
];
}
{
Groups = [
{
icon = "https://www.gstatic.com/images/branding/product/1x/groups_32dp.png";
href = "https://groups.google.com/u/1/";
}
];
}
];
}
{
Nix = [
{
Search = [
{
icon = "https://search.nixos.org/images/nix-logo.png";
href = "https://search.nixos.org";
}
];
}
{
"PR Tracker" = [
{
href = "https://nixpk.gs/pr-tracker.html";
}
];
}
{
"Home Manager Options" = [
{
href = "https://home-manager-options.extranix.com/";
}
];
}
{
"Nixpkgs Versions" = [
{
href = "https://lazamar.co.uk/nix-versions/";
}
];
}
];
}
];
};
};
}

View file

@ -0,0 +1,66 @@
let
volumePath = "/overseer/services";
in
{
lib,
config,
...
}: {
systemd.tmpfiles.rules = [
"d ${volumePath}/lubelogger"
"d ${volumePath}/lubelogger/data"
"d ${volumePath}/lubelogger/keys"
];
###########
# Service #
###########
sops = {
secrets = {
"lubelogger/user_hash" = {};
"lubelogger/pass_hash" = {};
};
templates."lubelogger-env".content = ''
LC_ALL=en_US.UTF-8
LANG=en_US.UTF-8
MailConfig__EmailServer=""
MailConfig__EmailFrom=""
MailConfig__Port=587
MailConfig__Username=""
MailConfig__Password=""
UserNameHash="${config.sops.placeholder."lubelogger/user_hash"}"
UserPasswordHash="${config.sops.placeholder."lubelogger/pass_hash"}"
LUBELOGGER_CUSTOM_WIDGETS=true
'';
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"garage.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "garage.wanderingcrow.net";
locations."/" = {
proxyPass = "http://10.88.0.8:8080";
proxyWebsockets = true;
};
};
};
};
virtualisation.oci-containers = {
backend = "podman";
containers = {
"lubelogger" = {
image = "ghcr.io/hargata/lubelogger:latest";
extraOptions = ["--ip=10.88.0.8"];
environmentFiles = [config.sops.templates."lubelogger-env".path];
volumes = [
"${volumePath}/lubelogger/data:/App/data"
"${volumePath}/lubelogger/keys:/root/.aspnet/DataProtection-Keys"
];
};
};
};
}

View file

@ -0,0 +1,86 @@
{
lib,
config,
...
}: let
fqdn = "matrix.wanderingcrow.net";
baseUrl = "https://${fqdn}";
clientConfig."m.homeserver".base_url = baseUrl;
serverConfig."m.server" = "${fqdn}:443";
mkWellKnown = data: ''
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '${builtins.toJSON data}';
'';
in {
############
# Database #
############
services.postgresql = {
enable = true;
ensureUsers = [
{
name = "matrix-synapse";
ensureDBOwnership = true;
}
];
ensureDatabases = ["matrix-synapse"];
};
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
virtualHosts = {
"wanderingcrow.net" = {
forceSSL = lib.mkDefault true;
useACMEHost = lib.mkDefault "wanderingcrow.net";
locations = {
"= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
"= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
};
};
"${fqdn}" = {
forceSSL = true;
useACMEHost = "${fqdn}";
locations = {
"/".extraConfig = ''return 404;'';
"/_matrix".proxyPass = "http://localhost:8008";
"/_synapse/client".proxyPass = "http://localhost:8008";
};
};
};
};
services.matrix-synapse = {
enable = true;
settings = {
server_name = "wanderingcrow.net";
public_baseurl = baseUrl;
listeners = [
{
port = 8008;
bind_addresses = ["::1"];
type = "http";
tls = false;
x_forwarded = true;
resources = [
{
names = ["client" "federation"];
compress = true;
}
];
}
];
database = {
name = "psycopg2";
args = {
user = "matrix-synapse";
database = "matrix-synapse";
};
};
};
};
}

View file

@ -0,0 +1,51 @@
let
volumePath = "/overseer/services";
in
{
lib,
config,
...
}: {
systemd.tmpfiles.rules = [
"d ${volumePath}/openhab openhab"
"d ${volumePath}/openhab/conf openhab"
"d ${volumePath}/openhab/userdata openhab"
"d ${volumePath}/openhab/addons openhab"
];
###########
# Service #
###########
virtualisation.oci-containers = {
backend = "podman";
containers."openhab" = {
image = "openhab/openhab:5.0.0.M1";
extraOptions = ["--ip=10.88.0.9"];
volumes = [
"${volumePath}/openhab/conf:/openhab/conf"
"${volumePath}/openhab/userdata:/openhab/userdata"
"${volumePath}/openhab/addons:/openhab/addons"
];
};
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"openhab.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "openhab.wanderingcrow.net";
locations."/" = {
extraConfig = ''
allow 192.168.0.0/16;
allow 10.8.0.0/24;
allow 172.220.132.255;
deny all;
'';
proxyPass = "http://10.88.0.9:8080";
};
};
};
};
}

View file

@ -0,0 +1,24 @@
{
lib,
config,
inputs,
...
}: {
services = {
nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"wanderingcrow.net" = {
default = true;
forceSSL = true;
useACMEHost = "wanderingcrow.net";
locations."/" = {
root = inputs.the-nest.outputs.packages.x86_64-linux.default;
};
};
};
};
};
}

View file

@ -0,0 +1,30 @@
{
lib,
config,
pkgs,
...
}: {
services = {
trilium-server = {
enable = true;
package = pkgs.trilium-next-server;
instanceName = "WanderingCrow";
port = 8090;
};
nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"notes.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "notes.wanderingcrow.net";
locations."/" = {
proxyPass = "http://127.0.0.1:8090";
proxyWebsockets = true;
};
};
};
};
};
}

View file

@ -0,0 +1,71 @@
let
volumePath = "/overseer/services";
in
{
lib,
config,
...
}: {
systemd.tmpfiles.rules = [
"d ${volumePath}/umami"
];
###########
# Service #
###########
sops = {
secrets = {
"umami/secret" = {};
"umami/db_url" = {};
"umami/db_pass" = {};
};
templates."umami-env".content = ''
APP_SECRET=${config.sops.placeholder."umami/secret"}
DATABASE_TYPE=postgresql
DATABASE_URL=${config.sops.placeholder."umami/db_url"}
'';
templates."umami-db".content = ''
POSTGRES_DB=umami
POSTGRES_USER=umami
POSTGRES_PASSWORD=${config.sops.placeholder."umami/db_pass"}
'';
};
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts = {
"umami.wanderingcrow.net" = {
forceSSL = true;
useACMEHost = "umami.wanderingcrow.net";
locations."/" = {
proxyPass = "http://10.88.0.6:3000";
proxyWebsockets = true;
};
locations."/script.js" = {
extraConfig = ''
deny 172.220.132.255;
'';
};
};
};
};
virtualisation.oci-containers = {
backend = "podman";
containers = {
"umami" = {
image = "ghcr.io/umami-software/umami:postgresql-latest";
dependsOn = ["umami-db"];
extraOptions = ["--ip=10.88.0.6"];
environmentFiles = [config.sops.templates."umami-env".path];
};
"umami-db" = {
image = "postgres:15-alpine";
volumes = ["${volumePath}/umami:/var/lib/postgresql/data"];
extraOptions = ["--ip=10.88.0.7"];
environmentFiles = [config.sops.templates."umami-db".path];
};
};
};
}