Deploying Shopify apps is different from standard websites because of Webhooks, Admin API Rate Limits, and OAuth handshakes.
1. The "Vercel Problem" (Timeouts)
Vercel Serverless functions have a timeout (usually 10s-60s).
- Issue: Shopify bulk operations, product syncs, or installing the app on a large store can take >60s.
- Result:
504 Gateway Timeoutand broken installs.
Solution A: Remix on Vercel (Hybrid)
- Use Vercel for the UI.
- Offload long tasks (syncing) to a separate worker (Cloudflare Workers, Inngest, or separate VPS).
- Use
Deferin Remix to stream UI while backend works (but doesn't fix hard timeouts for the main thread).
Solution B: VPS / Docker (Recommended for Serious Apps)
Deploying to a persistent server (Fly.io, Railway, DigitalOcean, Hetzner) eliminates timeouts.
- Tooling: Coolify (self-hosted Vercel alternative), Dokku, or manual Docker.
2. Deployment Checklist
A. Environment Variables
Ensure these are set in your CI/CD or platform secrets:
SHOPIFY_API_KEYSHOPIFY_API_SECRETSCOPES(must match exactly what's in code)SHOPIFY_APP_URL(The public HTTPS URL, e.g.,https://app.mytitle.com)DATABASE_URL
B. Database Migrations
Run migrations during the build or as a release phase command.
- Fly.io: Use
release_commandinfly.toml. - Docker: Can run
npx prisma migrate deployin theCMDscript before starting the app.
C. Build Command
Ensure you build for production:
npm run build
# Ensure this runs `remix build` and copies necessary public assets
3. Platform Specifics
Fly.io
Excellent for Shopify apps due to global regions and Docker support.
fly.toml example:
[build]
dockerfile = "Dockerfile"
[env]
PORT = "3000"
[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = true
auto_start_machines = true
Coolify / Hetzner
If you want to save money ($5/mo for a powerful VPS).
- Install Coolify on VPS.
- Connect GitHub Repo.
- Select "Nixpacks" or "Docker file".
- Set Environment Variables.
- Deploy.
4. Background Jobs (Crucial)
You MUST have a strategy for background jobs.
- Options:
- Redis + BullMQ: Requires a persistent Redis instance. (See
redis-bullmqskill). - Inngest / Trigger.dev: Serverless background jobs. Good if you don't want to manage Redis.
- Redis + BullMQ: Requires a persistent Redis instance. (See
5. Post-Deployment Verification
- Install Test: Install the app on a Development Store.
- Webhook Test: Trigger a webhook (e.g., update a product) and check server logs.
- App Proxy: If used, verify the proxy URL loads correctly (CORS errors are common here).