From 2ba9dc2ec1a80d9609c50a39b7dbb36cb00caa2c Mon Sep 17 00:00:00 2001 From: Omar Shaarawi <16183117+omarshaarawi@users.noreply.github.com> Date: Tue, 2 Jun 2026 16:22:42 -0500 Subject: [PATCH] Guard Litestream to production so preview envs can't clobber prod R2 (#2) Mirrors frontdesk/norblom/bloomcrawl. start.sh ran 'litestream replicate' unconditionally; a Railway PR-preview env clones prod R2_* creds and would replicate its writes back over the prod backup. Gate on RAILWAY_ENVIRONMENT_NAME: only production runs Litestream; non-prod runs an ephemeral local DB. Prerequisite for project-wide prDeploys. --- scripts/start.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/start.sh b/scripts/start.sh index 0f923757..0623b259 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -2,6 +2,17 @@ set -e DB=/data/docuseal/db.sqlite3 mkdir -p /data/docuseal + +# Litestream replicates to the prod R2 path (litestream.yml). Only production may +# touch it. A Railway PR-preview / staging env clones production's R2_* creds, so +# without this guard it would restore prod data and replicate its own writes back +# over the prod backup — silent data loss. Non-prod envs run an ephemeral local +# DB, no R2. +if [ "$RAILWAY_ENVIRONMENT_NAME" != "production" ]; then + echo "[start.sh] env=${RAILWAY_ENVIRONMENT_NAME:-local}: skipping Litestream (ephemeral DB, no R2)." + exec /app/bin/bundle exec puma -C /app/config/puma.rb --dir /app +fi + if [ ! -f "$DB" ]; then echo "[start.sh] DB missing — restoring from R2 via litestream..." litestream restore -if-replica-exists -config /etc/litestream.yml "$DB" || echo "[start.sh] WARN: restore failed; starting empty."