chore: deployment semantics
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -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",
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
12
asset/systemd/step@.timer
Normal 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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
Reference in New Issue
Block a user