258 lines
8.4 KiB
Nix
258 lines
8.4 KiB
Nix
{ config, pkgs, nestedContainerExtras, ... }:
|
|
let
|
|
mastodonContainerFactory = import ../modules/mastodon_container.nix { };
|
|
prodConfig = {
|
|
containerName = "mastodon";
|
|
hostAddress = "192.168.42.11";
|
|
domain = "snoot.tube";
|
|
localAddress = "192.168.42.12";
|
|
useElasticsearch = true;
|
|
mastodonPackage = pkgs.mastodonFork;
|
|
forwardPorts = [
|
|
{
|
|
containerPort = 443;
|
|
hostPort = 443;
|
|
protocol = "tcp";
|
|
}
|
|
{
|
|
containerPort = 80;
|
|
hostPort = 80;
|
|
protocol = "tcp";
|
|
}
|
|
];
|
|
imports = nestedContainerExtras.imports;
|
|
disabledModules = nestedContainerExtras.disabledModules;
|
|
acme = {
|
|
acceptTerms = true;
|
|
defaults.email = "vivlim@pm.me";
|
|
defaults.server =
|
|
"https://localhost"; # try to use localhost as acme server. this request *will* fail, and we'll fall back to self-signed
|
|
#defaults.enableDebugLogs = true;
|
|
};
|
|
smtp = {
|
|
createLocally = false;
|
|
authenticate = false;
|
|
fromAddress = "snoot-tube-mastodon@vvn.space";
|
|
host =
|
|
"192.168.1.7"; # ts ip isn't reachable from the container. maybe need a mail relay on the host? use lan ip for now "100.109.126.18"; # sky-reflected-in-mirrors ts ip
|
|
port = 25;
|
|
};
|
|
mastodonExtraConfig = {
|
|
ALTERNATE_DOMAINS = "dev.snoot.tube,awake.snoot.tube";
|
|
#EMAIL_DOMAIN_ALLOWLIST = "vvn.space";
|
|
SMTP_AUTH_METHOD = "none";
|
|
SMTP_OPENSSL_VERIFY_MODE = "none";
|
|
MAX_TOOT_CHARS = "42069";
|
|
AUTHORIZED_FETCH = "true";
|
|
USER_ACTIVE_DAYS = "14";
|
|
STATSD_ADDR = "outer:9125";
|
|
MAX_REACTIONS = "8";
|
|
SEARCH_SCOPE = "public";
|
|
};
|
|
oauth2ProxyUsers = ''
|
|
viv
|
|
itsonlythee
|
|
lifning
|
|
Skirmisher
|
|
'';
|
|
oauth2ProxyKeys = config.sops.secrets.oauth2_proxy_keys.path;
|
|
|
|
};
|
|
|
|
prodContainer = (mastodonContainerFactory prodConfig);
|
|
in {
|
|
config.networking.hostName = "mastodon-snoottube";
|
|
config.networking.firewall.enable = true;
|
|
config.networking.firewall.allowedTCPPorts =
|
|
[ 80 443 22 19999 19998 19980 19981 9102 4040 ];
|
|
config.networking.firewall.interfaces."ve-+".allowedTCPPorts =
|
|
[ 3128 ]; # ssh forwarded http proxy
|
|
config.networking.firewall.interfaces."ve-+".allowedUDPPorts =
|
|
[ 9125 ]; # statsd
|
|
config.networking.firewall.checkReversePath = "loose";
|
|
|
|
config.networking.extraHosts = ''
|
|
192.168.42.11 outer
|
|
192.168.42.12 mastodon-container
|
|
'';
|
|
|
|
config.services.tailscale.enable = true;
|
|
|
|
# enable containers to reach network
|
|
config.networking.nat.enable = true;
|
|
config.networking.nat.internalInterfaces = [ "ve-+" ];
|
|
config.networking.nat.externalInterface = "ens18";
|
|
|
|
config.services.prometheus_exporters = {
|
|
enable = true;
|
|
nodePort = 19982;
|
|
systemdPort = 19983;
|
|
combinedPort = 19980;
|
|
};
|
|
|
|
config.services.autossh = {
|
|
sessions = [{
|
|
name = "snoot.tube_ingress";
|
|
user = "root";
|
|
monitoringPort = 0;
|
|
extraArguments =
|
|
"-o ExitOnForwardFailure=yes -o ConnectTimeout=10 -o ServerAliveInterval=15 -o ServerAliveCountMax=4 -N -R 4433:${prodConfig.localAddress}:443 -L 3128:localhost:3128 -L 19981:localhost:19980 -L 19998:localhost:19999 -L 4040:localhost:4040 -g -i /root/.ssh/id_ed25519_to_ingress snoot.tube -p 6922";
|
|
}];
|
|
};
|
|
|
|
config.containers = { mastodon = prodContainer.containerConfig; };
|
|
|
|
config.system.activationScripts.createMastodonContainerPaths =
|
|
pkgs.lib.stringAfter [ "setupSecrets" "var" ]
|
|
prodContainer.activationScript;
|
|
|
|
config.sops.secrets.oauth2_proxy_keys = { };
|
|
|
|
config.environment.systemPackages = [
|
|
(let
|
|
script = pkgs.writeShellScriptBin "tootctl" ''
|
|
echo "untested! check if this works and remove this echo if it does"
|
|
sudo nixos-container "run mastodon -- tootctl $@\""
|
|
'';
|
|
in pkgs.stdenv.mkDerivation {
|
|
name = "mastodon-container-tootctl-wrapper";
|
|
version = "1.0.0";
|
|
phases = "installPhase";
|
|
installPhase = ''
|
|
mkdir -p $out/bin
|
|
cp ${script}/bin/* $out/bin/
|
|
'';
|
|
})
|
|
];
|
|
|
|
config.sops.defaultSopsFile = ../secrets/backend.yaml;
|
|
config.sops.secrets.borg_backup_repo_passphrase = { };
|
|
config.sops.secrets.borgbase_ssh_private_key =
|
|
{ }; # it is extremely important for this to have a trailing newline, or connecting will fail
|
|
config.services.borgbackup.jobs."borgbase" = {
|
|
paths = [ "/var/lib/mastodon-container" "/var/backup" ];
|
|
exclude = [ ];
|
|
|
|
repo = "h5g87o5w@h5g87o5w.repo.borgbase.com:repo";
|
|
encryption = {
|
|
mode = "repokey-blake2";
|
|
passCommand =
|
|
"cat ${config.sops.secrets.borg_backup_repo_passphrase.path}";
|
|
};
|
|
environment.BORG_RSH =
|
|
"ssh -i ${config.sops.secrets.borgbase_ssh_private_key.path}";
|
|
compression = "auto,lzma";
|
|
startAt = "daily";
|
|
};
|
|
|
|
config.systemd.services.statsd-exporter = {
|
|
description = "StatsD Exporter";
|
|
wantedBy = [ "multi-user.target" ];
|
|
after = [ "container@mastodon.service" ];
|
|
|
|
serviceConfig = let
|
|
mappingFile = pkgs.writeText "statsd-mapping.yaml" ''
|
|
## Prometheus Statsd Exporter mapping for Mastodon 4.0+
|
|
##
|
|
## Version 1.0, November 2022
|
|
##
|
|
## Documentation: https://ipng.ch/s/articles/2022/11/27/mastodon-3.html
|
|
|
|
mappings:
|
|
## Web collector
|
|
- match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.status\.(.+)
|
|
match_type: regex
|
|
name: "mastodon_controller_status"
|
|
labels:
|
|
controller: $1
|
|
action: $2
|
|
format: $3
|
|
status: $4
|
|
mastodon: "web"
|
|
- match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.db_time
|
|
match_type: regex
|
|
name: "mastodon_controller_db_time"
|
|
labels:
|
|
controller: $1
|
|
action: $2
|
|
format: $3
|
|
mastodon: "web"
|
|
- match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.view_time
|
|
match_type: regex
|
|
name: "mastodon_controller_view_time"
|
|
labels:
|
|
controller: $1
|
|
action: $2
|
|
format: $3
|
|
mastodon: "web"
|
|
- match: Mastodon\.production\.web\.(.+)\.(.+)\.(.+)\.total_duration
|
|
match_type: regex
|
|
name: "mastodon_controller_duration"
|
|
labels:
|
|
controller: $1
|
|
action: $2
|
|
format: $3
|
|
mastodon: "web"
|
|
|
|
## Database collector
|
|
- match: Mastodon\.production\.db\.tables\.(.+)\.queries\.(.+)\.duration
|
|
match_type: regex
|
|
name: "mastodon_db_operation"
|
|
labels:
|
|
table: "$1"
|
|
operation: "$2"
|
|
mastodon: "db"
|
|
|
|
## Cache collector
|
|
- match: Mastodon\.production\.cache\.(.+)\.duration
|
|
match_type: regex
|
|
name: "mastodon_cache_duration"
|
|
labels:
|
|
operation: "$1"
|
|
mastodon: "cache"
|
|
|
|
## Sidekiq collector
|
|
- match: Mastodon\.production\.sidekiq\.(.+)\.processing_time
|
|
match_type: regex
|
|
name: "mastodon_sidekiq_worker_processing_time"
|
|
labels:
|
|
worker: "$1"
|
|
mastodon: "sidekiq"
|
|
- match: Mastodon\.production\.sidekiq\.(.+)\.success
|
|
match_type: regex
|
|
name: "mastodon_sidekiq_worker_success_total"
|
|
labels:
|
|
worker: "$1"
|
|
mastodon: "sidekiq"
|
|
- match: Mastodon\.production\.sidekiq\.(.+)\.failure
|
|
match_type: regex
|
|
name: "mastodon_sidekiq_worker_failure_total"
|
|
labels:
|
|
worker: "$1"
|
|
mastodon: "sidekiq"
|
|
- match: Mastodon\.production\.sidekiq\.queues\.(.+)\.enqueued
|
|
match_type: regex
|
|
name: "mastodon_sidekiq_queue_enqueued"
|
|
labels:
|
|
queue: "$1"
|
|
mastodon: "sidekiq"
|
|
- match: Mastodon\.production\.sidekiq\.queues\.(.+)\.latency
|
|
match_type: regex
|
|
name: "mastodon_sidekiq_queue_latency"
|
|
labels:
|
|
queue: "$1"
|
|
mastodon: "sidekiq"
|
|
- match: Mastodon\.production\.sidekiq\.(.+)
|
|
match_type: regex
|
|
name: "mastodon_sidekiq_$1"
|
|
labels:
|
|
mastodon: "sidekiq"
|
|
'';
|
|
in {
|
|
ExecStart =
|
|
"${pkgs.prometheus-statsd-exporter}/bin/statsd_exporter --web.listen-address=':9102' --statsd.listen-udp=':9125' --statsd.mapping-config=${mappingFile}";
|
|
};
|
|
};
|
|
}
|
|
|