Developer Guide
Deploy to GFI VPS (dev)
Run OpenStory as a gfi-run HTTP service on the Hetzner testnet VPS
OpenStory's production target is Cloudflare Workers. The VPS path is a dev replica of bun dev: Vite + Workerd/Miniflare with local D1 and R2, not a Workers deploy.
URL
https://sh-openstory-dev.gfigroup.io
Sign-in is the admin email + password from the service env (ADMIN_EMAILS, ADMIN_PASSWORD).
One-time owner registration
On the VPS, as ggcloud:
gfi-run app create openstory \
--repo-dir /home/ggcloud/repos/openstory \
--dockerfile Dockerfile
gfi-run service create openstory-dev \
--app openstory \
--type http \
--port 3000 \
--health-path /healthz \
--public-write \
--env-file /home/ggcloud/data/apps-env/openstory-dev/testnet.env \
--data-mount wrangler-state:/app/.wrangler:rw--public-write is required because login and generation are POST. The bind mount keeps Miniflare D1/R2 across recreates.
gfi-run drops all container capabilities, so root inside the container cannot write a 0700 host mount owned by ggcloud. After service create, make the Miniflare dir world-writable once:
chmod 0777 /home/ggcloud/data/apps-data/openstory-dev/wrangler-stateEnv
Copy .env.local to /home/ggcloud/data/apps-env/openstory-dev/testnet.env (mode 0600). Set:
VITE_APP_URL=https://sh-openstory-dev.gfigroup.io
VITE_ALLOWED_HOSTS=all
CLOUDFLARE_INCLUDE_PROCESS_ENV=true
CREDITS_UNLIMITED=trueDo not bake secrets into the image. gfi-run push / deploy refuse .env.local in the source tree.
Deploy from a laptop
# source directory must not contain .env / .env.local
./scripts/gfi-run --target [email protected] \
push openstory-dev /path/to/openstoryOr rsync to /home/ggcloud/repos/openstory and run gfi-run deploy openstory-dev /home/ggcloud/repos/openstory on the VPS.
Verify
gfi-run status openstory-dev
curl -fsS https://sh-openstory-dev.gfigroup.io/healthz