Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions docs/docs/deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Deployment

Deployment is the core workflow of Miren — it takes your application code, builds a container image, and runs it on your server.

## How Deployment Works

When you run `miren deploy`, Miren:

1. **Uploads your files** — sends your source code to the server (after your first deploy, only changed files are transferred)
2. **Detects and builds on the server** — the server inspects your source code to detect the [language, framework](/languages), and [services](/services), then builds a container image using the detected stack (or your Dockerfile)
3. **Activates the new version** — rolls out the new version, replacing the previous one

Every deployment is tracked with a unique version ID, its current status, and the git commit it came from. You can inspect, roll back, or redeploy any previous version at any time.

## Deploying from a Project Directory

The most common workflow — run `miren deploy` from the root of your project:

```bash
cd ~/myapp
miren deploy
```

You can also deploy from a different directory with `-d`:

```bash
miren deploy -d path/to/app
```

Miren reads the app name from `.miren/app.toml`. If you haven't set up your project yet, Miren offers to run `miren init` for you, which creates an `app.toml` with the app name derived from your directory name. If this is the first deploy of the app, Miren creates it automatically on the server.

### Confirmation Prompt

If your cluster config includes multiple clusters, Miren asks you to confirm which cluster to deploy to. Skip the prompt with `--force`:

```bash
miren deploy --force
```

The prompt is also skipped automatically when only one cluster is configured or when stdin is not a terminal (e.g., in CI).

## Build Detection

Miren automatically detects how to build your application. It inspects your project files and identifies the language, framework, package manager, and entry points. See [Languages](/languages) for details on supported stacks.

Use `--analyze` to see what Miren detects without actually building or deploying:

```bash
miren deploy --analyze
```

You'll see the detected stack, services, entrypoint, and what files and frameworks influenced the result. Handy when a build isn't doing what you expect.

If a build fails, Miren displays the build errors and the deployment is marked as failed in history (visible via `miren app history`).

Use `--explain` (or `-x`) to watch each build step as it runs. This is the default in non-interactive environments; in interactive terminals, Miren shows a compact progress UI instead.

## Deploy-Time Environment Variables

Set environment variables at deploy time with `-e` and `-s`. They're applied to the app before the new version activates.

```bash
# Regular variables
miren deploy -e RELEASE_SHA=abc123 -e LOG_LEVEL=debug

# Sensitive variables (masked in output)
miren deploy -s DATABASE_URL=postgres://user:pass@host/db

# Read value from a file
miren deploy -s API_KEY=@secrets/api-key.txt

# Prompt for the value (sensitive vars mask input)
miren deploy -s SECRET_KEY
```

## Redeploying an Existing Version

Skip the build entirely and redeploy a previously built version:

```bash
miren deploy --version myapp-vCVkjR6u7744AsMebwMjGU
```

Useful for rolling forward to a known-good version without waiting for a new build.

