add gotosocial container, tidy up some files, disable tlp&powertop on laptops

This commit is contained in:
Chaos 2023-07-29 15:41:20 +00:00
parent 627079e5f7
commit eb865ecae2
No known key found for this signature in database
26 changed files with 233 additions and 353 deletions

View file

@ -15,7 +15,7 @@
hostname = "192.168.100.11"; hostname = "192.168.100.11";
proxyJump = "hetzner-vm"; proxyJump = "hetzner-vm";
}; };
"container-matrix" = { "container-social" = {
user = "root"; user = "root";
hostname = "192.168.100.12"; hostname = "192.168.100.12";
proxyJump = "hetzner-vm"; proxyJump = "hetzner-vm";

View file

@ -1,211 +0,0 @@
{
tree,
lib,
inputs,
pkgs,
config,
...
}: let
hostIP = "192.168.100.10";
containerIP = "192.168.100.12";
# Using secrets from Host
secrets = config.services.secrets.secrets;
in {
containers.matrix = {
autoStart = true;
privateNetwork = true;
hostAddress = hostIP;
localAddress = containerIP;
bindMounts = {
"${secrets.matrix_restic_password.path}" = {
hostPath = "${secrets.matrix_restic_password.path}";
};
"${secrets.matrix_restic_env.path}" = {
hostPath = "${secrets.matrix_restic_env.path}";
};
};
config = {
config,
pkgs,
...
}: {
_module.args = {
inherit inputs;
inherit tree;
host_secrets = secrets;
};
imports = with tree;
[
profiles.base
inputs.home-manager-unstable.nixosModules.home-manager
profiles.sshd
modules.nixos.secrets
users.root
]
++ (with hosts.hetzner-vm.containers.matrix; [
profiles.matrix
profiles.restic
]);
# For Shared Secrets
systemd.tmpfiles.rules = [
"d ${config.services.secrets.secretsDir} - root root"
];
networking.firewall = {
enable = true;
allowedTCPPorts = [22 6167];
};
home-manager.users.root = {
imports = with tree; [home.base home.dev.small];
home.packages = with pkgs; [vault];
home.stateVersion = "22.05";
};
# Manually configure nameserver. Using resolved inside the container seems to fail
# currently
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
system.stateVersion = "22.05";
};
};
services.nginx = {
virtualHosts = {
"matrix.owo.monster" = {
forceSSL = true;
enableACME = true;
listen = [
{
addr = "0.0.0.0";
port = 80;
ssl = false;
}
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
{
addr = "0.0.0.0";
port = 8448;
ssl = true;
}
];
extraConfig = ''
merge_slashes off;
'';
locations."/" = {
root = pkgs.element-web;
};
locations."=/config.matrix.owo.monster.json" = {
alias = let
config = {
default_server_config = {
"m.homeserver" = {
"base_url" = "https://matrix.owo.monster";
};
"m.identity_server" = {
"base_url" = "https://vector.im";
};
};
brand = "Element";
bug_report_endpoint_url = "";
default_country_code = "GB";
default_federate = true;
default_theme = "dark";
disable_3pid_login = false;
disable_custom_urls = false;
disable_guests = false;
disable_login_language_selector = false;
jitsi.preferred_domain = "";
element_call = {
brand = "Element Call";
participant_limit = 8;
url = "";
};
enable_presence_by_hs_url = {
"https://matrix-client.matrix.org" = false;
"https://matrix.org" = false;
};
features = {};
integrations_rest_url = "https://scalar.vector.im/api";
integrations_ui_url = "https://scalar.vector.im/";
integrations_widgets_urls = ["https://scalar.vector.im/_matrix/integrations/v1" "https://scalar.vector.im/api" "https://scalar-staging.vector.im/_matrix/integrations/v1" "https://scalar-staging.vector.im/api" "https://scalar-staging.riot.im/scalar/api"];
map_style_url = "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx";
room_directory = {servers = ["matrix.org"];};
setting_defaults = {breadcrumbs = true;};
show_labs_settings = false;
uisi_autorageshake_app = "element-auto-uisi";
};
in
pkgs.writeText "config.matrix.owo.monster.json" (builtins.toJSON config);
extraConfig = ''
default_type application/json;
'';
};
locations."/_matrix/" = {
proxyPass = "http://backend_conduit$request_uri";
proxyWebsockets = true;
extraConfig = ''
proxy_set_header Host $host;
proxy_buffering off;
'';
};
locations."=/.well-known/matrix/server" = {
alias = let
config = {
"m.server" = "matrix.owo.monster";
};
in
pkgs.writeText "well-known-matrix-server" (builtins.toJSON config);
extraConfig = ''
default_type application/json;
'';
};
locations."=/.well-known/matrix/client" = {
alias = let
config = {
"m.homeserver" = {
"base_url" = "https://matrix.owo.monster";
};
"m.identity_server" = {
"base_url" = "https://vector.im";
};
};
in
pkgs.writeText "well-known-matrix-client" (builtins.toJSON config);
extraConfig = ''
default_type application/json;
add_header Access-Control-Allow-Origin "*";
'';
};
};
};
upstreams = {
"backend_conduit" = {
servers = {
"${containerIP}:${toString 6167}" = {};
};
};
};
};
networking.firewall.allowedTCPPorts = [80 443 8448];
networking.firewall.allowedUDPPorts = [80 443 8448];
}

View file

@ -1,14 +0,0 @@
{
inputs,
pkgs,
...
}: {
services.matrix-conduit = {
enable = true;
settings.global = {
address = "0.0.0.0";
allow_registration = true;
server_name = "matrix.owo.monster";
};
};
}

View file

@ -1,17 +0,0 @@
{
pkgs,
config,
host_secrets,
...
}: let
secrets = host_secrets;
in {
environment.systemPackages = [
(pkgs.writeShellScriptBin "restic-matrix" ''
env \
RESTIC_PASSWORD_FILE=${secrets.matrix_restic_password.path} \
$(cat ${secrets.matrix_restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
}

View file

@ -2,7 +2,6 @@
tree, tree,
lib, lib,
inputs, inputs,
pkgs,
config, config,
... ...
}: let }: let

View file

@ -1,5 +1,4 @@
{ {
config,
lib, lib,
pkgs, pkgs,
host_secrets, host_secrets,

View file

@ -0,0 +1,79 @@
{
pkgs,
config,
lib,
host_secrets,
...
}: let
secrets = host_secrets;
# Because gotosocial-admin isn't a seporate package we need to generate a seperate config
# and duplicate the wrapper for use in a systemd unit
goToSocialConfigFile = (pkgs.formats.yaml {}).generate "config.yml" config.services.gotosocial.settings;
goToSocialAdmin = "${(pkgs.writeShellScriptBin "goToSocialAdmin" ''
exec systemd-run \
-u gotosocial-admin.service \
-p Group=gotosocial \
-p User=gotosocial \
-q -t -G --wait --service-type=exec \
${pkgs.gotosocial}/bin/gotosocial --config-path ${goToSocialConfigFile} admin "$@"
'')}/bin/goToSocialAdmin";
backupPrepareCommand = "${
(pkgs.writeShellScriptBin "backupPrepareCommand" ''
systemctl start ${
lib.concatStringsSep " "
(lib.forEach config.services.postgresqlBackup.databases
(db: "postgresqlBackup-${db}"))
} --wait
${goToSocialAdmin} export --path /var/lib/gotosocial/gts-export.json
'')
}/bin/backupPrepareCommand";
backupCleanupCommand = "${(pkgs.writeShellScriptBin "backupCleanupCommand" ''
rm /var/lib/gotosocial/gts-export.json
'')}/bin/backupCleanupCommand";
in {
environment.systemPackages = [
(pkgs.writeShellScriptBin "restic-social" ''
env \
RESTIC_PASSWORD_FILE=${secrets.social_restic_password.path} \
$(cat ${secrets.social_restic_env.path}) \
${pkgs.restic}/bin/restic $@
'')
];
services.restic.backups.social = {
user = "root";
paths = [
"/var/backup/postgresql"
"/var/lib/gotosocial"
];
# repository is overrided in environmentFile to contain auth
# make sure to keep up to date when changing repository
repository = "rest:https://storage-restic.owo.monster/Social";
passwordFile = "${secrets.social_restic_password.path}";
environmentFile = "${secrets.social_restic_env.path}";
pruneOpts = [
"--keep-last 10"
];
timerConfig = {
OnBootSec = "1m";
OnCalendar = "daily";
};
inherit backupPrepareCommand;
inherit backupCleanupCommand;
};
services.postgresqlBackup = {
enable = true;
backupAll = false;
databases = ["gotosocial"];
compression = "zstd";
};
}

View file

@ -0,0 +1,30 @@
{...}: {
services.gotosocial = {
enable = true;
setupPostgresqlDB = true;
settings = {
application-name = "Chaos";
host = "gts-01.owo.monster";
bind-address = "0.0.0.0";
log-level = "info";
log-client-ip = false;
port = 8080;
letsencrypt-enabled = false;
accounts-registration-open = false;
media-image-max-size = 1000000 * 64; # MB
media-video-max-size = 1000000 * 1024; # MB
media-description-max-chars = 4000;
media-remote-cache-days = 3;
media-emoji-local-max-size = 102400;
media-emoji-remote-max-size = 102400;
statuses-cw-max-chars = 150;
statuses-poll-max-options = 10;
statuses-media-max-files = 8;
};
};
}

View file

@ -0,0 +1,96 @@
{
tree,
inputs,
config,
...
}: let
hostIP = "192.168.100.10";
containerIP = "192.168.100.12";
# Using secrets from Host
secrets = config.services.secrets.secrets;
in {
containers.social = {
autoStart = true;
privateNetwork = true;
hostAddress = hostIP;
localAddress = containerIP;
bindMounts = {
"${secrets.social_restic_password.path}" = {
hostPath = "${secrets.social_restic_password.path}";
};
"${secrets.social_restic_env.path}" = {
hostPath = "${secrets.social_restic_env.path}";
};
};
config = {
config,
pkgs,
...
}: {
_module.args = {
inherit inputs;
inherit tree;
host_secrets = secrets;
};
imports = with tree;
[
profiles.base
inputs.home-manager-unstable.nixosModules.home-manager
profiles.sshd
modules.nixos.secrets
users.root
]
++ (with hosts.hetzner-vm.containers.social; [
profiles.gotosocial
profiles.backups
]);
environment.systemPackages = with pkgs; [
rclone
restic
];
# For Shared Secrets
systemd.tmpfiles.rules = [
"d ${config.services.secrets.secretsDir} - root root"
];
networking.firewall = {
enable = true;
allowedTCPPorts = [22 8080];
};
home-manager.users.root = {
imports = with tree; [home.base home.dev.small];
home.packages = with pkgs; [vault];
home.stateVersion = "22.05";
};
# Manually configure nameserver. Using resolved inside the container seems to fail
# currently
environment.etc."resolv.conf".text = "nameserver 8.8.8.8";
system.stateVersion = "22.05";
};
};
services.nginx.virtualHosts."gts-01.owo.monster" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://${containerIP}:8080";
extraConfig = ''
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
'';
};
extraConfig = ''
client_max_body_size 128M;
'';
};
}

