Skip to content

Deploy to production

Production deployments should build the app, apply committed migrations, then run the web server and at least one worker.

Terminal window
pnpm run build

The build creates:

  • Directorydist/
    • Directoryui/
    • Directoryopenshop/
      • Directoryserver/

Single-app deployments usually need:

Terminal window
DATABASE_URL=postgresql://...
SHOPIFY_API_KEY=...
SHOPIFY_API_SECRET=...
HOST=https://your-app.example.com
ENCRYPTION_KEY=<64 hex characters>

Generate an encryption key:

Terminal window
openssl rand -hex 32

ENCRYPTION_KEY protects provider credentials and Shopify access tokens. Treat it as required in production.

Generate and review migrations in development or CI:

Terminal window
pnpm exec openshop migrate generate
pnpm exec openshop migrate check

Commit the generated SQL in ./drizzle, then apply committed migrations before starting production processes:

Terminal window
pnpm exec openshop migrate

openshop migrate only applies SQL from ./drizzle. It does not run generation tooling.

Run the web server and worker separately:

Terminal window
pnpm exec openshop start
pnpm exec openshop worker --concurrency=5

openshop start serves HTTP traffic and dispatches cron runs. It does not execute queued flow runs. At least one worker must be running for queued runs to complete.

  • The web process starts without migration errors.
  • The worker process starts and reports no database connectivity errors.
  • The embedded admin UI loads inside Shopify.
  • A test flow run moves from queued to completed or failed with logs.

OpenShop does not apply migrations on boot. If a deploy fails before migrations are applied, roll back the app process only. If committed SQL was already applied, use your normal database rollback or forward-fix process.