People say “deploy the Shopify app” as if it were a single binary. In practice a modern Remix Shopify app is a bundle of release channels:

  • the Node/Remix server (Docker/ECS/Lightsail/PM2)
  • UI extensions (Admin, Checkout, POS)
  • theme app extensions
  • Shopify Functions (WASM)
  • Prisma migrations
  • app TOML / Partner Dashboard configuration
  • sometimes separate Lambdas the app depends on

I have shipped this shape across many merchant environments with buildspecs, Dockerfiles, Terraform pipelines, and Shopify CLI deploys. The complexity is coordinating channels that do not share one atomic commit in production.

Different channels, different failure modes

A server deploy can succeed while an extension version is stale. A Function can be updated while the UI still writes old cart attributes. A migration can run before the new code is live, or after.

This is why “green build” is not “green merchant experience.”

Environment matrix explosion

Dev stores, staging shops, production shops, multiple TOML files per engineer/client environment. This multiplies. Without naming conventions and automation, humans mis-deploy to the wrong shop. That error is uniquely painful because it can look like success in CI.

Treat shop identity as a first-class config with guardrails.

Extension deploys are real deploys

shopify app deploy (and related flows) publishes extension versions merchants run. Swapping .dev constants, injecting API URLs, and restoring files (as some deploy scripts do) exists because Shopify app packaging is picky. Those scripts are load-bearing. Treat them like release engineering, with debug artifacts and rollback notes.

Databases and app servers must negotiate

Prisma migrations in a blue-green or ECS rollout need the same expand/contract care as any other app. Shopify apps often store sessions and merchant config, corrupt that and every extension that depends on offline tokens fails together.

Infrastructure pipelines are part of the app

CodePipeline/CodeBuild to ECR to ECS, or webhook-driven blue-green on a VM, or Terraform applying service definitions. These are not “ops later.” If the Remix app cannot be redeployed safely, your extension velocity does not matter.

A release checklist I actually use

  1. Which channels changed in this release?
  2. Are contracts between channels compatible (attributes, Function inputs, API routes)?
  3. Migration safety for currently running servers?
  4. Who deploys extensions vs servers, and in what order?
  5. How do we verify on a real shop (not only CI)?
  6. What is the rollback per channel?

Shopify app delivery is multi-channel release management. Once you see it that way, the tooling choices get clearer, and the outages get rarer.

← Back to blog