View file

@ -7,7 +7,7 @@
rclone_serve_restic_hvm = 4210; rclone_serve_restic_hvm = 4210;
rclone_serve_restic_music = 4211; rclone_serve_restic_music = 4211;
rclone_serve_restic_vault = 4212; rclone_serve_restic_vault = 4212;
rclone_serve_restic_matrix = 4213; rclone_serve_restic_social = 4213;
rclone_serve_http_music = 4220; rclone_serve_http_music = 4220;
rclone_serve_http_public = 4221; rclone_serve_http_public = 4221;

View file

@ -128,12 +128,12 @@ in {
} }
{ {
user = "storage"; user = "storage";
remote = "StorageBox:Backups/Restic/Matrix"; remote = "StorageBox:Backups/Restic/Social";
type = "restic"; type = "restic";
extraArgs = [ extraArgs = [
"--addr=0.0.0.0:${toString ports.rclone_serve_restic_matrix}" "--addr=0.0.0.0:${toString ports.rclone_serve_restic_social}"
"--htpasswd=${secrets.restic_matrix_htpasswd.path}" "--htpasswd=${secrets.restic_social_htpasswd.path}"
"--baseurl=/Matrix/" "--baseurl=/Social/"
]; ];
inherit serviceConfig; inherit serviceConfig;
} }

