start refactoring shared code into modules, update the lock, do some other minor fixes
This commit is contained in:
parent
c2780184c2
commit
5527f50a3b
43 changed files with 2348 additions and 51 deletions
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
sops.secrets."releaseCookie".mode = "0440";
|
||||
sops.secrets."releaseCookie".owner = config.users.users.akkoma.name;
|
||||
|
||||
users.groups.akkoma = {};
|
||||
|
||||
users.users = {
|
||||
akkoma = {
|
||||
isSystemUser = true;
|
||||
group = "akkoma";
|
||||
};
|
||||
};
|
||||
|
||||
services.akkoma = {
|
||||
enable = true;
|
||||
package = pkgs.akkoma;
|
||||
extraPackages = with pkgs; [ffmpeg exiftool imagemagick];
|
||||
nginx = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
serverName = "akkoma.gladtherescake.eu";
|
||||
};
|
||||
#dist.cookie._secret = config.sops.secrets."releaseCookie".path;
|
||||
config = {
|
||||
":pleroma".":instance" = {
|
||||
name = "GLaDTheresCake Akkoma";
|
||||
email = "akkoma@gladtherescake.eu";
|
||||
notify_email = "no-reply@akkoma.gladtherescake.eu";
|
||||
emails.mailer = {
|
||||
enabled = true;
|
||||
adapter = "Swoosh.Adapters.Sendmail";
|
||||
cmd_path = "sendmail";
|
||||
cmd_args = "-N delay,failure,success";
|
||||
qmail = true;
|
||||
};
|
||||
description = "Lillian's Akkoma server!";
|
||||
languages = ["en" "nl"];
|
||||
registrations_open = true;
|
||||
max_pinned_statuses = 10;
|
||||
cleanup_attachments = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
{config, ...}: {
|
||||
users.users.aria2.group = "aria2";
|
||||
users.groups.aria2 = {};
|
||||
users.users.aria2.isSystemUser = true;
|
||||
|
||||
sops.secrets."wg-private".mode = "0440";
|
||||
sops.secrets."wg-private".owner = config.users.users.aria2.name;
|
||||
containers.aria2 = {
|
||||
forwardPorts = [
|
||||
{
|
||||
containerPort = 6969;
|
||||
hostPort = 6969;
|
||||
protocol = "udp";
|
||||
}
|
||||
];
|
||||
bindMounts = {
|
||||
"/var/lib/media" = {
|
||||
hostPath = "/var/lib/media";
|
||||
isReadOnly = false;
|
||||
};
|
||||
"/var/lib/wg/private-key" = {
|
||||
hostPath = config.sops.secrets."wg-private".path;
|
||||
isReadOnly = true;
|
||||
};
|
||||
};
|
||||
autoStart = true;
|
||||
privateNetwork = true;
|
||||
hostAddress = "192.168.100.10";
|
||||
localAddress = "192.168.100.11";
|
||||
hostAddress6 = "fc00::1";
|
||||
localAddress6 = "fc00::2";
|
||||
config = {
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
system.stateVersion = "unstable";
|
||||
networking.firewall.allowedTCPPorts = [6969];
|
||||
networking.firewall.allowedUDPPorts = [6969 51820];
|
||||
users.users = {
|
||||
aria2.extraGroups = ["jellyfin" "nextcloud"];
|
||||
};
|
||||
services.aria2 = {
|
||||
enable = true;
|
||||
downloadDir = "/var/lib/media";
|
||||
rpcListenPort = 6969;
|
||||
};
|
||||
networking.wg-quick.interfaces = {
|
||||
wg0 = {
|
||||
postUp = ''
|
||||
# Mark packets on the wg0 interface
|
||||
wg set wg0 fwmark 51820
|
||||
|
||||
# Forbid anything else which doesn't go through wireguard VPN on
|
||||
# ipV4 and ipV6
|
||||
${pkgs.iptables}/bin/iptables -A OUTPUT \
|
||||
! -d 192.168.0.0/16 \
|
||||
! -o wg0 \
|
||||
-m mark ! --mark $(wg show wg0 fwmark) \
|
||||
-m addrtype ! --dst-type LOCAL \
|
||||
-j REJECT
|
||||
${pkgs.iptables}/bin/ip6tables -A OUTPUT \
|
||||
! -o wg0 \
|
||||
-m mark ! --mark $(wg show wg0 fwmark) \
|
||||
-m addrtype ! --dst-type LOCAL \
|
||||
-j REJECT
|
||||
${pkgs.iptables}/bin/iptables -I OUTPUT -o lo -p tcp \
|
||||
--dport 6969 -m state --state NEW,ESTABLISHED -j ACCEPT
|
||||
${pkgs.iptables}/bin/iptables -I OUTPUT -s 192.168.100.10/24 -d 192.168.100.11/24 \
|
||||
-j ACCEPT
|
||||
'';
|
||||
postDown = ''
|
||||
${pkgs.iptables}/bin/iptables -D OUTPUT \
|
||||
! -o wg0 \
|
||||
-m mark ! --mark $(wg show wg0 fwmark) \
|
||||
-m addrtype ! --dst-type LOCAL \
|
||||
-j REJECT
|
||||
${pkgs.iptables}/bin/ip6tables -D OUTPUT \
|
||||
! -o wg0 -m mark \
|
||||
! --mark $(wg show wg0 fwmark) \
|
||||
-m addrtype ! --dst-type LOCAL \
|
||||
-j REJECT
|
||||
'';
|
||||
|
||||
address = ["10.2.0.2/32"];
|
||||
dns = ["10.2.0.1"];
|
||||
privateKeyFile = "/var/lib/wg/private-key";
|
||||
|
||||
peers = [
|
||||
{
|
||||
publicKey = "7A19/lMrfmpFZARivC7FS8DcGxMn5uUq9LcOqFjzlDo=";
|
||||
allowedIPs = ["0.0.0.0/0"];
|
||||
endpoint = "185.159.158.182:51820";
|
||||
persistentKeepalive = 25;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{config, ...}: {
|
||||
users.users.aria2.group = "aria2";
|
||||
users.groups.aria2 = {};
|
||||
users.users.aria2.isSystemUser = true;
|
||||
|
||||
sops.secrets."rpcSecret".mode = "0440";
|
||||
sops.secrets."rpcSecret".owner = config.users.users.aria2.name;
|
||||
|
||||
services.aria2 = {
|
||||
enable = true;
|
||||
downloadDir = "/var/lib/media";
|
||||
rpcListenPort = 6969;
|
||||
rpcSecretFile = config.sops.secrets."rpcSecret".path;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
{config, ...}: {
|
||||
services.phpfpm.pools.nextcloud.settings = {
|
||||
"listen.owner" = config.services.caddy.user;
|
||||
"listen.group" = config.services.caddy.group;
|
||||
};
|
||||
|
||||
users.users.caddy.extraGroups = ["nextcloud"];
|
||||
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
|
||||
# Setup Nextcloud virtual host to listen on ports
|
||||
virtualHosts = {
|
||||
"${config.services.nextcloud.hostName}" = {
|
||||
useACMEHost = "${config.services.nextcloud.hostName}";
|
||||
extraConfig = ''
|
||||
redir /.well-known/carddav /remote.php/dav 301
|
||||
redir /.well-known/caldav /remote.php/dav 301
|
||||
redir /.well-known/webfinger /index.php/.well-known/webfinger 301
|
||||
redir /.well-known/nodeinfo /index.php/.well-known/nodeinfo 301
|
||||
|
||||
encode gzip
|
||||
reverse_proxy localhost:9000
|
||||
header Strict-Transport-Security max-age=31536000;
|
||||
@forbidden {
|
||||
path /.htaccess
|
||||
path /data/*
|
||||
path /config/*
|
||||
path /db_structure
|
||||
path /.xml
|
||||
path /README
|
||||
path /3rdparty/*
|
||||
path /lib/*
|
||||
path /templates/*
|
||||
path /occ
|
||||
path /console.php
|
||||
}
|
||||
handle @forbidden {
|
||||
respond 404
|
||||
}
|
||||
|
||||
handle {
|
||||
root * /var/www/html
|
||||
php_fastcgi 127.0.0.1:9000 {
|
||||
# Tells nextcloud to remove /index.php from URLs in links
|
||||
env front_controller_active true
|
||||
}
|
||||
file_server
|
||||
}
|
||||
'';
|
||||
};
|
||||
"onlyoffice.gladtherescake.eu" = {
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{pkgs, ...}: {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"cinny.gladtherescake.eu" = {
|
||||
root = "${pkgs.cinny}";
|
||||
## Force HTTP redirect to HTTPS
|
||||
forceSSL = true;
|
||||
## LetsEncrypt
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
index = "index.html";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
# You'll need to edit these values
|
||||
# The hostname that will appear in your user and room IDs
|
||||
server_name = "matrix.gladtherescake.eu";
|
||||
|
||||
# An admin email for TLS certificate notifications
|
||||
admin_email = "letsencrypt@gladtherescake.eu";
|
||||
|
||||
# These ones you can leave alone
|
||||
|
||||
# Build a dervation that stores the content of `${server_name}/.well-known/matrix/server`
|
||||
well_known_server = pkgs.writeText "well-known-matrix-server" ''
|
||||
{
|
||||
"m.server": "${server_name}"
|
||||
}
|
||||
'';
|
||||
|
||||
# Build a dervation that stores the content of `${server_name}/.well-known/matrix/client`
|
||||
well_known_client = pkgs.writeText "well-known-matrix-client" ''
|
||||
{
|
||||
"m.homeserver": {
|
||||
"base_url": "https://${server_name}"
|
||||
}
|
||||
}
|
||||
'';
|
||||
in {
|
||||
# Configure continuwuity itself
|
||||
services.matrix-continuwuity = {
|
||||
enable = true;
|
||||
|
||||
settings.global = {
|
||||
inherit server_name;
|
||||
allow_registration = false;
|
||||
# emergency_password = "testpassword";
|
||||
turn_uris = ["turn:turn.gladtherescake.eu.url?transport=udp" "turn:turn.gladtherescake.eu?transport=tcp"];
|
||||
turn_secret = "cPKWEn4Fo5TAJoE7iX3xeVOaMVE4afeRN1iRGWYfbkWbkaZMxTpnmazHyH6c6yXT";
|
||||
well_known = {
|
||||
server = "matrix.gladtherescake.eu:443";
|
||||
client = "https://matrix.gladtherescake.eu";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Configure automated TLS acquisition/renewal
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults = {
|
||||
email = admin_email;
|
||||
};
|
||||
};
|
||||
|
||||
# ACME data must be readable by the NGINX user
|
||||
users.users.nginx.extraGroups = [
|
||||
"acme"
|
||||
];
|
||||
|
||||
# Configure NGINX as a reverse proxy
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
virtualHosts = {
|
||||
"${server_name}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
|
||||
listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "[::]";
|
||||
port = 443;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 8448;
|
||||
ssl = true;
|
||||
}
|
||||
{
|
||||
addr = "[::]";
|
||||
port = 8448;
|
||||
ssl = true;
|
||||
}
|
||||
];
|
||||
|
||||
locations."/_matrix/" = {
|
||||
proxyPass = "http://backend_continuwuity";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
proxy_set_header Host $host;
|
||||
proxy_buffering off;
|
||||
'';
|
||||
};
|
||||
locations."=/.well-known/matrix/server" = {
|
||||
# Use the contents of the derivation built previously
|
||||
alias = "${well_known_server}";
|
||||
|
||||
extraConfig = ''
|
||||
# Set the header since by default NGINX thinks it's just bytes
|
||||
default_type application/json;
|
||||
'';
|
||||
};
|
||||
|
||||
locations."=/.well-known/matrix/client" = {
|
||||
# Use the contents of the derivation built previously
|
||||
alias = "${well_known_client}";
|
||||
return = "200 '{\"m.homeserver\": {\"base_url\": \"https://${server_name}\"}, \"org.matrix.msc3575.proxy\": {\"url\": \"https://${server_name}\"}}'";
|
||||
|
||||
extraConfig = ''
|
||||
# Set the header since by default NGINX thinks it's just bytes
|
||||
default_type application/json;
|
||||
|
||||
# https://matrix.org/docs/spec/client_server/r0.4.0#web-browser-clients
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
'';
|
||||
};
|
||||
locations."/_matrix/client/unstable/org.matrix.msc3575/sync" = {
|
||||
proxyPass = "http://matrix.gladtherescake.eu/client/unstable/org.matrix.msc3575/sync";
|
||||
proxyWebsockets = true;
|
||||
recommendedProxySettings = false;
|
||||
return = "200 '{\"contacts\": [{\"matrix_id\": \"@admin:server.name\", \"email_address\": \"admin@server.name\", \"role\": \"m.role.admin\"}]}'";
|
||||
extraConfig = ''
|
||||
proxy_set_header Host $host;
|
||||
proxy_buffering off;
|
||||
'';
|
||||
};
|
||||
|
||||
extraConfig = ''
|
||||
merge_slashes off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
upstreams = {
|
||||
"backend_continuwuity" = {
|
||||
servers = {
|
||||
"[::1]:${toString config.services.matrix-continuwuity.settings.global.port}" = {};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Open firewall ports for HTTP, HTTPS, and Matrix federation
|
||||
networking.firewall.allowedTCPPorts = [80 443 8448];
|
||||
networking.firewall.allowedUDPPorts = [80 443 8448];
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
{config, ...}: {
|
||||
sops.secrets."coturn-auth-secret".mode = "0440";
|
||||
sops.secrets."coturn-auth-secret".owner = config.users.users.turnserver.name;
|
||||
users.users.nginx.extraGroups = ["turnserver"];
|
||||
services.coturn = {
|
||||
enable = true;
|
||||
use-auth-secret = true;
|
||||
static-auth-secret-file = config.sops.secrets."coturn-auth-secret".path;
|
||||
realm = "turn.gladtherescake.eu";
|
||||
relay-ips = [
|
||||
"62.171.160.195"
|
||||
"2a02:c207:2063:2448::1"
|
||||
];
|
||||
extraConfig = "
|
||||
cipher-list=\"HIGH\"
|
||||
no-loopback-peers
|
||||
no-multicast-peers
|
||||
";
|
||||
secure-stun = true;
|
||||
cert = "/var/lib/acme/turn.gladtherescake.eu/fullchain.pem";
|
||||
pkey = "/var/lib/acme/turn.gladtherescake.eu/key.pem";
|
||||
min-port = 49152;
|
||||
max-port = 49999;
|
||||
};
|
||||
|
||||
# setup certs
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"turn.gladtherescake.eu" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# share certs with coturn and restart on renewal
|
||||
security.acme.certs = {
|
||||
"turn.gladtherescake.eu" = {
|
||||
group = "turnserver";
|
||||
postRun = "systemctl reload nginx.service; systemctl restart coturn.service";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{...}: {
|
||||
imports = [
|
||||
./grafana
|
||||
#./loki
|
||||
./prometheus
|
||||
./telegraf
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
{config, ...}: {
|
||||
# grafana configuration
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings.server = {
|
||||
domain = "grafana.lillianviolet.dev";
|
||||
http_port = 2342;
|
||||
http_addr = "127.0.0.1";
|
||||
};
|
||||
provision = {
|
||||
datasources.settings = {
|
||||
apiVersion = 1;
|
||||
datasources = [
|
||||
{
|
||||
name = "Prometheus";
|
||||
type = "prometheus";
|
||||
access = "proxy";
|
||||
url = "http://localhost:${toString config.services.prometheus.port}";
|
||||
isDefault = true;
|
||||
}
|
||||
{
|
||||
name = "Loki";
|
||||
type = "loki";
|
||||
access = "proxy";
|
||||
url = "http://localhost:3100";
|
||||
isDefault = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# nginx reverse proxy
|
||||
services.nginx.virtualHosts.${config.services.grafana.settings.server.domain} = {
|
||||
## Force HTTP redirect to HTTPS
|
||||
forceSSL = true;
|
||||
## LetsEncrypt
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{...}: {
|
||||
services.loki = {
|
||||
enable = true;
|
||||
configFile = ./loki.yaml;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# Enables authentication through the X-Scope-OrgID header, which must be present
|
||||
# if true. If false, the OrgID will always be set to "fake".
|
||||
auth_enabled: false
|
||||
|
||||
server:
|
||||
http_listen_address: "0.0.0.0"
|
||||
http_listen_port: 3100
|
||||
|
||||
ingester:
|
||||
lifecycler:
|
||||
address: "127.0.0.1"
|
||||
ring:
|
||||
kvstore:
|
||||
store: inmemory
|
||||
replication_factor: 1
|
||||
final_sleep: 0s
|
||||
chunk_idle_period: 5m
|
||||
chunk_retain_period: 30s
|
||||
|
||||
schema_config:
|
||||
configs:
|
||||
- from: 2020-05-15
|
||||
store: boltdb
|
||||
object_store: filesystem
|
||||
schema: v11
|
||||
index:
|
||||
prefix: index_
|
||||
period: 168h
|
||||
|
||||
storage_config:
|
||||
boltdb:
|
||||
directory: /tmp/loki/index
|
||||
|
||||
filesystem:
|
||||
directory: /tmp/loki/chunks
|
||||
|
||||
limits_config:
|
||||
enforce_metric_name: false
|
||||
reject_old_samples: true
|
||||
reject_old_samples_max_age: 168h
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{config, ...}: {
|
||||
services.prometheus = {
|
||||
enable = true;
|
||||
port = 9001;
|
||||
# Export the current system metrics
|
||||
exporters = {
|
||||
node = {
|
||||
enable = true;
|
||||
enabledCollectors = ["systemd"];
|
||||
port = 9002;
|
||||
};
|
||||
};
|
||||
scrapeConfigs = [
|
||||
# Scrape the current system
|
||||
{
|
||||
job_name = "GrafanaService system";
|
||||
static_configs = [
|
||||
{
|
||||
targets = ["127.0.0.1:${toString config.services.prometheus.exporters.node.port}"];
|
||||
}
|
||||
];
|
||||
}
|
||||
# Scrape the Loki service
|
||||
{
|
||||
job_name = "Loki service";
|
||||
static_configs = [
|
||||
{
|
||||
targets = ["127.0.0.1:3100"];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
{config, ...}: {
|
||||
sops.secrets."grafana-telegraf-key".mode = "0440";
|
||||
sops.secrets."grafana-telegraf-key".owner = config.users.users.telegraf.name;
|
||||
services.telegraf = {
|
||||
enable = true;
|
||||
extraConfig = {
|
||||
agent = {
|
||||
interval = "10s";
|
||||
round_interval = true;
|
||||
metric_batch_size = 1000;
|
||||
metric_buffer_limit = 10000;
|
||||
collection_jitter = "0s";
|
||||
flush_interval = "10s";
|
||||
flush_jitter = "0s";
|
||||
precision = "";
|
||||
debug = false;
|
||||
quiet = false;
|
||||
logfile = "";
|
||||
hostname = "queen";
|
||||
omit_hostname = false;
|
||||
};
|
||||
inputs = {
|
||||
cpu = {
|
||||
percpu = true;
|
||||
totalcpu = true;
|
||||
collect_cpu_time = false;
|
||||
report_active = false;
|
||||
core_tags = false;
|
||||
};
|
||||
disk = {
|
||||
ignore_fs = ["tmpfs" "devtmpfs" "devfs" "overlay" "aufs" "squashfs"];
|
||||
};
|
||||
diskio = {};
|
||||
kernel = {};
|
||||
mem = {};
|
||||
system = {};
|
||||
};
|
||||
outputs = {
|
||||
websocket = {
|
||||
url = "ws://localhost:${toString config.services.prometheus.port}/api/live/push/telegraf";
|
||||
data_format = "influx";
|
||||
headers = {
|
||||
Authorisation = "Bearer glsa_lqpcKV34Pp0d7eIhKN79E2HTwzWWwN4m_fe64e398";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
19
modules/nixos/shared-packages/server-settings/default.nix
Normal file
19
modules/nixos/shared-packages/server-settings/default.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{...}: {
|
||||
imports = [
|
||||
./conduit
|
||||
./forgejo
|
||||
./gotosocial
|
||||
./mail-server
|
||||
./nextcloud
|
||||
# ./phanpy
|
||||
./postgres
|
||||
./roundcube
|
||||
./coturn
|
||||
# ./dashboard
|
||||
#./cinny
|
||||
#./firefox-sync
|
||||
./writefreely
|
||||
./mollysocket
|
||||
./jellyfin
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
port = 5126;
|
||||
in {
|
||||
sops.secrets."sync-secrets".mode = "0440";
|
||||
sops.secrets."sync-secrets".owner = config.users.users.firefox-syncserver.name;
|
||||
|
||||
users.groups.firefox-syncserver = {};
|
||||
users.users.firefox-syncserver = {
|
||||
isSystemUser = true;
|
||||
group = "firefox-syncserver";
|
||||
extraGroups = [config.users.groups.keys.name];
|
||||
};
|
||||
|
||||
services.mysql.package = pkgs.mariadb;
|
||||
services.firefox-syncserver = {
|
||||
enable = true;
|
||||
secrets = config.sops.secrets."sync-secrets".path;
|
||||
singleNode = {
|
||||
enable = true;
|
||||
hostname = "sync.gladtherescake.eu";
|
||||
url = "http://localhost:${toString port}";
|
||||
enableNginx = true;
|
||||
enableTLS = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
{pkgs, ...}: {
|
||||
imports = [];
|
||||
|
||||
#sops.secrets."mailpassunhash".mode = "0440";
|
||||
#sops.secrets."mailpassunhash".owner = config.users.users.virtualMail.name;
|
||||
|
||||
services.forgejo = {
|
||||
enable = true;
|
||||
#TODO: different mail passwords for different services
|
||||
#mailerPasswordFile = config.sops.secrets."mailpassunhash".path;
|
||||
database = {
|
||||
type = "postgres";
|
||||
};
|
||||
settings = {
|
||||
"cron.sync_external_users" = {
|
||||
RUN_AT_START = true;
|
||||
SCHEDULE = "@every 24h";
|
||||
UPDATE_EXISTING = true;
|
||||
};
|
||||
mailer = {
|
||||
ENABLED = true;
|
||||
PROTOCOL = "sendmail";
|
||||
FROM = "no-reply@git.lillianviolet.dev";
|
||||
SENDMAIL_PATH = "${pkgs.system-sendmail}/bin/sendmail";
|
||||
SENDMAIL_ARGS = "-bs";
|
||||
};
|
||||
repository = {
|
||||
ENABLE_PUSH_CREATE_USER = true;
|
||||
};
|
||||
federation = {
|
||||
ENABLED = true;
|
||||
};
|
||||
other = {
|
||||
SHOW_FOOTER_VERSION = false;
|
||||
};
|
||||
service.DISABLE_REGISTRATION = true;
|
||||
server = {
|
||||
DOMAIN = "git.lillianviolet.dev";
|
||||
ROOT_URL = "https://git.lillianviolet.dev/";
|
||||
HTTP_PORT = 3218;
|
||||
};
|
||||
"markup.jupyter" = {
|
||||
ENABLED = true;
|
||||
FILE_EXTENSIONS = ".ipynb";
|
||||
RENDER_COMMAND = "${pkgs.jupyter}/bin/jupyter nbconvert --stdout --to html --template full";
|
||||
IS_INPUT_FILE = true;
|
||||
RENDER_CONTENT_MODE = "no-sanitizer";
|
||||
};
|
||||
"markup.sanitizer.jupyter0" = {
|
||||
ELEMENT = "div";
|
||||
ALLOW_ATTR = "class";
|
||||
REGEXP = "";
|
||||
};
|
||||
"markup.sanitizer.jupyter0.img" = {
|
||||
ALLOW_DATA_URI_IMAGES = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
virtualHosts = {
|
||||
"git.lillianviolet.dev" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:3218";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
{pkgs, ...}: {
|
||||
users.users.gotosocial.extraGroups = ["virtualMail"];
|
||||
|
||||
services.nginx = {
|
||||
virtualHosts = {
|
||||
"social.gladtherescake.eu" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:4257";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.gotosocial = {
|
||||
enable = true;
|
||||
package = pkgs.gotosocial;
|
||||
setupPostgresqlDB = true;
|
||||
settings = {
|
||||
application-name = "gotosocial";
|
||||
host = "social.gladtherescake.eu";
|
||||
bind-address = "localhost";
|
||||
port = 4257;
|
||||
protocol = "https";
|
||||
storage-local-base-path = "/var/lib/gotosocial/storage";
|
||||
instance-languages = ["en-gb" "nl"];
|
||||
media-image-max-size = 41943040;
|
||||
media-video-max-size = 209715200;
|
||||
media-description-max-chars = 2000;
|
||||
#smtp-host = "localhost";
|
||||
#smtp-port = 587;
|
||||
#smtp-username = "no-reply@social.gladtherescake.eu";
|
||||
#smtp-password = config.sops.secrets."mailpassunhash".path;
|
||||
#smtp-from = "no-reply@social.gladtherescake.eu";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."gotosocial" = {
|
||||
requires = ["postgresql.service"];
|
||||
after = ["postgresql.service"];
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{...}: {
|
||||
services.nginx = {
|
||||
virtualHosts = {
|
||||
"video.gladtherescake.eu" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:8096";
|
||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.jellyfin = {
|
||||
enable = true;
|
||||
user = "nextcloud";
|
||||
group = "nextcloud";
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
{config, ...}: {
|
||||
sops.secrets."mailpass".mode = "0440";
|
||||
sops.secrets."mailpass".owner = config.users.users.virtualMail.name;
|
||||
|
||||
#Fix for the dovecot update
|
||||
# services.dovecot2.sieve.extensions = ["fileinto"];
|
||||
|
||||
mailserver = {
|
||||
stateVersion = 3;
|
||||
enable = true;
|
||||
enableImap = true;
|
||||
enableSubmission = true;
|
||||
fqdn = "mail.gladtherescake.eu";
|
||||
domains = [
|
||||
"nextcloud.gladtherescake.eu"
|
||||
"akkoma.gladtherescake.eu"
|
||||
"social.gladtherescake.eu"
|
||||
"gladtherescake.eu"
|
||||
"lillianviolet.dev"
|
||||
"git.lillianviolet.dev"
|
||||
];
|
||||
|
||||
loginAccounts = {
|
||||
"me@gladtherescake.eu" = {
|
||||
hashedPasswordFile = config.sops.secrets."mailpass".path;
|
||||
aliases = [
|
||||
"@gladtherescake.eu"
|
||||
];
|
||||
catchAll = [
|
||||
"gladtherescake.eu"
|
||||
];
|
||||
};
|
||||
"no-reply@nextcloud.gladtherescake.eu" = {
|
||||
hashedPasswordFile = config.sops.secrets."mailpass".path;
|
||||
};
|
||||
"no-reply@akkoma.gladtherescake.eu" = {
|
||||
hashedPasswordFile = config.sops.secrets."mailpass".path;
|
||||
};
|
||||
"no-reply@social.gladtherescake.eu" = {
|
||||
hashedPasswordFile = config.sops.secrets."mailpass".path;
|
||||
};
|
||||
"info@lillianviolet.dev" = {
|
||||
hashedPasswordFile = config.sops.secrets."mailpass".path;
|
||||
aliases = [
|
||||
"@lillianviolet.dev"
|
||||
];
|
||||
catchAll = [
|
||||
"lillianviolet.dev"
|
||||
];
|
||||
};
|
||||
"no-reply@git.lillianviolet.dev" = {
|
||||
hashedPasswordFile = config.sops.secrets."mailpass".path;
|
||||
};
|
||||
};
|
||||
|
||||
mailboxes = {
|
||||
All = {
|
||||
auto = "subscribe";
|
||||
specialUse = "All";
|
||||
};
|
||||
Archive = {
|
||||
auto = "subscribe";
|
||||
specialUse = "Archive";
|
||||
};
|
||||
Drafts = {
|
||||
auto = "subscribe";
|
||||
specialUse = "Drafts";
|
||||
};
|
||||
Junk = {
|
||||
auto = "subscribe";
|
||||
specialUse = "Junk";
|
||||
};
|
||||
Sent = {
|
||||
auto = "subscribe";
|
||||
specialUse = "Sent";
|
||||
};
|
||||
Trash = {
|
||||
auto = "no";
|
||||
specialUse = "Trash";
|
||||
};
|
||||
};
|
||||
|
||||
rejectRecipients = [
|
||||
"no-reply@nextcloud.gladtherescake.eu"
|
||||
"no-reply@akkoma.gladtherescake.eu"
|
||||
"no-reply@social.gladtherescake.eu"
|
||||
"no-reply@git.lillianviolet.dev"
|
||||
"ongebonden@gladtherescake.eu"
|
||||
"teluyep_canoja_52868396@gladtherescake.eu"
|
||||
"me.belsimpel@gladtherescake.eu"
|
||||
"me.tele2@gladtherescake.eu"
|
||||
"me+tele2@gladtherescake.eu"
|
||||
"me.archiveorg@gladtherescake.eu"
|
||||
];
|
||||
x509.useACMEHost = config.mailserver.fqdn;
|
||||
};
|
||||
security.acme.certs.${config.mailserver.fqdn} = {
|
||||
webroot = "/var/lib/acme/acme-challenge/";
|
||||
extraDomainNames = [
|
||||
"imap.lillianviolet.dev"
|
||||
"mail.lillianviolet.dev"
|
||||
"pop3.lillianviolet.dev"
|
||||
"lillianviolet.dev"
|
||||
"gladtherescake.eu"
|
||||
"mail.gladtherescake.eu"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{config, ...}: {
|
||||
sops.secrets."mollysocket-vapid-key".mode = "0440";
|
||||
|
||||
services.mollysocket = {
|
||||
enable = true;
|
||||
environmentFile = config.sops.secrets."mollysocket-vapid-key".path;
|
||||
settings = {
|
||||
port = 4381;
|
||||
allowed_endpoints = ["https://molly.gladtherescake.eu" "https://nextcloud.gladtherescake.eu"];
|
||||
allowed_uuids = ["db639f29-b7e7-431a-9c75-bcdcb87b6bdf"];
|
||||
webserver = true;
|
||||
};
|
||||
};
|
||||
services.nginx = {
|
||||
virtualHosts = {
|
||||
"molly.gladtherescake.eu" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:4381";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
sops.secrets."nextcloudadmin".mode = "0440";
|
||||
sops.secrets."nextcloudadmin".owner = config.users.users.nextcloud.name;
|
||||
sops.secrets."nextclouddb".mode = "0440";
|
||||
sops.secrets."nextclouddb".owner = config.users.users.nextcloud.name;
|
||||
# sops.secrets."local.json".mode = "0440";
|
||||
# sops.secrets."local.json".owner = config.users.users.onlyoffice.name;
|
||||
|
||||
users.users = {
|
||||
# nextcloud.extraGroups = [config.users.groups.keys.name config.users.users.onlyoffice.name];
|
||||
nextcloud.extraGroups = [config.users.groups.keys.name];
|
||||
#aria2.extraGroups = ["nextcloud"];
|
||||
# onlyoffice.extraGroups = [config.users.users.nextcloud.name];
|
||||
};
|
||||
|
||||
# Enable Nginx
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
# Use recommended settings
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
# Only allow PFS-enabled ciphers with AES256
|
||||
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
||||
|
||||
# Setup Nextcloud virtual host to listen on ports
|
||||
virtualHosts = {
|
||||
"nextcloud.gladtherescake.eu" = {
|
||||
## Force HTTP redirect to HTTPS
|
||||
forceSSL = true;
|
||||
## LetsEncrypt
|
||||
enableACME = true;
|
||||
};
|
||||
"onlyoffice.gladtherescake.eu" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Actual Nextcloud Config
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = "nextcloud.gladtherescake.eu";
|
||||
|
||||
package = pkgs.nextcloud33;
|
||||
|
||||
# Use HTTPS for links
|
||||
https = true;
|
||||
|
||||
# Auto-update Nextcloud Apps
|
||||
autoUpdateApps.enable = true;
|
||||
# Set what time makes sense for you
|
||||
autoUpdateApps.startAt = "05:00:00";
|
||||
configureRedis = true;
|
||||
maxUploadSize = "16G";
|
||||
|
||||
#Increase opcache string buffer
|
||||
phpOptions."opcache.interned_strings_buffer" = "23";
|
||||
# Further forces Nextcloud to use HTTPS
|
||||
settings = {
|
||||
overwriteprotocol = "https";
|
||||
default_phone_region = "NL";
|
||||
maintenance_window_start = 3;
|
||||
log_type = "file";
|
||||
};
|
||||
appstoreEnable = true;
|
||||
extraAppsEnable = true;
|
||||
#extraApps = with config.services.nextcloud.package.packages.apps; {
|
||||
# List of apps we want to install and are already packaged in
|
||||
# https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/nextcloud/packages/nextcloud-apps.json
|
||||
# inherit calendar contacts deck forms notes onlyoffice polls twofactor_nextcloud_notification unsplash;
|
||||
#};
|
||||
|
||||
config = {
|
||||
# Nextcloud PostegreSQL database configuration, recommended over using SQLite
|
||||
dbtype = "pgsql";
|
||||
dbuser = "nextcloud";
|
||||
dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
|
||||
dbname = "nextcloud";
|
||||
dbpassFile = config.sops.secrets."nextclouddb".path;
|
||||
|
||||
adminpassFile = config.sops.secrets."nextcloudadmin".path;
|
||||
adminuser = "GLaDTheresCake";
|
||||
};
|
||||
};
|
||||
|
||||
# services.onlyoffice = {
|
||||
# port = 16783;
|
||||
# enable = true;
|
||||
# hostname = "onlyoffice.gladtherescake.eu";
|
||||
# #postgresHost = "/run/postgesql";
|
||||
# #postgresUser = "onlyoffice";
|
||||
# #postgresName = "onlyoffice";
|
||||
# #jwtSecretFile = config.sops.secrets."local.json".path;
|
||||
# };
|
||||
|
||||
# services.rabbitmq = {
|
||||
# enable = true;
|
||||
# };
|
||||
|
||||
systemd.services."sops-nix.service" = {
|
||||
before = [
|
||||
"nextcloud-setup.service"
|
||||
"postgresql.service"
|
||||
"onlyoffice-converter.service"
|
||||
"onlyoffice-docservice.service"
|
||||
"nginx.service"
|
||||
"phpfpm-nextcloud.service"
|
||||
"redis-nextcloud.service"
|
||||
];
|
||||
};
|
||||
|
||||
# Ensure that postgres is running before running the setup
|
||||
systemd.services."nextcloud-setup" = {
|
||||
requires = ["postgresql.service"];
|
||||
after = ["postgresql.service"];
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
{...}: {
|
||||
users.users = {
|
||||
ombi.extraGroups = ["radarr" "sonarr" "aria2" "nextcloud"];
|
||||
};
|
||||
services.ombi = {
|
||||
enable = true;
|
||||
port = 2368;
|
||||
};
|
||||
|
||||
users.users = {
|
||||
radarr.extraGroups = ["aria2" "nextcloud"];
|
||||
sonarr.extraGroups = ["aria2" "nextcloud"];
|
||||
};
|
||||
|
||||
services = {
|
||||
#uses port 7878
|
||||
radarr.enable = true;
|
||||
#uses port 8989
|
||||
sonarr.enable = true;
|
||||
prowlarr.enable = true;
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
virtualHosts = {
|
||||
"ombi.gladtherescake.eu" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:2368";
|
||||
};
|
||||
};
|
||||
"radarr.gladtherescake.eu" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:7878";
|
||||
};
|
||||
};
|
||||
"sonarr.gladtherescake.eu" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:8989";
|
||||
};
|
||||
};
|
||||
"prowlarr.gladtherescake.eu" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:9696";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{pkgs, ...}: {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"phanpy.gladtherescake.eu" = {
|
||||
root = "${pkgs.phanpy}";
|
||||
## Force HTTP redirect to HTTPS
|
||||
forceSSL = true;
|
||||
## LetsEncrypt
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
index = "index.html";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
{pkgs, ...}: {
|
||||
services.postgresql = {
|
||||
# https://nixos.org/manual/nixos/stable/#module-postgresql
|
||||
package = pkgs.postgresql_16;
|
||||
enable = true;
|
||||
|
||||
# Ensure the database, user, and ownership is set
|
||||
ensureDatabases = [
|
||||
"nextcloud"
|
||||
"onlyoffice"
|
||||
"akkoma"
|
||||
"gotosocial"
|
||||
"gitea"
|
||||
];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "nextcloud";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
{
|
||||
name = "onlyoffice";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
{
|
||||
name = "akkoma";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
{
|
||||
name = "gotosocial";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
{
|
||||
name = "gitea";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
environment.systemPackages = [
|
||||
(let
|
||||
# XXX specify the postgresql package you'd like to upgrade to.
|
||||
# Do not forget to list the extensions you need.
|
||||
newPostgres = pkgs.postgresql_16.withPackages (pp: [
|
||||
# pp.plv8
|
||||
]);
|
||||
in
|
||||
pkgs.writeScriptBin "upgrade-pg-cluster" ''
|
||||
set -eux
|
||||
# XXX it's perhaps advisable to stop all services that depend on postgresql
|
||||
systemctl stop postgresql
|
||||
|
||||
export NEWDATA="/var/lib/postgresql/${newPostgres.psqlSchema}"
|
||||
|
||||
export NEWBIN="${newPostgres}/bin"
|
||||
|
||||
export OLDDATA="${config.services.postgresql.dataDir}"
|
||||
export OLDBIN="${config.services.postgresql.package}/bin"
|
||||
|
||||
install -d -m 0700 -o postgres -g postgres "$NEWDATA"
|
||||
cd "$NEWDATA"
|
||||
sudo -u postgres $NEWBIN/initdb -D "$NEWDATA"
|
||||
|
||||
sudo -u postgres $NEWBIN/pg_upgrade \
|
||||
--old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \
|
||||
--old-bindir $OLDBIN --new-bindir $NEWBIN \
|
||||
"$@"
|
||||
'')
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
# TODO: Figure out how to create packages for some plugins for roundcube!
|
||||
# https://packagist.org/search/?query=roundcube
|
||||
# https://discourse.nixos.org/t/roundcube-with-plugins/28292/7
|
||||
services.roundcube = {
|
||||
enable = true;
|
||||
package = pkgs.roundcube.withPlugins (
|
||||
plugins: [
|
||||
plugins.contextmenu
|
||||
plugins.carddav
|
||||
plugins.custom_from
|
||||
plugins.persistent_login
|
||||
plugins.thunderbird_labels
|
||||
]
|
||||
);
|
||||
plugins = [
|
||||
"contextmenu"
|
||||
"carddav"
|
||||
"custom_from"
|
||||
"persistent_login"
|
||||
"thunderbird_labels"
|
||||
];
|
||||
|
||||
# this is the url of the vhost, not necessarily the same as the fqdn of
|
||||
# the mailserver
|
||||
hostName = "webmail.lillianviolet.dev";
|
||||
extraConfig = ''
|
||||
# starttls needed for authentication, so the fqdn required to match
|
||||
# the certificate
|
||||
$config['smtp_server'] = "tls://${config.mailserver.fqdn}";
|
||||
$config['smtp_user'] = "%u";
|
||||
$config['smtp_pass'] = "%p";
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
sops.secrets."writefreely".mode = "0440";
|
||||
sops.secrets."writefreely".owner = config.users.users.writefreely.name;
|
||||
sops.secrets."writefreelymysql".mode = "0440";
|
||||
sops.secrets."writefreelymysql".owner = config.users.users.writefreely.name;
|
||||
services.writefreely = {
|
||||
enable = true;
|
||||
host = "writefreely.gladtherescake.eu";
|
||||
nginx.enable = true;
|
||||
nginx.forceSSL = true;
|
||||
acme.enable = true;
|
||||
# database = {
|
||||
# type = "mysql";
|
||||
# createLocally = true;
|
||||
# passwordFile = config.sops.secrets."writefreelymysql".path;
|
||||
# };
|
||||
admin = {
|
||||
initialPasswordFile = config.sops.secrets."writefreely".path;
|
||||
name = "GLaDTheresCake";
|
||||
};
|
||||
settings = {
|
||||
app = {
|
||||
min_username_len = 2;
|
||||
max_blogs = 100;
|
||||
default_visibility = "public";
|
||||
federation = true;
|
||||
local_timeline = true;
|
||||
};
|
||||
server.port = 1212;
|
||||
};
|
||||
};
|
||||
systemd.services.writefreely = {
|
||||
path = [pkgs.libressl];
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue