Owner decision 2026-10-07: production's mongod becomes a one-member replica set (rs0), so that a backup can read every collection at one instant (a snapshot read session), which a standalone mongod can't. The unit runs mongod with --replSet rs0 and a 990 MB oplog; setup.sh converts it once, idempotently (PrivaPub stopped, mongod restarted, rs.initiate, the primary awaited, PrivaPub started); every connection string says directConnection=true, which works against the standalone too, so this code can deploy before the conversion. The CI's throwaway mongod and the pasture's are replica sets as well, so the snapshot path is what the tests exercise; MongoTopology tells which a mongod is, and TopologyTests holds the test mongod to it. The suite passes on it (906). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
68 lines
3.1 KiB
Bash
Executable File
68 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# One-time root setup on Max for PrivaPub at privapub.thepra.dev. Idempotent.
|
|
# rsync -a -e $MAX/ssh.sh deploy/ root@nuvola.xyz:/root/privapub-deploy/
|
|
# $MAX/run.sh bash /root/privapub-deploy/max/setup.sh
|
|
set -euo pipefail
|
|
SRC="${1:-/root/privapub-deploy}"
|
|
HOST=privapub.thepra.dev
|
|
UNIT=privapub
|
|
RUNNER=build-runner
|
|
ACME=/root/.acme.sh/acme.sh
|
|
|
|
echo "== directories"
|
|
install -d -o "$RUNNER" -g www-data -m 755 /var/www/$HOST
|
|
install -d -o "$RUNNER" -g "$RUNNER" -m 750 /var/backups/$HOST
|
|
install -d -o www-data -g www-data -m 750 /var/lib/privapub /var/lib/privapub/mongo
|
|
# backups: the service writes them, and so does the deploy (as $RUNNER, a member of www-data) before each deploy
|
|
install -d -o www-data -g www-data -m 2770 /var/lib/privapub/backups
|
|
|
|
echo "== sudoers"
|
|
SUDOERS=/etc/sudoers.d/$RUNNER
|
|
touch "$SUDOERS"; chmod 440 "$SUDOERS"
|
|
grep -qF "systemctl start $UNIT," "$SUDOERS" || echo "$RUNNER ALL=(root) NOPASSWD: /usr/bin/systemctl start $UNIT, /usr/bin/systemctl stop $UNIT, /usr/bin/systemctl restart $UNIT, /usr/bin/systemctl is-active $UNIT, /usr/bin/systemctl show $UNIT*, /usr/bin/systemctl status $UNIT*" >> "$SUDOERS"
|
|
visudo -cf "$SUDOERS"
|
|
|
|
echo "== units"
|
|
install -m 644 "$SRC/systemd/privapub-mongod.service" /etc/systemd/system/privapub-mongod.service
|
|
install -m 644 "$SRC/systemd/$UNIT.service" /etc/systemd/system/$UNIT.service
|
|
systemctl daemon-reload
|
|
systemctl enable --now privapub-mongod >/dev/null
|
|
systemctl enable $UNIT >/dev/null
|
|
systemctl is-active privapub-mongod
|
|
|
|
echo "== replica set"
|
|
# once: mongod restarted with --replSet (PrivaPub stopped meanwhile), the one-member set rs0 made, its primary awaited
|
|
if [ "$(mongosh --quiet --port 27022 --eval 'db.hello().setName' 2>/dev/null)" != "rs0" ]; then
|
|
systemctl stop $UNIT
|
|
systemctl restart privapub-mongod
|
|
for _ in $(seq 1 60); do mongosh --quiet --port 27022 --eval 'db.hello()' >/dev/null 2>&1 && break; sleep 1; done
|
|
mongosh --quiet --port 27022 --eval "rs.initiate({_id: 'rs0', members: [{_id: 0, host: '127.0.0.1:27022'}]})" >/dev/null
|
|
for _ in $(seq 1 60); do [ "$(mongosh --quiet --port 27022 --eval 'db.hello().isWritablePrimary')" = "true" ] && break; sleep 1; done
|
|
systemctl start $UNIT
|
|
fi
|
|
echo "replica set: $(mongosh --quiet --port 27022 --eval 'db.hello().setName')"
|
|
|
|
echo "== nginx snippet and bootstrap vhost"
|
|
install -m 644 "$SRC/nginx/privapub-headers.conf" /etc/nginx/snippets/privapub-headers.conf
|
|
if [ -f /root/.acme.sh/${HOST}_ecc/fullchain.cer ]; then
|
|
install -m 644 "$SRC/nginx/$HOST.conf" /etc/nginx/sites-available/$HOST.conf
|
|
else
|
|
awk '/^server \{/{n++} n==1' "$SRC/nginx/$HOST.conf" > /etc/nginx/sites-available/$HOST.conf
|
|
fi
|
|
ln -sf /etc/nginx/sites-available/$HOST.conf /etc/nginx/sites-enabled/$HOST.conf
|
|
nginx -t
|
|
systemctl reload nginx
|
|
|
|
echo "== certificate"
|
|
if [ -f /root/.acme.sh/${HOST}_ecc/fullchain.cer ]; then
|
|
echo "$HOST: certificate present"
|
|
else
|
|
$ACME --issue --server letsencrypt -d $HOST -w /var/www/acme --renew-hook "systemctl reload nginx"
|
|
fi
|
|
|
|
echo "== full vhost"
|
|
install -m 644 "$SRC/nginx/$HOST.conf" /etc/nginx/sites-available/$HOST.conf
|
|
nginx -t
|
|
systemctl reload nginx
|
|
echo "setup complete"
|