On this page

Publish is the moment a mutable sandbox becomes a frozen, reproducible artifact ready to serve production traffic.

The pipeline

  1. Sandbox /workspace (mutable; agent or developer is editing here)
  2. Source snapshot (tarball, sha256-keyed, stored in object storage)
  3. Builder VM (Firecracker microVM booted from miosa-builder image)
  4. Build (Dockerfile / Railpack / buildpack / static packager)
  5. Release (static tarball or dynamic rootfs/OCI image, sha256-keyed)
  6. Deployment Version (database row pointing at the release)
  7. Health check (for dynamic; static skips this)
  8. Promotion (Deployment.active_version_id updated)

The sequence below shows who acts at each step:

```mermaid
sequenceDiagram
    participant YC as Your Code
    participant M as MIOSA

    YC->>M: POST /deployments/:id/publish
    M-->>YC: 202 Accepted (build in progress)
    M->>M: freeze /workspace → source snapshot
    M->>M: boot builder VM
    M->>M: compile + package → release artifact
    M->>M: create Deployment Version row
    M->>M: health check (dynamic only)
    M->>M: promote — Deployment.active_version_id updated
    M-->>YC: version.state = ready, public_url live

You call one endpoint. MIOSA does all of this internally and returns the result when the version is ready.

The publish call

Response shape:

{
  "data": {
    "deployment": {
      "id": "dep_...",
      "active_version_id": "ver_...",
      "state": "running",
      "public_url": "https://smile-dental.workspace.miosa.app"
    },
    "version": {
      "id": "ver_...",
      "kind": "static",
      "state": "ready",
      "artifact_uri": "s3://...",
      "artifact_sha256": "...",
      "source_sha256": "..."
    },
    "services": [
      { "id": "svc_...", "type": "static_web", "state": "healthy" }
    ],
    "promoted": true
  }
}

Source snapshots

Before the builder runs, MIOSA freezes a snapshot of the sandbox’s source. The snapshot is a tarball of /workspace (or whatever output_path you specify), excluding cache directories that don’t need to ship:


included:    application code, package manifests, lockfiles, public assets, config
excluded:    node_modules, .next/cache, dist (will be rebuilt), .git (unless needed),
             __pycache__, build/, target/

The snapshot tarball is uploaded to object storage and sha256-keyed. The version record stores source_sha256 so retries can rebuild from the exact same input without re-snapshotting.

The sandbox keeps running while the build runs. You can keep editing.

Build modes

MIOSA picks a build mode from the source. You can override with build_command if needed.

ModeTriggerWhat happens
DockerfileDockerfile exists in output_pathBuildKit (buildctl) builds the image inside the builder VM
Railpack-style auto-detectpackage.json / requirements.txt / pyproject.toml / go.mod / mix.exsMIOSA detector picks the right install + build commands
Static packagerOnly static files in output (no server entrypoint detected)Files are tarballed and uploaded as a static release
ExplicitbuildCommand and/or runCommand providedMIOSA runs those, then packages whatever’s in output_path

What gets promoted, and when

Static publishes promote as soon as the artifact is uploaded — there’s nothing to health-check.

Dynamic publishes don’t promote until:

  1. The build succeeded.
  2. The release rootfs / OCI image was uploaded.
  3. New Runtime Instances were scheduled on compute hosts.
  4. Health checks (GET healthCheckPath) returned 2xx for the configured grace period (default 30s healthy before promotion).

If health checks fail, the previous version stays live and the new version is marked failed. No traffic is sent to the broken release. Your last known good production keeps serving.

Idempotency

Pass Idempotency-Key on every publish. If the same key is sent twice within the retention window, MIOSA returns the original result without re-building. This makes retries safe — useful for shaky network connections and worker queues.

Failure modes

FailureWhat happensRecovery
Build command exits non-zeroVersion marked failed, log uploaded, production unchangedFix in sandbox, publish again
Health check never passesVersion marked failed, runtime instances torn downFix run command or healthCheckPath, publish again
Source snapshot failsPublish returns 5xx immediately, no version row createdRetry the request
Static build exceeds artifact size limitVersion marked failedReduce assets or contact support to raise limit
Two publishes race for the same deploymentSecond one waits on the advisory lock; both eventually succeed in orderNone — handled by Engine.OperationLocks

See also

Was this helpful?