Altien turns Mike into one tenant-portable image

One packaged build now runs the whole app and can serve any client without a rebuild.

infrastructuremulti-tenant

Maintained by Allen Morgan · verified on MikeWatch

Altien collapsed Mike's separate front-end and back-end builds into a single image that runs both together. The more interesting change is what's no longer locked in when the image is built. A client's identity and sign-in settings - the kind tied to Microsoft Entra, Microsoft's corporate login service - used to get baked into the front-end at build time, which meant a fresh build for every customer.

Now those settings are fetched when the app loads in the browser, so the same image can serve any tenant. Only one value still has to be set at build time. The work also trims what gets shipped to Azure's build service and adds a small fix so the open-source version installs cleanly without Altien's private provisioning scripts.

So what Anyone deploying Mike across multiple clients or environments: one image now covers all of them, with no per-customer rebuild.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

2 commits from Altien/mikeOssAzure, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
d829a171 feat(build): bundled multistage Dockerfile + static export config Allen Morgan 2026-05-08 ↗ GitHub
commit body
Single image for the application: Next.js builds the frontend as a
static export and the Dockerfile copies the resulting /out tree into
the backend image's /app/public.  The Express server picks it up at
runtime when the directory is present (see the static-frontend block in
backend/src/index.ts).

  * Dockerfile                   - three stages:
      backend-deps  : install + tsc + tree-shake the backend
      frontend-deps : install + next build with NEXT_PUBLIC_API_BASE_URL
                      passed in via --build-arg so the same image source
                      can target same-origin or split-origin deployments
      runtime       : node:lts-alpine + libreoffice (for docx convert)
                      with the built backend, prod node_modules, and
                      the frontend export.

  * .dockerignore                - excludes backend test fixtures,
                                   migrations directory artefacts, the
                                   frontend's .next/ debug output, and
                                   anything under .claude/.

  * frontend/next.config.ts       - output: "export" so the frontend
                                   produces a static SPA bundle that
                                   the backend can serve out of a
                                   single Express process.

  * frontend/.env.local.example   - documents the new minimal env
                                   surface: only NEXT_PUBLIC_API_BASE_URL
                                   plus the optional supabase-mode pair.

  * frontend/package.json + lockfile - bumps the dep set to match the
                                   updated context + lazy-supabase
                                   shape; resend dropped (unused).
feec6d3e fix(build): add scripts/install/README.md placeholder Allen Morgan 2026-05-08 ↗ GitHub
commit body
The runtime stage of the Dockerfile unconditionally COPYs
scripts/install, but that directory was not present in the OSS
fork, so `az acr build` (and any plain `docker build`) failed at
"COPY failed: file not found in build context" before runtime
was reached.

The application code in backend/src/routes/install.ts already
expects this directory may be empty or absent when the OSS image
is built without the marketplace deploy bundle. The runtime route
checks fs.existsSync and degrades cleanly. The Dockerfile was the
mismatch.

This commit ships an empty-by-design placeholder README so the
COPY succeeds. Downstreams that bundle their own operator scripts
drop them alongside this README without Dockerfile changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-199.md from inside the repo you want the changes in.

⬇ Download capture-thread-199.md