Skip to content

Guides · Shopify · Updated September 29, 2026 · 9 min read

DeploTeka: how I built a platform that runs one Shopify app per store

How I designed and built DeploTeka to run a dedicated Shopify app for every client store. In production, with my own Fixel Pixel fleet of about 100 stores.

In this guide

·

Short answer

DeploTeka is a platform I designed and built for Shopify app vendors who give every client store its own dedicated custom-distribution app. It claims each provisioning run with an idempotency key before touching Shopify, resumes from persisted steps, fences stale workers, keeps secrets out of the browser and never counts an install link as an install. It has run in production as a hosted service since July 2026, with my own product Fixel Pixel as customer zero: a fleet of about 100 Shopify stores.

Key takeaways

  • One app per client store is an operations problem. The hard part is not calling the Shopify CLI; it is knowing whether a run finished, whether it can resume safely and whether the store is really installed.
  • Every run is claimed with an idempotency key before the first Shopify change, executes persisted steps and resumes where it stopped instead of starting a second, conflicting run.
  • Stale workers are fenced by a durable lease with a monotonic generation. An effect the system cannot account for is recorded as unknown, never as success.
  • The tenant is on every key, secrets never reach the browser, install links are treated as secrets, and a store DeploTeka provisions is never marked installed without evidence.
  • Success is measured by the outcome, not the pipeline: activation means the first successful Shopify Admin API call made with the delivered credential.
Concept: separate client applications with a controlled release lifecycle.

Shopify’s custom distribution binds an app to one store, or to one Shopify Plus organization. So a vendor who sells to many independent merchants, and wants each of them on a private, dedicated app, ends up operating one app per store: dozens of them, then hundreds. I designed and built DeploTeka to make that operable. It provisions, releases and hands over a dedicated app for each client store, and at any moment it can say which runs finished, which can safely resume and which stores have real evidence of an install. It runs in production as a hosted service, with my own Shopify measurement product, Fixel Pixel, as customer zero: a fleet of about 100 stores.

The task: why one app per store is hard

DeploTeka is for Shopify app vendors: a technical founder with a Shopify-connected product, or an agency with repeatable app or integration code, serving merchants who have nothing to do with each other. Each merchant gets its own custom-distribution app. Sharing one custom app across unrelated merchants is exactly what the product is built to avoid.

Per store, the work is always the same. Create the app. Select custom distribution. Take custody of the credentials and deliver them to the vendor’s backend. Release the vendor’s version. Send the merchant an install link, wait for approval, then find out whether the right store really ended up with the right installation and version. Done by hand, it is the same checklist for every client, and every step can fail in its own way. At a hundred stores the bottleneck is no longer the product. It is operations.

The obvious answer is a script that loops over the stores and calls the Shopify CLI. It fails on three questions:

  • Did the run finish? Provisioning is a chain: create the app, select custom distribution, read back the credentials, apply branding, deploy the template, create the signed store-specific install agreement. A script that dies at step four leaves a half-built app behind and no record of where it stopped.
  • Is it safe to resume? Starting again from the top after step four is not a retry. It is a second, conflicting run against a live store.
  • Is the store actually installed? The script sees “install link created” and reports success. The merchant has not approved anything yet.

DeploTeka exists to answer those three questions with evidence.

What I built

DeploTeka is a tenant-scoped control plane in four layers: tenant-aware contracts and policies in the domain; orchestration and use cases in the application layer; PostgreSQL persistence, an encrypted vault and the Shopify adapters in infrastructure; Fastify routes and server-rendered views over HTTP. It works through the official Shopify APIs and CLI. The vendor’s code stays the vendor’s: DeploTeka reads the app configuration it needs without cloning, building or running the vendor’s source on its own servers.

Eight pieces carry the weight.

A tenant boundary on every key

Every database key carries the organization it belongs to, and every repository method requires a tenant id. A job id on its own authorizes nothing: knowing the id of someone else’s run does not let you read it or touch it. Isolation lives in the data layer, so a new screen or endpoint cannot forget it.

A secrets boundary at the API

