Skip to content

Environment variables

All secrets and per-env configuration live in .env.local (gitignored). A redacted template lives at .env.example.

Full list

# ─── WordPress / WooCommerce backend ─────────────────────────────────────
WP_BASE_URL=https://fruitplug.co.uk
WP_STORE_API_URL=https://fruitplug.co.uk/wp-json/wc/store/v1
WP_REST_URL=https://fruitplug.co.uk/wp-json
# Woo REST v3 consumer creds — wp-admin → Woo → Advanced → REST API
WC_CONSUMER_KEY=
WC_CONSUMER_SECRET=
# fruitplug-api shared secret (for our custom endpoints)
FRUITPLUG_API_SECRET=

# ─── Stripe (WooPayments wraps this; direct Stripe needed for Billing) ───
STRIPE_PUBLISHABLE_KEY=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=

# ─── Instagram Graph (nightly reel sync) ─────────────────────────────────
IG_USER_ID=37748600858
IG_LONG_LIVED_TOKEN=

# ─── Auth ────────────────────────────────────────────────────────────────
JWT_SECRET=change-me-to-random-32-bytes
NEXTAUTH_SECRET=change-me-to-random-32-bytes
NEXTAUTH_URL=http://localhost:3000

# ─── Analytics ───────────────────────────────────────────────────────────
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=https://eu.posthog.com
NEXT_PUBLIC_GA_ID=

# ─── Images / CDN ────────────────────────────────────────────────────────
CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=

# ─── Push notifications (Phase 2) ────────────────────────────────────────
VAPID_PUBLIC_KEY=
VAPID_PRIVATE_KEY=
VAPID_SUBJECT=mailto:info@fruitplug.co.uk

# ─── Observability ───────────────────────────────────────────────────────
SENTRY_DSN=
SENTRY_AUTH_TOKEN=

# ─── Runtime ─────────────────────────────────────────────────────────────
NODE_ENV=development
PORT=3000
HOSTNAME=0.0.0.0

Which of these are required today?

Variable Required for Set?
WP_STORE_API_URL Every shop/cart/PDP page ✅ production URL works
WP_REST_URL fruitplug-api calls (loyalty/box/push)
WC_CONSUMER_KEY / SECRET Server-side Woo REST v3 (order history, admin calls) ⏳ pending — generate in wp-admin
STRIPE_* Checkout ⏳ pending — need test keys
IG_LONG_LIVED_TOKEN Nightly reel auto-sync ⏳ Phase 2
JWT_SECRET / NEXTAUTH_SECRET Auth flow ⏳ needed when /account lands
VAPID_* Push notifications ⏳ Phase 2

Local dev vs staging

  • Local dev (pnpm dev): reads .env.local
  • Staging server (this host, container fruitplug-web-dev): env passed to docker run via -e flags. See infra/dev.Dockerfile for defaults and current Caddy config for the active values.

Secrets handling

  • .env.local is gitignored.
  • The A2 SSH key lives at ~/.ssh/fruitplug_a2 (outside the repo) with chmod 600.
  • The A2 key passphrase is passed via A2_PASSPHRASE env var to the infra/a2/ scripts; never committed.
  • GHCR container images pull with GITHUB_TOKEN in CI (not yet wired — see CI/CD).
  • Stripe/IG/VAPID keys will live in GitHub Secrets once CI is wired; on the server they'll be in /etc/fruitplug/web.env (0600 root-owned).

Generating strong defaults

# JWT / NextAuth secret
openssl rand -hex 32

# VAPID pair
npx web-push generate-vapid-keys