View file

@ -71,12 +71,12 @@
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
''; '';
}; };
restic_matrix_htpasswd = { restic_social_htpasswd = {
user = "storage"; user = "storage";
group = "storage"; group = "storage";
fetchScript = '' fetchScript = ''
username=$(simple_get "/api-keys/storage/restic/Matrix" .username) username=$(simple_get "/api-keys/storage/restic/Social" .username)
password=$(simple_get "/api-keys/storage/restic/Matrix" .password) password=$(simple_get "/api-keys/storage/restic/Social" .password)
htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null htpasswd -bc "$secretFile" "$username" "$password" 2>/dev/null
''; '';
}; };
@ -108,7 +108,6 @@
htpasswd -bc "$secretFile" "$username" "$password" 2>&1 htpasswd -bc "$secretFile" "$username" "$password" 2>&1
''; '';
}; };
rclone_config = { rclone_config = {
user = "storage"; user = "storage";
group = "storage"; group = "storage";

View file

@ -97,7 +97,7 @@ in {
"/HetznerVM/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_hvm}"; "/HetznerVM/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_hvm}";
"/Music/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_music}"; "/Music/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_music}";
"/Vault/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_vault}"; "/Vault/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_vault}";
"/Matrix/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_matrix}"; "/Social/".proxyPass = "http://${containerIP}:${toString ports.rclone_serve_restic_social}";
}; };
}; };
} }

