Added nginx upload limit
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
../../nixos/roles/frontpage
|
../../nixos/roles/frontpage
|
||||||
# ../../nixos/roles/paperless-ngx.nix
|
# ../../nixos/roles/paperless-ngx.nix
|
||||||
../../nixos/roles/octoprint.nix
|
../../nixos/roles/octoprint.nix
|
||||||
|
../../nixos/roles/matrix/postgres-backup.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ in
|
|||||||
|
|
||||||
lfs = {
|
lfs = {
|
||||||
enable = true;
|
enable = true;
|
||||||
#contentDir = "${config.services.gitea.stateDir}/data/lfs";
|
contentDir = "${config.services.gitea.stateDir}/data/lfs";
|
||||||
};
|
};
|
||||||
|
|
||||||
database = {
|
database = {
|
||||||
@@ -104,11 +104,6 @@ in
|
|||||||
DISABLE_SSH = false;
|
DISABLE_SSH = false;
|
||||||
START_SSH_SERVER = true;
|
START_SSH_SERVER = true;
|
||||||
LFS_START_SERVER = true;
|
LFS_START_SERVER = true;
|
||||||
LFS_JWT_SECRET_URI = "file://${config.sops.secrets."gitea/lfsJwtSecret".path}";
|
|
||||||
};
|
|
||||||
|
|
||||||
lfs = {
|
|
||||||
PATH = "${config.services.gitea.stateDir}/data/lfs";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
metrics = {
|
metrics = {
|
||||||
|
|||||||
@@ -7,96 +7,108 @@
|
|||||||
{
|
{
|
||||||
sops.secrets = {
|
sops.secrets = {
|
||||||
pg_replication_password = {
|
pg_replication_password = {
|
||||||
owner = "postgres";
|
owner = "root";
|
||||||
group = "postgres";
|
group = "root";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.postgresql = {
|
virtualisation.docker.enable = true;
|
||||||
enable = true;
|
|
||||||
package = pkgs.postgresql_15; # must match cyper-proxy's PG version exactly
|
|
||||||
|
|
||||||
settings = {
|
systemd.services.postgresql-replica = {
|
||||||
hot_standby = true;
|
description = "PostgreSQL WAL streaming replica (Docker)";
|
||||||
hot_standby_feedback = true;
|
|
||||||
max_standby_streaming_delay = "30s";
|
|
||||||
listen_addresses = "127.0.0.1"; # only local, no external exposure
|
|
||||||
wal_receiver_timeout = "60s";
|
|
||||||
recovery_min_apply_delay = "0"; # set e.g. "1h" for a delayed safety replica
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Writes standby.signal and primary_conninfo before PostgreSQL starts.
|
|
||||||
systemd.services.postgresql = {
|
|
||||||
preStart = lib.mkAfter ''
|
|
||||||
DATADIR="${config.services.postgresql.dataDir}"
|
|
||||||
PG_PASS=$(cat ${config.sops.secrets.pg_replication_password.path})
|
|
||||||
|
|
||||||
# Tell Postgres to start as a hot standby
|
|
||||||
if [ ! -f "$DATADIR/standby.signal" ]; then
|
|
||||||
touch "$DATADIR/standby.signal"
|
|
||||||
chown postgres:postgres "$DATADIR/standby.signal"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# primary_conninfo via Tailscale — no public IP involved
|
|
||||||
CONNINFO="host=100.109.10.91 port=5432 user=replicator password=$PG_PASS application_name=cyper-controller sslmode=require"
|
|
||||||
|
|
||||||
grep -v "^primary_conninfo" "$DATADIR/postgresql.auto.conf" 2>/dev/null > /tmp/auto.conf.tmp || true
|
|
||||||
echo "primary_conninfo = '$CONNINFO'" >> /tmp/auto.conf.tmp
|
|
||||||
mv /tmp/auto.conf.tmp "$DATADIR/postgresql.auto.conf"
|
|
||||||
chown postgres:postgres "$DATADIR/postgresql.auto.conf"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Run once manually to seed the standby: systemctl start postgresql-basebackup
|
|
||||||
# Do NOT add it to wantedBy — it would wipe the data dir on every reboot.
|
|
||||||
systemd.services.postgresql-basebackup = {
|
|
||||||
description = "Bootstrap PostgreSQL standby via pg_basebackup from cyper-proxy";
|
|
||||||
requires = [
|
requires = [
|
||||||
"network-online.target"
|
"docker.service"
|
||||||
"tailscaled.service"
|
"tailscaled.service"
|
||||||
|
"network-online.target"
|
||||||
];
|
];
|
||||||
after = [
|
after = [
|
||||||
"network-online.target"
|
"docker.service"
|
||||||
"tailscaled.service"
|
"tailscaled.service"
|
||||||
|
"network-online.target"
|
||||||
];
|
];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "simple";
|
||||||
User = "postgres";
|
Restart = "on-failure";
|
||||||
RemainAfterExit = false;
|
RestartSec = "10s";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
DATADIR="/storage/backup/postgresql-replica"
|
||||||
|
PG_PASS=$(cat ${config.sops.secrets.pg_replication_password.path})
|
||||||
|
|
||||||
|
${pkgs.docker}/bin/docker pull postgres:17
|
||||||
|
|
||||||
|
if [ ! -f "$DATADIR/PG_VERSION" ]; then
|
||||||
|
echo "No data dir found — running pg_basebackup..."
|
||||||
|
rm -rf "$DATADIR"
|
||||||
|
|
||||||
|
${pkgs.docker}/bin/docker run --rm \
|
||||||
|
-e PGPASSWORD="$PG_PASS" \
|
||||||
|
-v "/storage/backup:/out" \
|
||||||
|
--network host \
|
||||||
|
postgres:17 \
|
||||||
|
pg_basebackup \
|
||||||
|
--host=100.109.10.91 \
|
||||||
|
--port=5432 \
|
||||||
|
--username=replicator \
|
||||||
|
--pgdata=/out/postgresql-replica \
|
||||||
|
--wal-method=stream \
|
||||||
|
--checkpoint=fast \
|
||||||
|
--progress \
|
||||||
|
--verbose
|
||||||
|
|
||||||
|
# standby signal
|
||||||
|
touch "$DATADIR/standby.signal"
|
||||||
|
|
||||||
|
# primary conninfo
|
||||||
|
cat > "$DATADIR/postgresql.auto.conf" <<EOF
|
||||||
|
primary_conninfo = 'host=100.109.10.91 port=5432 user=replicator password=$PG_PASS application_name=cyper-controller sslmode=require'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# minimal postgresql.conf
|
||||||
|
cat > "$DATADIR/postgresql.conf" <<EOF
|
||||||
|
hot_standby = on
|
||||||
|
hot_standby_feedback = on
|
||||||
|
wal_receiver_timeout = '60s'
|
||||||
|
port = 5434
|
||||||
|
listen_addresses = '*'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chown -R 999:999 "$DATADIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ensure postgresql.conf exists on subsequent starts
|
||||||
|
if [ ! -f "$DATADIR/postgresql.conf" ]; then
|
||||||
|
cat > "$DATADIR/postgresql.conf" <<EOF
|
||||||
|
hot_standby = on
|
||||||
|
hot_standby_feedback = on
|
||||||
|
wal_receiver_timeout = '60s'
|
||||||
|
port = 5434
|
||||||
|
listen_addresses = '*'
|
||||||
|
EOF
|
||||||
|
chown 999:999 "$DATADIR/postgresql.conf"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
script = ''
|
script = ''
|
||||||
DATADIR="${config.services.postgresql.dataDir}"
|
${pkgs.docker}/bin/docker run --rm \
|
||||||
PG_PASS=$(cat ${config.sops.secrets.pg_replication_password.path})
|
--name postgresql-replica \
|
||||||
|
-v /storage/backup/postgresql-replica:/var/lib/postgresql/data \
|
||||||
|
--network host \
|
||||||
|
postgres:17
|
||||||
|
'';
|
||||||
|
|
||||||
if [ -d "$DATADIR/global" ]; then
|
postStop = ''
|
||||||
echo "Data directory already exists — skipping."
|
${pkgs.docker}/bin/docker rm -f postgresql-replica 2>/dev/null || true
|
||||||
echo "Remove $DATADIR manually to force a re-initialise."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Running pg_basebackup from cyper-proxy via Tailscale..."
|
|
||||||
PGPASSWORD="$PG_PASS" ${config.services.postgresql.package}/bin/pg_basebackup \
|
|
||||||
--host=100.109.10.91 \
|
|
||||||
--port=5432 \
|
|
||||||
--username=replicator \
|
|
||||||
--pgdata="$DATADIR" \
|
|
||||||
--wal-method=stream \
|
|
||||||
--write-recovery-conf \
|
|
||||||
--checkpoint=fast \
|
|
||||||
--progress \
|
|
||||||
--verbose
|
|
||||||
|
|
||||||
chown -R postgres:postgres "$DATADIR"
|
|
||||||
chmod 0700 "$DATADIR"
|
|
||||||
echo "Done. Start postgresql.service to begin streaming replication."
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Block any external access to postgres on the public interface
|
services.prometheus.exporters.postgres = {
|
||||||
networking.firewall = {
|
enable = true;
|
||||||
interfaces."tailscale0".allowedTCPPorts = [ ]; # replication is outbound only
|
port = 9188;
|
||||||
|
runAsLocalSuperUser = false;
|
||||||
|
dataSourceName = "postgresql://postgres@localhost:5434/postgres?sslmode=disable";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ in
|
|||||||
metrics_path = "/_synapse/metrics";
|
metrics_path = "/_synapse/metrics";
|
||||||
static_configs = [
|
static_configs = [
|
||||||
{
|
{
|
||||||
targets = [ "127.0.0.1:9009" ];
|
targets = [ "100.109.10.91:9009" ];
|
||||||
labels = {
|
labels = {
|
||||||
instance = config.networking.hostName;
|
instance = config.networking.hostName;
|
||||||
job = "master";
|
job = "master";
|
||||||
@@ -143,6 +143,28 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
job_name = "postgresql-replica";
|
||||||
|
static_configs = [
|
||||||
|
{
|
||||||
|
targets = [ "localhost:9188" ];
|
||||||
|
labels = {
|
||||||
|
instance = config.networking.hostName;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
job_name = "postgresql-proxy";
|
||||||
|
static_configs = [
|
||||||
|
{
|
||||||
|
targets = [ "100.109.10.91:9188" ];
|
||||||
|
labels = {
|
||||||
|
instance = "cyper-proxy";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
]
|
]
|
||||||
++ (lib.mapAttrsToList mkNodeJob extraNodes)
|
++ (lib.mapAttrsToList mkNodeJob extraNodes)
|
||||||
++ (mkWeatherScrapeConfigs weatherCities);
|
++ (mkWeatherScrapeConfigs weatherCities);
|
||||||
|
|||||||
@@ -40,7 +40,11 @@ in
|
|||||||
|
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
# controller services (proxied to upstream tailscale node)
|
# controller services (proxied to upstream tailscale node)
|
||||||
"git.cyperpunk.de" = mkProxy 9000;
|
"git.cyperpunk.de" = (mkProxy 9000) // {
|
||||||
|
extraConfig = ''
|
||||||
|
client_max_body_size 500m;
|
||||||
|
'';
|
||||||
|
};
|
||||||
"search.cyperpunk.de" = mkProxy 11080;
|
"search.cyperpunk.de" = mkProxy 11080;
|
||||||
"file.cyperpunk.de" = mkProxy 10000;
|
"file.cyperpunk.de" = mkProxy 10000;
|
||||||
"ngx.cyperpunk.de" = mkWsProxy 28101;
|
"ngx.cyperpunk.de" = mkWsProxy 28101;
|
||||||
|
|||||||
Reference in New Issue
Block a user