Recently Written · git

subplz-web

git clone https://github.com/equwal/subplz-web

Log | Files | Refs


infra/burst/state/setup-web-server.sh (3012 bytes)

1 #!/bin/bash
2 # Set up the shared state of burst mode on the web server (Debian 12):
3 #
4 #   - Postgres on 127.0.0.1: role and database "subplz".
5 #   - Redis on 127.0.0.1, with a password, and a journal on disk.
6 #   - The user "subplz-tunnel": burst workers log in as this user only to
7 #     forward two ports (Postgres and Redis). No shell, no other port.
8 #   - A nightly Postgres backup to the bucket (enabled by the runbook).
9 #
10 # Terraform (main.tf) runs this script on the web server itself. It is
11 # idempotent: a second run changes nothing. Input: POSTGRES_PASSWORD,
12 # REDIS_PASSWORD, TUNNEL_PUBLIC_KEY in the environment.
13 set -euo pipefail
14 : "${POSTGRES_PASSWORD:?}" "${REDIS_PASSWORD:?}" "${TUNNEL_PUBLIC_KEY:?}"
15 
16 export DEBIAN_FRONTEND=noninteractive
17 apt-get update -q
18 apt-get install -y -q postgresql redis-server rclone
19 
20 # --- Postgres: the Debian package listens on localhost only. -----------------
21 runuser -u postgres -- psql -q -v ON_ERROR_STOP=1 -v pw="$POSTGRES_PASSWORD" <<'SQL'
22 SELECT 'CREATE ROLE subplz LOGIN' WHERE NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'subplz')\gexec
23 ALTER ROLE subplz PASSWORD :'pw';
24 SELECT 'CREATE DATABASE subplz OWNER subplz' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'subplz')\gexec
25 SQL
26 
27 # --- Redis: localhost only, a password, and a journal (the queue survives a restart).
28 conf=/etc/redis/redis.conf
29 set_conf() {
30   if grep -q "^$1 " "$conf"; then
31     sed -i "s|^$1 .*|$1 $2|" "$conf"
32   else
33     echo "$1 $2" >> "$conf"
34   fi
35 }
36 set_conf bind "127.0.0.1 -::1"
37 set_conf requirepass "$REDIS_PASSWORD"
38 set_conf appendonly yes
39 systemctl restart redis-server
40 
41 # --- The tunnel user. ---------------------------------------------------------
42 if ! id subplz-tunnel >/dev/null 2>&1; then
43   useradd --system --create-home --shell /usr/sbin/nologin subplz-tunnel
44 fi
45 home=$(getent passwd subplz-tunnel | cut -d: -f6)
46 install -d -m 700 -o subplz-tunnel -g subplz-tunnel "$home/.ssh"
47 printf 'restrict,port-forwarding,permitopen="127.0.0.1:5432",permitopen="127.0.0.1:6379" %s\n' \
48   "$TUNNEL_PUBLIC_KEY" > "$home/.ssh/authorized_keys"
49 chown subplz-tunnel:subplz-tunnel "$home/.ssh/authorized_keys"
50 chmod 600 "$home/.ssh/authorized_keys"
51 
52 # --- Nightly backup of Postgres to the bucket. The runbook writes
53 # /etc/subplz-rclone.env and /etc/subplz-backup.env, then enables the timer.
54 cat > /etc/systemd/system/subplz-pgdump.service <<'UNIT'
55 [Unit]
56 Description=Back up the subplz Postgres database to the bucket
57 
58 [Service]
59 Type=oneshot
60 EnvironmentFile=/etc/subplz-rclone.env
61 EnvironmentFile=/etc/subplz-backup.env
62 ExecStart=/bin/bash -c 'set -o pipefail; runuser -u postgres -- pg_dump -Fc subplz | rclone rcat "r2:$BUCKET/backups/subplz-$(date -u +%%Y%%m%%d).dump"'
63 UNIT
64 cat > /etc/systemd/system/subplz-pgdump.timer <<'UNIT'
65 [Unit]
66 Description=Back up the subplz Postgres database each night
67 
68 [Timer]
69 OnCalendar=*-*-* 04:30:00
70 Persistent=true
71 
72 [Install]
73 WantedBy=timers.target
74 UNIT
75 systemctl daemon-reload
76 echo "web server ready: Postgres, Redis, tunnel user"