Skip to content

Getting started

Deployment checklist

Use this checklist before delivering a buyer installation or publishing a production deployment.

Backend production checklist

  • Set APP_ENV=prod.
  • Set a unique secure APP_SECRET.
  • Configure production DATABASE_URL, or use the browser installer at /install.
  • Generate production JWT keys, or let the browser installer create missing keys.
  • Configure JWT_PASSPHRASE.
  • Configure mail delivery in admin Notification Settings.
  • Configure Stripe live or test keys in admin Payment Settings.
  • Configure the Stripe webhook secret in admin Payment Settings.
  • Configure Google Maps key.
  • Configure Pusher credentials.
  • Configure storage driver and credentials.
  • New database: php bin/console app:database:install (or the browser installer). Existing database: run the migrations, or use the update page.
  • Build production frontend assets.
  • Clear and warm Symfony cache.
  • Create the first admin user, or use the browser installer.
  • Point the web server document root to public/.
  • Confirm HTTPS works.
  • Confirm upload directories are writable.
  • Confirm logs are writable.
  • Confirm admin login works.
  • Confirm mobile login works.
  • Confirm a test order can be created.
  • Confirm a test payment can be completed.
  • Confirm Stripe webhook events are received.
  • Optional: set SENTRY_DSN in .env.local for error reports, and point an uptime monitor at /api/v1/health.
composer install --no-dev --optimize-autoloader
npm ci
npm run build
php bin/console app:database:install --if-empty
php bin/console doctrine:migrations:migrate --no-interaction
php bin/console cache:clear --env=prod
php bin/console cache:warmup --env=prod

Create an admin user if one does not exist:

php bin/console app:admin:create-user admin@example.com strong-password

Caching and performance

  • Settings are read in one query and kept for 5 minutes in the app cache (var/cache); saving a setting in the admin applies at once. If you change settings directly in the database, run php bin/console cache:pool:clear cache.app.
  • The app cache is on disk, which is right for one server. When several servers run the same instance, point it at Redis so they share it (also needed for rate limits): in config/packages/cache.yaml set app: cache.adapter.redis and default_redis_provider: '%env(REDIS_URL)%', set REDIS_URL, and add the redis PHP extension.
  • Catalog API responses (stores, menus, home, categories, search) carry Cache-Control: private, max-age=15 and an ETag: the apps keep them for 15 seconds, then ask again and get 304 Not Modified when nothing changed. Don't let a shared proxy or CDN cache /api.
  • A store's menu costs the same few database queries whatever its size (about 120 ms for 500 products in prod mode on a laptop).

Mobile release checklist

  • Create the client's brand with npm run brand:new (name, bundle ID / package, URL scheme, API URL, support email), see New client instance. The Apple Pay merchant ID is derived from the bundle ID.
  • Replace the icon (1024×1024) and set the colours and splash in brands/<slug>/brand.json; set the EAS project ID.
  • Set EXPO_PUBLIC_STRIPE_PUBLISHABLE_KEY, EXPO_PUBLIC_GOOGLE_MAPS_API_KEY, EXPO_PUBLIC_GOOGLE_MAPS_API_KEY_ANDROID, EXPO_PUBLIC_PUSHER_KEY and EXPO_PUBLIC_PUSHER_CLUSTER.
  • Optional: add the client's Sentry project (crash reports) and Firebase config files (analytics, with user consent) to the brand.
  • Run npm run brand:apply -- <slug> before building.
  • Test login and refresh token flow.
  • Test location permissions.
  • Test checkout.
  • Test Apple Pay on a real iOS device if enabled.
  • Test Google Pay on a real Android device if enabled.
  • Build release binaries with EAS or the buyer's preferred build process. Later JavaScript-only fixes can ship with eas update.
  • Fill in the legal details in Settings → General (legal name, registered address, tax ID, registration number, support email). They are printed in the legal pages.
  • Review the terms, privacy policy, courier terms and store terms in Legal documents with a lawyer. Until you publish your own, built-in English templates are shown at /legal/terms, /legal/privacy, /legal/rider-terms and /legal/vendor-terms.
  • App Store Connect and Google Play Console: use https://your-domain/legal/privacy as the privacy policy URL.
  • Google Play Console → Data deletion: use https://your-domain/account/delete as the account deletion URL. In-app deletion is in Settings → Delete account (Apple guideline 5.1.1(v)).
  • Schedule app:account:process-deletions daily (see Scheduled jobs).

Security checklist

  • Do not commit .env.local.
  • Do not commit private JWT keys.
  • Do not commit Stripe secret keys. Store backend Stripe credentials in admin Payment Settings.
  • Do not commit Pusher secrets.
  • Use HTTPS everywhere in production.
  • Restrict Google Maps keys.
  • Restrict Stripe webhook events to the events you need.
  • Use strong admin passwords.
  • Remove demo data from production.
  • Review roles before assigning admin access.

Found a mistake? Tell us.