View file

@ -11,7 +11,7 @@
profiles.nix-gc profiles.nix-gc
./containers/storage/storage.nix ./containers/storage/storage.nix
./containers/matrix/matrix.nix ./containers/social/social.nix
./containers/music/music.nix ./containers/music/music.nix
hosts.hetzner-vm.profiles.restic hosts.hetzner-vm.profiles.restic

View file

@ -51,6 +51,10 @@ in {
passwordFile = "${secrets.restic_password.path}"; passwordFile = "${secrets.restic_password.path}";
environmentFile = "${secrets.restic_env.path}"; environmentFile = "${secrets.restic_env.path}";
pruneOpts = [
"--keep-last 20"
];
timerConfig = { timerConfig = {
OnBootSec = "1m"; OnBootSec = "1m";
OnCalendar = "daily"; OnCalendar = "daily";

View file

@ -111,16 +111,17 @@
''; '';
}; };
matrix_restic_password = { social_restic_password = {
fetchScript = '' fetchScript = ''
simple_get "/private-public-keys/restic/Matrix" .password > $secretFile simple_get "/private-public-keys/restic/Social" .password > $secretFile
''; '';
}; };
matrix_restic_env = { social_restic_env = {
fetchScript = '' fetchScript = ''
RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Matrix" .username) RESTIC_USERNAME=$(simple_get "/api-keys/storage/restic/Social" .username)
RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Matrix" .password) RESTIC_PASSWORD=$(simple_get "/api-keys/storage/restic/Social" .password)
echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Matrix" > $secretFile ''; echo "RESTIC_REPOSITORY=rest:https://$RESTIC_USERNAME:$RESTIC_PASSWORD@storage-restic.owo.monster/Social" > $secretFile
'';
}; };
restic_password = { restic_password = {
fetchScript = '' fetchScript = ''

View file

@ -1,8 +1,4 @@
{ {tree, ...}: {
tree,
pkgs,
...
}: {
imports = with tree; [ imports = with tree; [
users.root users.root
users.chaos users.chaos

View file

@ -1,8 +1,4 @@
{ {tree, ...}: {
tree,
pkgs,
...
}: {
imports = with tree; [ imports = with tree; [
users.root users.root
users.chaos users.chaos

View file

@ -1,45 +0,0 @@
{
stdenv,
lib,
fetchFromGitLab,
rustPlatform,
pkg-config,
rocksdb,
}: let
meta = builtins.fromJSON (builtins.readFile ./meta.json);
rev = meta.rev;
sha256 = meta.sha256;
in
rustPlatform.buildRustPackage rec {
pname = "matrix-conduit";
version = "latest-${rev}";
src = fetchFromGitLab {
owner = "famedly";
repo = "conduit";
rev = "${rev}";
sha256 = "${sha256}";
};
cargoSha256 = "sha256-E9f7yJR2GksUHjWE4EP+iBRlhn4JG/JUVw7/L+41Nfc=";
nativeBuildInputs = [
rustPlatform.bindgenHook
pkg-config
];
buildInputs = [
rocksdb
];
cargoBuildFlags = ["--bin" "conduit"];
meta = with lib; {
broken = stdenv.isDarwin;
description = "A Matrix homeserver written in Rust";
homepage = "https://conduit.rs/";
license = licenses.asl20;
maintainers = with maintainers; [pstn piegames pimeys];
};
}

View file

@ -1,4 +0,0 @@
{
"rev": "7b987411630056204b73e61165c8a99e20a78fec",
"sha256": "sha256-xcNa18r1V+SM0J0NGDrt2xr+nFgAhutiVvTljUSeStM="
}

View file

@ -1,26 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p curl jq git moreutils nix nix-prefetch
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
json_get() {
jq -r "$1" < 'meta.json'
}
json_set() {
jq --arg x "$2" "$1 = \$x" < 'meta.json' | sponge 'meta.json'
}
old_rev=$(json_get '.rev')
new_rev=$(curl -L "https://gitlab.com/api/v4/projects/famedly%2Fconduit/repository/commits" 2>/dev/null | jq ".[0].id" -r)
if [ "$new_rev" = "$old_rev" ]; then
echo "conduit is up-to-date."
exit
fi
json_set '.rev' "$new_rev"
new_sha256=$(nix-prefetch fetchFromGitLab --owner famedly --repo conduit --rev "$new_rev")
json_set '.sha256' "$new_sha256"

View file

@ -9,6 +9,4 @@ final: _prev: {
}; };
piped-frontend = final.callPackage ./piped/frontend {}; piped-frontend = final.callPackage ./piped/frontend {};
piped-proxy = final.callPackage ./piped/proxy {}; piped-proxy = final.callPackage ./piped/proxy {};
# currently broken
#matrix-conduit = final.callPackage ./conduit {};
} }

View file

@ -1,6 +1,5 @@
{ {
config, config,
pkgs,
tree, tree,
... ...
}: { }: {

View file

@ -1,8 +1,6 @@
{config, ...}: { {config, ...}: {
services.xserver.libinput.enable = true; services.xserver.libinput.enable = true;
services.tlp.enable = true;
powerManagement.enable = true; powerManagement.enable = true;
powerManagement.powertop.enable = true;
hardware.acpilight.enable = true; hardware.acpilight.enable = true;
environment.systemPackages = [config.boot.kernelPackages.cpupower]; environment.systemPackages = [config.boot.kernelPackages.cpupower];
} }

3
profiles/tlp.nix Normal file
View file

@ -0,0 +1,3 @@
{...}: {
services.tlp.enable = true;
}

View file

@ -15,7 +15,7 @@
"hosts/hetzner-vm/modules/mailserver".functor.enable = true; "hosts/hetzner-vm/modules/mailserver".functor.enable = true;
"hosts/hetzner-vm/modules/piped".functor.enable = true; "hosts/hetzner-vm/modules/piped".functor.enable = true;
"hosts/hetzner-vm/containers/storage/profiles".functor.enable = true; "hosts/hetzner-vm/containers/storage/profiles".functor.enable = true;
"hosts/hetzner-vm/containers/matrix/profiles".functor.enable = true; "hosts/hetzner-vm/containers/social/profiles".functor.enable = true;
# Profiles # Profiles
"profiles/*".functor.enable = true; "profiles/*".functor.enable = true;