The browser never receives Partner or Dashboard cookies, CSRF tokens, app client secrets, offline access tokens or raw connector responses, and none of them belong in logs or ordinary status payloads. App credentials are sealed in an encrypted vault. Install links are treated as secrets too. In the web app only an owner, admin or operator can reveal one, each reveal writes an audit event, and on the token-delivery path a fresh link is minted on every reveal instead of being stored.

Idempotent, resumable provisioning

A run is claimed durably, with an idempotency key, before the first Shopify mutation. The database holds the organization-plus-key pair unique, so the same request cannot start a second run. The run then executes persisted steps, each with its own status, evidence and audit event. If a step needs action outside DeploTeka (from an operator, the merchant or a deploy tool on the vendor’s own machine), the run pauses on a named manual action and later resumes in the same run and the same idempotency scope. After a crash it continues from its last persisted step. A provider effect whose outcome is unknown stays unknown and is reconciled, never retried blindly.

Versioned releases per store

The app DeploTeka generates for each store is a versioned asset of the vendor’s tenant, built from a template. The control plane deploys it but is not coupled to its code. In the next release, now in review, handoff mode adds a gate: the merchant’s install link is held back until the released version of that store’s app can be read back from Shopify. That gate came from a real run, where a link minted before any version existed was unusable while the run still reported “ready”.

Credential delivery, measured by the outcome

Credentials go from the vault to the vendor’s backend, never through the browser. Every delivery ends as applied, replayed or unknown, and unknown is neither a success nor a failure: it is reconciled through the status path. Delivery proves transport, not that the credential works. So in DeploTeka, activation means the first successful Shopify Admin API call made with the delivered credential.

I set that definition after the first live credential delivery, on my own store on 28 August 2026. Every internal signal was green and the delivery had completed, yet the receiving side still could not make a single Admin API call until a person told it which scopes had been granted. A green pipeline was not a solved problem. A working API call is.

Roles that keep secrets away from status

Four roles. Owner: billing, connector credentials, members, destructive actions. Admin: templates, clients, stores, provisioning, and members other than owners. Operator: clients, stores, provisioning, and revealing an install link. Viewer: read-only status and audit history, with no secret-bearing links. A viewer can follow a run from start to finish without ever being able to reveal the link it produced.

A store DeploTeka provisions counts as installed only when Shopify auth has produced a valid offline session for the exact store and app client id, and tenant, store and app ownership agree in the database. The design also requires the app’s required extensions to be read back as ready. In the released version that check is still a placeholder; the next release, now in review, makes it fail closed: without positive proof it answers “unknown”, and the store stays in provisioning instead of showing as installed. A verifier that cannot reach a store also returns “unknown”, with an explicit reason: no false negative, no quiet promotion to installed. A store DeploTeka provisions is never marked installed without evidence.

Fencing for stale workers

Each run is held under a durable lease with an owner, an expiry and a generation number that only ever goes up. When a lease runs out and another worker takes the run over, the old worker is fenced: its generation is stale, so it can no longer advance the run. Every external effect is guarded before and after the call, and an effect that outlives its lease is recorded as unknown, not as success. Scheduling runs through single-writer lanes. The fencing is covered by 99 focused tests, including two workers competing for the same run. It is deliberately not an exactly-once promise: the design makes uncertainty explicit instead of pretending it away.

How it runs today

I run DeploTeka’s live operations myself, with Fixel Pixel, my Shopify measurement product, as the reference integration.

  • July 2026. I migrated Fixel Pixel’s store fleet into DeploTeka’s production service. It now holds about 100 Shopify stores.
  • August 2026. Stale-worker fencing finished, covered by 99 focused tests, followed by single-writer scheduler lanes.
  • 28 August 2026. First live credential delivery, on my own store.
  • 7 and 8 September 2026. Production releases, with a release rehearsed across two stores of my own fleet on 8 September.

Every production release, and every action on a live store or a credential, needs my authorization. The next release, now in review, adds the fail-closed extension check and the install-link gate. It ships once review is complete and I sign it off.

Engineering decisions worth stealing

