mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-27 21:01:03 +08:00
Ships a compressed RAM/device snapshot (stack-emulator-<arch>.savevm.zst) alongside the qcow2. `emulator start` resumes from it and rotates the per-install secrets in place, taking cold-boot from 30-120s to ~6-7s. Build phase adds a STACKCFG runtime ISO so stack.service can boot during image creation, starts qemu-guest-agent so its virtio-serial port stays open in the snapshot, then stop+migrate file:+quit via QMP. Runtime sends fresh secrets through QGA guest-exec input-data, which pipes them to trigger-fast-rotate and rotate-secrets inside the container: targeted sed on the placeholder PCK in built JS, UPDATE on the internal ApiKeySet, supervisorctl restart stack-app + cron-jobs. Placeholder hex values are baked in instead of random keys under STACK_EMULATOR_BUILD_SNAPSHOT=1 so no real secret ships in the snapshot. Device topology and SMP must match at capture and resume; runtime adds phantom seed/bundle drives and pins SMP=4. Cold-boot fallback kicks in automatically when the snapshot is missing, corrupt, or incompatible. supervisord.conf now uses stopasgroup/killasgroup for stack-app and cron-jobs so supervisor restart actually kills the Node children (they were keeping their port bindings and breaking rotation).
45 lines
1.8 KiB
Bash
45 lines
1.8 KiB
Bash
#!/bin/bash
|
|
set -e
|
|
|
|
PGDATA=/data/postgres
|
|
PG_BIN=/usr/lib/postgresql/16/bin
|
|
|
|
if [ -z "$(ls -A "$PGDATA" 2>/dev/null)" ]; then
|
|
gosu postgres "$PG_BIN/initdb" -D "$PGDATA" --no-sync --auth-local=trust --auth-host=md5
|
|
|
|
{
|
|
echo "host all all 0.0.0.0/0 md5"
|
|
echo "host all all ::/0 md5"
|
|
} >> "$PGDATA/pg_hba.conf"
|
|
|
|
echo "shared_preload_libraries = 'pg_stat_statements'" >> "$PGDATA/postgresql.conf"
|
|
echo "pg_stat_statements.track = all" >> "$PGDATA/postgresql.conf"
|
|
|
|
gosu postgres "$PG_BIN/pg_ctl" -D "$PGDATA" start -w \
|
|
-o "-c listen_addresses=127.0.0.1 -c shared_preload_libraries=pg_stat_statements"
|
|
|
|
gosu postgres psql -c "ALTER USER postgres PASSWORD 'PASSWORD-PLACEHOLDER--uqfEC1hmmv';"
|
|
gosu postgres psql -c "CREATE DATABASE stackframe;"
|
|
gosu postgres psql -c "CREATE DATABASE svix;"
|
|
gosu postgres psql -d stackframe -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements;"
|
|
gosu postgres psql -d stackframe -c "CREATE ROLE anon NOLOGIN;"
|
|
gosu postgres psql -d stackframe -c "CREATE ROLE authenticated NOLOGIN;"
|
|
|
|
gosu postgres "$PG_BIN/pg_ctl" -D "$PGDATA" stop -w
|
|
fi
|
|
|
|
# Generate a fresh CRON_SECRET per container start. The cron endpoints are
|
|
# internal — nothing outside the container calls them — so we don't want the
|
|
# baked-in mock value from .env.development to be a usable credential against
|
|
# a running emulator. Overriding here propagates to both the backend and the
|
|
# run-cron-jobs.sh loop via supervisord's inherited environment.
|
|
#
|
|
# In snapshot-build mode the VM supplies a deterministic placeholder via the
|
|
# --env-file so the baked snapshot doesn't contain a real secret; on resume,
|
|
# /usr/local/bin/rotate-secrets swaps in a fresh per-install value.
|
|
if [ -z "${CRON_SECRET:-}" ]; then
|
|
export CRON_SECRET="$(openssl rand -hex 32)"
|
|
fi
|
|
|
|
exec /usr/bin/supervisord -n -c /etc/supervisor/conf.d/supervisord.conf
|