Find version IDs with `miren app history` (see [Deployment History](#deployment-history) below).

## Rollback

`miren rollback` provides an interactive way to revert to a previous version:

```bash
miren rollback -a myapp
```

This presents a picker showing your recent successful deployments:

| Column | Description |
|--------|-------------|
| VERSION | The version ID |
| STATUS | Deployment status (active, succeeded) |
| WHEN | Relative timestamp |
| GIT SHA | Short commit hash |
| BRANCH | Git branch at the time of deploy |

Select a version and Miren redeploys it immediately. The currently active version is excluded from the list since rolling back to the current version would be a no-op.

Rollback creates a new deployment record — it doesn't erase history.

## Deployment History

View the history of deployments for an app:

```bash
miren app history -a myapp
```

### Output

```text
STATUS VERSION WHEN DEPLOYED BY
✓ myapp-vCVkjR6u7744AsMebwMjGU 2m ago paul@miren.dev
✓ myapp-vCVkjJSe4fydvxEHfhsKfA 1h ago paul@miren.dev
✗ myapp-vCVmuoeQCzjoNN9hGsu14c 3h ago paul@miren.dev
↩ myapp-vCVkjTGJhRddyZDVq9CmnN 1d ago paul@miren.dev
```

Status icons:
- **✓** — active (currently running) or succeeded
- **✗** — failed
- **↩** — rolled back
- **⟳** — in progress
- **⊘** — cancelled

Comment on lines +128 to +134
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify which status values are actually accepted by `miren app history --status`
# Expected: find enum/validation/help text that defines canonical allowed values.
rg -nP -C3 --glob '!docs/**' -- '--status|rolled_back|succeeded|in_progress|cancelled|active|failed'

Repository: mirendev/runtime

Length of output: 50374


🏁 Script executed:

cd docs/docs && cat -n deployment.md | sed -n '125,145p'

Repository: mirendev/runtime

Length of output: 890


🏁 Script executed:

# Search for the CLI implementation of the status filter in the app history command
# Look for status enum/validation definitions
rg -n 'app.*history|history.*status' --glob '!docs/**' -t go | head -20

Repository: mirendev/runtime

Length of output: 717


🏁 Script executed:

# Search more broadly for status-related constants or enums
rg -n 'active|rolled_back|in_progress|succeeded' --glob '!docs/**' -t go | grep -i 'const\|enum\|status' | head -30

Repository: mirendev/runtime

Length of output: 2701


🏁 Script executed:

# Find the AppHistory command implementation
rg -n 'AppHistory|func.*History' cli/commands/app_*.go -A 20 | head -50

Repository: mirendev/runtime

Length of output: 3659


🏁 Script executed:

# Look for status validation or filter implementation in the app history command
find cli -name '*.go' -exec grep -l 'app.*history\|history.*status' {} \;

Repository: mirendev/runtime

Length of output: 142


🏁 Script executed:

# Check the app_status.go file more thoroughly for status filter handling
cat -n cli/commands/app_status.go | head -100

Repository: mirendev/runtime

Length of output: 3948


🏁 Script executed:

# Search for deployment status enum/constants
find . -name '*.go' -path '*/deployment*' ! -path './docs/**' | xargs grep -l 'status.*active\|status.*failed\|rolled_back' | head -10

Repository: mirendev/runtime

Length of output: 126


🏁 Script executed:

# Look for deployment status type definitions
rg -n 'type.*Status|const.*Status' --glob '!docs/**' -t go | grep -i deploy | head -20

Repository: mirendev/runtime

Length of output: 1000


🏁 Script executed:

# Check proto definitions for deployment status
find . -name '*.proto' | xargs grep -l 'deployment\|status' 2>/dev/null | head -5

Repository: mirendev/runtime

Length of output: 42


🏁 Script executed:

# Check the deployment server for status handling and validation
rg -n 'active|failed|rolled_back|succeeded|in_progress|cancelled' servers/deployment/server.go -C 2 | head -80

Repository: mirendev/runtime

Length of output: 2891


🏁 Script executed:

# Look at the test file to see which statuses are tested
rg -n '"active"|"failed"|"rolled_back"|"succeeded"|"in_progress"|"cancelled"' servers/deployment/server_test.go | head -30

Repository: mirendev/runtime

Length of output: 1528


🏁 Script executed:

# Search for status string literals in deployment code more carefully
rg -n 'Status.*=.*"' servers/deployment/ --glob '*.go' | grep -E '(active|failed|succeeded|rolled_back|in_progress|cancelled)'

Repository: mirendev/runtime

Length of output: 1823


🏁 Script executed:

# Check how status filter is used in ListDeployments
rg -n 'ListDeployments|listDeploymentsInternal' servers/deployment/server.go -A 10 | head -60

Repository: mirendev/runtime

Length of output: 2096


🏁 Script executed:

# Look for where the status filter parameter is validated or used
rg -n 'args\.Status|status filter' servers/deployment/server.go -B 2 -A 5

Repository: mirendev/runtime

Length of output: 645


🏁 Script executed:

# Check if the CLI does any validation on the status flag before sending to server
rg -n 'opts\.Status|status.*validation\|status.*check' cli/commands/app_history.go -B 3 -A 5

Repository: mirendev/runtime

Length of output: 580


Status filter documentation is incomplete and may mislead users.

The legend (lines 128-133) lists six status values: active, succeeded, failed, rolled_back, in progress, and cancelled. However, the filter documentation (line 141) describes only three: active, failed, rolled_back. The server accepts all six values (verified in servers/deployment/server.go validation). Update the filter description to either list all six supported values or explicitly document that only a subset is intentionally exposed.

Also applies to: 141-143

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/docs/deployment.md` around lines 128 - 134, The status filter docs are
inconsistent with the server validation (servers/deployment/server.go) which
accepts six values; update the filter description near the "Status filter"
section (around the current three-value list) to either enumerate all six
supported statuses with their icons — active (✓), succeeded (✓), failed (✗),
rolled_back (↩), in progress (⟳), cancelled (⊘) — or explicitly state that only
a subset is exposed and which ones; ensure the language matches the legend above
and mentions the exact status tokens (active, succeeded, failed, rolled_back, in
progress, cancelled) so the docs align with the server validation.

You can filter by status, show full git provenance with `--detailed`, or get JSON output for scripting. See the [`miren app history` reference](/command/app-history) for all options.

## Cancelling a Deployment

Cancel an in-progress deployment by its deployment ID:

```bash
miren deploy cancel -d <deployment-id>
```

Get the deployment ID from `miren app history --detailed`. If a CLI session is watching that deployment, it'll detect the cancellation and exit cleanly.

Only one deployment can run per app at a time. If you attempt to deploy while another is in progress, Miren tells you who started it and when. You can wait for it to finish or cancel it and start a new one.

## Git Provenance

Miren automatically captures git metadata (commit, branch, author, dirty state) from your working directory at deploy time. This information appears in `miren app history --detailed` and in the `miren rollback` picker. No configuration is needed — if you deploy from a git repo, provenance is captured automatically.

## Next Steps

- [Build & Language Detection](/languages) — How Miren detects and builds different languages and frameworks
- [App Configuration](/app-configuration) — Configure your app with `.miren/app.toml`
- [Services](/services) — Define multiple processes in your app
- [CI/CD Deployment](/ci-deploy) — Deploy from CI pipelines with OIDC authentication
- [app.toml Reference](/app-toml) — Complete field reference
1 change: 1 addition & 0 deletions docs/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const sidebars: SidebarsConfig = {
label: 'Features',
collapsed: false,
items: [
'deployment',
'app-configuration',
'languages',
'services',
Expand Down
Loading