None of these are specific to Shopify. They apply to any system that runs long, multi-step jobs against APIs you do not control.

  1. Claim before you touch. Write the run and its idempotency key to your own database before the first call to someone else’s API. A unique constraint on tenant plus key turns “did we already start this?” into a database guarantee.
  2. Persist steps, not just jobs. A job marked “running” tells you nothing after a crash. A run made of persisted steps, each with a status and evidence, tells you where to resume, and lets a person step in on a named action without breaking the chain.
  3. Fence with a generation, not a timeout. Leases expire and slow workers wake up. A monotonic generation checked before and after every external effect stops an old worker from overwriting its successor.
  4. Make unknown a first-class state. Networks lose answers. Three outcomes (done, failed, and unknown with a reason) keep a lost answer from being rounded to green or retried into a duplicate. When a check cannot prove something, fail closed to unknown.
  5. Define done by the customer’s outcome. Activation is the first successful Admin API call with the delivered credential, not the last green step in your pipeline. By the same logic, never hand out a link to something that does not exist yet.
  6. Write down what backs each claim. DeploTeka’s product contract tags every statement about its behaviour by evidence: code, test, dated production record, official platform source or accepted decision. That keeps a passing test from being quoted as proof of production.

What’s next

Three pieces come next: positive proof that a store’s required extensions are ready, so that check can answer “yes” instead of “unknown”; a release across the whole fleet, with a per-store record of exactly what shipped where; and bringing the first outside app vendors through the full journey. None has completed it yet.

If you need something similar

DeploTeka is the kind of system I like building: many tenants, a platform you do not control, long multi-step runs, secrets, and a hard requirement to know what actually happened. The same design carries over to provisioning pipelines, integration platforms, back-office automation and any job runner where a half-finished run costs money.

I can build this kind of platform for you, or the piece you are missing: idempotent provisioning, a resumable job runner, a credential-delivery flow or a tenant boundary that holds. See how I approach API integrations and automation, or describe your task on Task for Daniel. If you want to write the brief first, the API integration brief lists what to settle before code, including idempotency keys.

Questions this guide answers

Is DeploTeka running in production?

Yes. It has run as a hosted production service since July 2026, with further production releases on 7 and 8 September 2026. Customer zero is my own product, Fixel Pixel: I migrated Fixel Pixel's fleet of about 100 Shopify stores into it and run the live operations myself. No outside app vendor has completed the full journey yet.

What happens if two workers pick up the same run?

Only the current lease holder can move it forward. Each run is held under a durable lease with a generation number that only goes up; when a lease expires and another worker takes over, the old worker's generation is stale and it is fenced out. Every external effect is checked before and after the call, and an effect that outlives its lease is recorded as unknown and reconciled, not retried blindly. The fencing is covered by 99 focused tests, including two workers competing for the same run. It is deliberately not an exactly-once promise: the design makes uncertainty explicit instead.

What does 'installed' mean in DeploTeka?

That Shopify auth produced a valid offline session for the exact store and app, and that tenant, store and app ownership agree in the database. An install link on its own proves nothing, because the merchant still has to approve. Where a check cannot prove readiness, such as the app's required extensions, the next release answers 'unknown' instead of 'installed'. A store DeploTeka provisions is never marked installed without evidence.

Is DeploTeka related to conversion tracking?

No. DeploTeka provisions, releases and operates Shopify apps; it does not own the vendor's business logic, shopper data or attribution. Fixel Pixel, my Shopify measurement product, is its customer zero and reference integration. They are separate products.

Is this an official Shopify integration?

No. DeploTeka is independent software, not affiliated with or endorsed by Shopify. It uses the official Shopify APIs and CLI. A compatibility adapter outside those official interfaces sits behind a feature flag.

Can you build a platform like this for my product?

Yes. Multi-tenant provisioning, resumable job runners, credential delivery and integration platforms with idempotency and explicit unknowns are exactly the work I take on. Describe the task on Task for Daniel and I will tell you how I would approach it.

Discuss your project — free.

Send one paragraph: the systems involved, what breaks or is missing today, and what “done” would look like. If the task is already clear, I can quote the implementation directly. If we first need to establish the cause or scope, we agree a separate diagnostic engagement.