chore: deployment semantics

This commit is contained in:
2026-03-26 06:18:40 +02:00
parent f5fa5f4f6b
commit 409c8fd86b
7 changed files with 121 additions and 58 deletions

1
Cargo.lock generated
View File

@@ -2480,6 +2480,7 @@ dependencies = [
name = "rbv-cluster" name = "rbv-cluster"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"rayon",
"rbv-entity", "rbv-entity",
"thiserror 2.0.18", "thiserror 2.0.18",
"tracing", "tracing",

View File

@@ -3,7 +3,7 @@ server {
server_name rbv.internal; server_name rbv.internal;
http2 on; http2 on;
ssl_certificate /etc/nginx/tls/rbv/chain.pem; ssl_certificate /etc/nginx/tls/rbv/rbv.pem;
ssl_certificate_key /etc/nginx/tls/rbv/key.pem; ssl_certificate_key /etc/nginx/tls/rbv/key.pem;
root /usr/share/nginx/rbv; root /usr/share/nginx/rbv;

View File

@@ -8,7 +8,7 @@ Type=oneshot
Environment=RUST_LOG=info,ort=off,sqlx::query=off Environment=RUST_LOG=info,ort=off,sqlx::query=off
ExecStart=/usr/local/bin/rbv cluster \ ExecStart=/usr/local/bin/rbv cluster \
--database postgres://rbv:password@localhost:4432/rbv \ --database postgres://rbv:password@localhost:4432/rbv \
--concurrency 4 --concurrency 16
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@@ -8,7 +8,7 @@ OnSuccess=rbv-cluster.service
Environment=RUST_LOG=info,ort=off,sqlx::query=off Environment=RUST_LOG=info,ort=off,sqlx::query=off
ExecStart=/usr/local/bin/rbv index \ ExecStart=/usr/local/bin/rbv index \
--target /tank/data/rbv/%i \ --target /tank/data/rbv/%i \
--concurrency 24 \ --concurrency 16 \
--database postgres://rbv:password@localhost:4432/rbv \ --database postgres://rbv:password@localhost:4432/rbv \
--model-dir /tank/containers/immich/ml-cache --model-dir /tank/containers/immich/ml-cache
Restart=always Restart=always

12
asset/systemd/step@.timer Normal file
View File

@@ -0,0 +1,12 @@
[Unit]
Description=step cert renew
Documentation=https://hackmd.io/@rob-tn/rJvy9YYKWg
[Timer]
Persistent=true
OnCalendar=*:1/15
AccuracySec=1us
RandomizedDelaySec=5m
[Install]
WantedBy=timers.target

View File

@@ -47,7 +47,7 @@ sudo dnf install -y postgresql17-server pgvector_17
sudo /usr/pgsql-17/bin/postgresql-17-setup initdb sudo /usr/pgsql-17/bin/postgresql-17-setup initdb
# Enable and start # Enable and start
sudo systemctl enable --now postgresql-17 sudo systemctl enable --now postgresql-17.service
``` ```
### Make certificates readable by postgres ### Make certificates readable by postgres
@@ -56,63 +56,65 @@ Grant the postgres user read access via ACL, leaving ownership as root.
This way cert renewals take effect automatically without re-copying. This way cert renewals take effect automatically without re-copying.
```bash ```bash
sudo setfacl -m u:postgres:r \ sudo setfacl -m u:postgres:r /etc/pki/tls/private/$(hostname).pem
/etc/pki/tls/misc/frankie.hanzalova.internal.pem \
/etc/pki/tls/private/frankie.hanzalova.internal.pem \
/etc/pki/ca-trust/source/anchors/root-internal.pem
``` ```
### Configure postgresql.conf ### Configure postgresql.conf
```bash ```bash
sudo tee -a /var/lib/pgsql/17/data/postgresql.conf <<'EOF' sudo -u postgres mkdir -p /var/lib/pgsql/17/data/postgresql.conf.d
if ! sudo -u postgres grep 'postgresql.conf.d' /var/lib/pgsql/17/data/postgresql.conf &> /dev/null; then
# Network echo 'include_dir = postgresql.conf.d' | sudo -u postgres tee --append /var/lib/pgsql/17/data/postgresql.conf
listen_addresses = '*' fi
echo "listen_addresses = '*'" | sudo -u postgres tee /var/lib/pgsql/17/data/postgresql.conf.d/listen.conf
# TLS sudo -u postgres tee /var/lib/pgsql/17/data/postgresql.conf.d/ssl.conf <<'EOF'
ssl = on ssl = on
ssl_cert_file = '/etc/pki/tls/misc/frankie.hanzalova.internal.pem' ssl_cert_file = '/etc/pki/tls/misc/frankie.hanzalova.internal.pem'
ssl_key_file = '/etc/pki/tls/private/frankie.hanzalova.internal.pem' ssl_key_file = '/etc/pki/tls/private/frankie.hanzalova.internal.pem'
ssl_ca_file = '/etc/pki/ca-trust/source/anchors/root-internal.pem' ssl_ca_file = '/etc/pki/ca-trust/source/anchors/root-internal.pem'
EOF
# Memory — tune to ~25% of RAM for shared_buffers sudo -u postgres tee /var/lib/pgsql/17/data/postgresql.conf.d/memory.conf <<'EOF'
shared_buffers = 4GB shared_buffers = 4GB
work_mem = 64MB work_mem = 64MB
maintenance_work_mem = 512MB maintenance_work_mem = 512MB
EOF
# WAL sudo -u postgres tee /var/lib/pgsql/17/data/postgresql.conf.d/wal.conf <<'EOF'
wal_level = replica # needed for future Patroni replication wal_level = replica
max_wal_senders = 5 max_wal_senders = 5
wal_keep_size = 1GB wal_keep_size = 1GB
EOF
# Checkpoints sudo -u postgres tee /var/lib/pgsql/17/data/postgresql.conf.d/checkpoint.conf <<'EOF'
checkpoint_completion_target = 0.9 checkpoint_completion_target = 0.9
EOF EOF
sudo -u postgres tee /var/lib/pgsql/17/data/postgresql.conf.d/vchord.conf <<'EOF'
shared_preload_libraries = 'vchord'
EOF
sudo -u postgres tee /var/lib/pgsql/17/data/postgresql.conf.d/logging.conf <<'EOF'
log_destination = 'stderr'
logging_collector = off
EOF
sudo systemctl reload postgresql-17 sudo systemctl reload postgresql-17.service
``` ```
### Configure pg_hba.conf ### Configure pg_hba.conf
Replace the default rules with certificate-only authentication. Update the default rules with certificate-only authentication for lan connections.
Local unix-socket access retains `peer` for admin use. Local unix-socket access retains `peer` for admin use.
```bash ```bash
sudo tee /var/lib/pgsql/17/data/pg_hba.conf <<'EOF' sudo -u postgres mkdir -p /var/lib/pgsql/17/data/pg_hba.conf.d
# TYPE DATABASE USER ADDRESS METHOD if ! sudo -u postgres grep 'pg_hba.conf.d' /var/lib/pgsql/17/data/pg_hba.conf &> /dev/null; then
echo 'include_dir = pg_hba.conf.d' | sudo -u postgres tee --append /var/lib/pgsql/17/data/pg_hba.conf
# Local admin access (postgres OS user only) fi
local all postgres peer sudo -u postgres tee /var/lib/pgsql/17/data/pg_hba.conf.d/network-connections.conf <<'EOF'
hostnossl all all 0.0.0.0/0 reject
# All network connections must present a valid client certificate. hostssl all all 10.3.0.0/16 cert map=cert_cn
# The CN of the certificate is mapped to a database user via pg_ident.conf. hostssl all all 10.6.0.0/16 cert map=cert_cn
hostssl all all 0.0.0.0/0 cert clientcert=verify-full map=cn hostssl replication replicator 10.0.0.0/8 cert clientcert=verify-full map=cn
hostssl all all ::/0 cert clientcert=verify-full map=cn
# Replication (used by Patroni streaming replication)
hostssl replication replicator 0.0.0.0/0 cert clientcert=verify-full map=cn
EOF EOF
sudo systemctl reload postgresql-17.service
``` ```
### Configure pg_ident.conf ### Configure pg_ident.conf
@@ -121,11 +123,18 @@ Maps the CN of each client certificate to the appropriate database user.
Add a line for each application host. Add a line for each application host.
```bash ```bash
sudo tee /var/lib/pgsql/17/data/pg_ident.conf <<'EOF' sudo -u postgres mkdir -p /var/lib/pgsql/17/data/pg_ident.conf.d
# MAPNAME SYSTEM-USERNAME (certificate CN) PG-USERNAME if ! sudo -u postgres grep 'pg_ident.conf.d' /var/lib/pgsql/17/data/pg_ident.conf &> /dev/null; then
cn gramathea.kosherinata.internal rbv echo 'include_dir = pg_ident.conf.d' | sudo -u postgres tee --append /var/lib/pgsql/17/data/pg_ident.conf
cn gramathea.kosherinata.internal immich fi
sudo -u postgres tee /var/lib/pgsql/17/data/pg_ident.conf.d/immich.conf <<'EOF'
cn gramathea.kosherinata.internal immich
EOF EOF
sudo -u postgres tee /var/lib/pgsql/17/data/pg_ident.conf.d/rbv.conf <<'EOF'
cn gramathea.kosherinata.internal rbv
EOF
sudo systemctl reload postgresql-17.service
``` ```
### Create roles and databases ### Create roles and databases
@@ -150,17 +159,36 @@ VectorChord is not in PGDG — install from the GitHub release zip.
Check https://github.com/tensorchord/VectorChord/releases for the current version. Check https://github.com/tensorchord/VectorChord/releases for the current version.
```bash ```bash
wget https://github.com/tensorchord/VectorChord/releases/download/1.1.1/postgresql-17-vchord_1.1.1_x86_64-linux-gnu.zip curl \
unzip postgresql-17-vchord_1.1.1_x86_64-linux-gnu.zip --fail \
--show-error \
--location \
--silent \
--output /tmp/postgresql-17-vchord_1.1.1_x86_64-linux-gnu.zip \
--url https://github.com/tensorchord/VectorChord/releases/download/1.1.1/postgresql-17-vchord_1.1.1_x86_64-linux-gnu.zip
unzip \
-d /tmp/vchord \
/tmp/postgresql-17-vchord_1.1.1_x86_64-linux-gnu.zip
sudo cp pkglibdir/vchord.so /usr/pgsql-17/lib/ sudo install \
sudo cp sharedir/extension/vchord* /usr/pgsql-17/share/extension/ --owner root \
--group root \
/tmp/vchord/pkglibdir/vchord.so \
/usr/pgsql-17/lib/
sudo install \
--owner root \
--group root \
--mode 644 \
/tmp/vchord/sharedir/extension/vchord* \
/usr/pgsql-17/share/extension/
rm -rf pkglibdir sharedir postgresql-17-vchord_1.1.1_x86_64-linux-gnu.zip rm -rf /tmp/vchord /tmp/postgresql-17-vchord_1.1.1_x86_64-linux-gnu.zip
``` ```
VectorChord requires preloading (needs a restart, not just reload): VectorChord requires preloading (needs a restart, not just reload):
> [!CAUTION]
> deprecated in favour of `/var/lib/pgsql/17/data/postgresql.conf.d/vchord.conf` above.
```bash ```bash
sudo tee -a /var/lib/pgsql/17/data/postgresql.conf <<'EOF' sudo tee -a /var/lib/pgsql/17/data/postgresql.conf <<'EOF'
@@ -188,8 +216,9 @@ EOF
### Open firewall port ### Open firewall port
```bash ```bash
sudo firewall-cmd --permanent --add-service=postgresql sudo firewall-cmd --zone=$(firewall-cmd --get-default-zone) --add-service postgresql --permanent
sudo firewall-cmd --reload sudo firewall-cmd --reload
sudo firewall-cmd --list-services
``` ```
### Migrate data from gramathea ### Migrate data from gramathea

View File

@@ -1,3 +1,4 @@
#!/usr/bin/env bash
postgres_host=gramathea.kosherinata.internal postgres_host=gramathea.kosherinata.internal
api_host=gramathea.kosherinata.internal api_host=gramathea.kosherinata.internal
@@ -111,6 +112,7 @@ deploy_ui() {
${ui_host}:/tmp/provisioner \ ${ui_host}:/tmp/provisioner \
&& ssh ${ui_host} sudo mkdir -p /etc/nginx/tls/rbv \ && ssh ${ui_host} sudo mkdir -p /etc/nginx/tls/rbv \
&& ssh ${ui_host} sudo step ca certificate \ && ssh ${ui_host} sudo step ca certificate \
--force \
--provisioner lair \ --provisioner lair \
--provisioner-password-file /tmp/provisioner \ --provisioner-password-file /tmp/provisioner \
--ca-url https://ca.internal \ --ca-url https://ca.internal \
@@ -126,18 +128,37 @@ deploy_ui() {
exit 1 exit 1
fi fi
if rsync \ for unit in step@.{service,timer}; do
--archive \ if rsync \
--compress \ --archive \
--rsync-path 'sudo rsync' \ --compress \
--chown root:root \ --rsync-path 'sudo rsync' \
asset/systemd/step@.service \ --chown root:root \
${ui_host}:/etc/systemd/system/step@.service; then asset/systemd/${unit} \
echo 'step cert renewal service deployed successfully' ${ui_host}:/etc/systemd/system/${unit}; then
else echo "${unit} deployed successfully"
echo 'failed to deploy step cert renewal service' else
exit 1 echo "failed to deploy ${unit}"
fi exit 1
fi
done
ssh ${ui_host} "
sudo systemctl daemon-reload
if ! systemctl is-enabled --quiet step@rbv.timer; then
if sudo systemctl enable step@rbv.timer; then
echo 'step@rbv.timer enabled'
else
echo 'failed to enable step@rbv.timer'
fi
fi
if ! systemctl is-active --quiet step@rbv.timer; then
if sudo systemctl start step@rbv.timer; then
echo 'step@rbv.timer started'
else
echo 'failed to start step@rbv.timer'
fi
fi
"
(cd ui && npm run build) (cd ui && npm run build)
if ssh ${ui_host} sudo mkdir -p /usr/share/nginx/rbv \ if ssh ${ui_host} sudo mkdir -p /usr/share/nginx/rbv \