### Start the runner example Source: https://miren.md/command/runner-start Starts the runner with default settings. ```bash miren runner start ``` -------------------------------- ### Procfile examples for Node.js and Bun start commands Source: https://miren.md/guides/javascript Define explicit start commands for Node.js and Bun apps. Miren runs the package.json start script by default, but a Procfile makes the command explicit. Includes examples for direct scripts, compiled output, Next.js, Elysia, and background workers. ```Procfile # Node — direct web: node server.js # Node — npm script web: npm start # Node — yarn script web: yarn start # Express — compiled output web: node dist/index.js # Next.js web: npm run start # Bun — run TypeScript directly web: bun run src/index.ts # Bun — run JavaScript web: bun run src/index.js # Bun — package.json script web: bun run start # Bun — Elysia web: bun run src/server.ts # Background worker (Node) worker: node worker.js # Background worker (Bun) worker: bun run worker.ts ``` -------------------------------- ### Cold-start trace example Source: https://miren.md/observability Example trace output showing a cold-start request. The `httpingress` span covers the full request lifecycle, `httpingress.lease` shows lease acquisition (cold start), and containerd spans show image pull and task creation. The proxy-to-app span and your app's span appear as children. ```text httpingress [350ms] ├─ httpingress.lease [200ms] (cold start) │ ├─ rpc.call.AcquireLease [195ms] │ │ ├─ containerd...Images/Pull [150ms] │ │ └─ containerd...Tasks/Create [40ms] ├─ [proxy to app] [150ms] │ └─ my-app: GET /api/users [145ms] (your app's span) ``` -------------------------------- ### Bun + PostgreSQL example: app.toml, index.ts, and deploy Source: https://miren.md/addons Deploys a Bun + PostgreSQL app. The app.toml declares the service and addon, index.ts uses the injected DATABASE_URL to create a table and track visits, and miren deploy provisions the addon and starts the app. ```toml name = "my-bun-app" [services.web] command = "bun run index.ts" [addons.miren-postgresql] variant = "shared" ``` ```typescript const sql = new SQL({ url: process.env.DATABASE_URL }); await sql` CREATE TABLE IF NOT EXISTS visits ( id SERIAL PRIMARY KEY, visited_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ) `; const server = Bun.serve({ port: process.env.PORT || 3000, async fetch(req) { await sql`INSERT INTO visits DEFAULT VALUES`; const [{ count }] = await sql`SELECT COUNT(*) as count FROM visits`; return new Response(`Visits: ${count}\n`); }, }); ``` ```miren miren deploy ``` -------------------------------- ### Complete app.toml example Source: https://miren.md/app-configuration Complete app.toml configuration for a Miren application. Defines environment variables, build version, web and worker services, and a Postgres service with a persistent disk. Use as a starting point for a full deployment configuration. ```toml name = "myapp" [[env]] key = "DATABASE_URL" value = "postgres://user:pass@postgres.app.miren:5432/myapp" [[env]] key = "SECRET_KEY" required = true sensitive = true description = "Application secret for session signing" [build] version = "3.12" [services.web] command = "gunicorn app:app --bind 0.0.0.0:8000" port = 8000 [services.web.concurrency] mode = "auto" requests_per_instance = 20 [services.worker] command = "celery -A app worker" [services.worker.concurrency] mode = "fixed" num_instances = 2 [services.postgres] image = "postgres:16" [[services.postgres.env]] key = "PGDATA" value = "/var/lib/postgresql/data/pgdata" [services.postgres.concurrency] mode = "fixed" num_instances = 1 [[services.postgres.disks]] name = "myapp-pgdata" mount_path = "/var/lib/postgresql/data" size_gb = 20 ``` -------------------------------- ### Install Miren Server Source: https://miren.md/getting-started Run as server or with sudo to install the Miren runtime. Registers with miren.cloud and starts the systemd service. ```miren sudo miren server install ``` -------------------------------- ### Install with token for automation Source: https://miren.md/command/runner-install Uses the `--token` flag to provide an enrollment token, enabling non-interactive installation for automation. ```bash miren runner install --token mren_... ``` -------------------------------- ### Install interactively Source: https://miren.md/command/runner-install Runs the installer without flags, prompting for required information interactively. ```bash miren runner install ``` -------------------------------- ### Route a domain to an app Source: https://miren.md/command/route-set Example that routes example.com to the myapp application. ```bash miren route set example.com myapp ``` -------------------------------- ### Dockerfile.miren: install Quicklisp and preload Hunchentoot Source: https://miren.md/guides/commonlisp Dockerfile.miren that uses clfoundation/sbcl:latest, installs curl, installs Quicklisp, preloads Hunchentoot during build, copies the app, exposes port 8080, and runs app.lisp with sbcl. ```dockerfile FROM clfoundation/sbcl:latest RUN apt-get update -y && apt-get install -y curl && rm -rf /var/lib/apt/lists/* \ && curl -sO https://beta.quicklisp.org/quicklisp.lisp \ && sbcl --non-interactive --load quicklisp.lisp \ --eval '(quicklisp-quickstart:install :path "/quicklisp")' \ && sbcl --non-interactive --load /quicklisp/setup.lisp \ --eval '(ql:quickload :hunchentoot)' WORKDIR /app COPY . /app EXPOSE 8080 CMD ["sbcl", "--disable-debugger", "--load", "/app/app.lisp"] ``` -------------------------------- ### Dockerfile.miren for OCaml/Dream build Source: https://miren.md/guides/ocaml Multi-stage Dockerfile for building an OCaml/Dream app. Uses USER root to install system packages because sudo fails in Miren's sandbox, then switches back to USER opam and passes --no-depexts to opam install. The runtime stage installs libev4, libgmp10, libssl3, and ca-certificates, copies the built binary, and sets CMD to start the app. ```dockerfile # ----- Build stage ----- FROM ocaml/opam:debian-12-ocaml-5.2 AS builder # Install system libraries Dream needs. Miren's build sandbox runs without # new privileges, so `sudo` fails here — switch to root instead. USER root RUN apt-get update -y \ && apt-get install -y libev-dev libgmp-dev libssl-dev pkg-config m4 USER opam WORKDIR /app COPY --chown=opam:opam . . # System deps are already installed above, so skip opam's sudo-based depext step. RUN opam install -y --no-depexts dream dune RUN opam exec -- dune build --profile release ./main.exe # ----- Runtime stage ----- FROM debian:12-slim RUN apt-get update -y \ && apt-get install -y libev4 libgmp10 libssl3 ca-certificates \ && apt-get clean && rm -rf /var/lib/apt/lists/* COPY --from=builder /app/_build/default/main.exe /usr/local/bin/app EXPOSE 8080 CMD ["app"] ``` -------------------------------- ### .dockerignore example Source: https://miren.md/guides/static Example .dockerignore file to exclude .git, node_modules, and dist from the Docker build context. ```text .git node_modules dist ``` -------------------------------- ### Example: List all pools Source: https://miren.md/command/sandbox-pool-list Runs the command to list all sandbox pools. ```bash miren sandbox-pool list ``` -------------------------------- ### Back up a specific addon disk (example) Source: https://miren.md/addons Example backup command for a dedicated addon disk. The output shows the generated snapshot filename with a timestamp. ```miren miren disk backup -n pg-pg-myapp-sCZDabc123-data # Output: pg-pg-myapp-sCZDabc123-data-20260324-120000.miren.zst ``` -------------------------------- ### Node.js OpenTelemetry auto-instrumentation setup Source: https://miren.md/observability Set up OpenTelemetry auto-instrumentation for a Node.js app. Install the auto-instrumentations package, configure the OTLP endpoint, service name, and `NODE_OPTIONS` in `.miren/app.toml`. The `--require` flag loads auto-instrumentation before app start, instrumenting HTTP, Express, and other common libraries. ```bash npm install @opentelemetry/auto-instrumentations-node ``` ```toml [[env]] key = "OTEL_EXPORTER_OTLP_ENDPOINT" value = "https://your-otel-collector:4318" [[env]] key = "OTEL_SERVICE_NAME" value = "my-node-app" [[env]] key = "NODE_OPTIONS" value = "--require @opentelemetry/auto-instrumentations-node/register" ``` -------------------------------- ### Example server.toml configuration Source: https://miren.md/server-config A sample configuration file demonstrating settings for server address, ingress, TLS, etcd, and buildkit storage management. ```toml mode = "standalone" [server] address = ":8443" data_path = "/var/lib/miren" http_request_timeout = 60 [ingress] mode = "tls-autoprovision" [tls] acme_email = "admin@example.com" [etcd] start_embedded = true [buildkit] gc_keep_storage = "20GB" gc_keep_duration = "14d" ``` -------------------------------- ### miren app run command examples Source: https://miren.md/command/app-run These examples show how to use the miren app run command. The first opens an interactive shell, the second runs a specific command, the third runs database migrations, the fourth runs a declared task, and the fifth starts a task without attaching a terminal. ```bash miren app run ``` ```bash miren app run -- bin/rails console ``` ```bash miren app run -- bin/rails db:migrate ``` ```bash miren app run --task reindex ``` ```bash miren app run --task reindex --detach ``` -------------------------------- ### Warm-request trace example Source: https://miren.md/observability Example trace output for a warm request where a sandbox is already running. The `httpingress.lease` span shows a cached lease (0.1ms) instead of a cold start, and the proxy-to-app span is the dominant cost. ```text httpingress [15ms] ├─ httpingress.lease [0.1ms] (cached lease) ├─ [proxy to app] [14ms] │ └─ my-app: GET /api/users [12ms] ``` -------------------------------- ### Complete Go example using jsonrpc3 library Source: https://miren.md/admin-interface Complete Go example using the jsonrpc3 library to set up an admin JSON-RPC endpoint. It registers methods with introspection metadata, wraps the handler with bearer-token auth middleware, and mounts it at /.well-known/miren/admin. The code includes sample data and handler implementations for list-users, get-user, and clear-cache. ```go package main "context" "crypto/subtle" "log" "net/http" "os" "strings" "miren.dev/jsonrpc3/go/jsonrpc3" ) func main() { port := os.Getenv("PORT") if port == "" { port = "8080" } adminToken := os.Getenv("ADMIN_TOKEN") if adminToken == "" { log.Println("WARNING: ADMIN_TOKEN not set") } // Create the admin handler with method definitions adminMethods := jsonrpc3.NewMethodMap() // Register admin methods with introspection metadata adminMethods.Register("list-users", listUsers, jsonrpc3.WithDescription("List all users in the system"), jsonrpc3.WithParams(map[string]string{ "limit": "number", "offset": "number", }), jsonrpc3.WithCategory("users"), ) adminMethods.Register("get-user", getUser, jsonrpc3.WithDescription("Get a specific user by ID"), jsonrpc3.WithParams(map[string]string{ "user_id": "string", }), jsonrpc3.WithCategory("users"), ) adminMethods.Register("clear-cache", clearCache, jsonrpc3.WithDescription("Clear the application cache"), jsonrpc3.WithCategory("maintenance"), ) // Create the HTTP handler for JSON-RPC rpcHandler := jsonrpc3.NewHTTPHandler(adminMethods) // Wrap with auth middleware authHandler := authMiddleware(adminToken, rpcHandler) // Mount admin endpoint at well-known path http.Handle("/.well-known/miren/admin", authHandler) log.Printf("Starting server on port %s", port) log.Fatal(http.ListenAndServe(":"+port, nil)) } func authMiddleware(token string, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if token != "" { auth := r.Header.Get("Authorization") if !strings.HasPrefix(auth, "Bearer ") { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } if subtle.ConstantTimeCompare( []byte(strings.TrimPrefix(auth, "Bearer ")), []byte(token), ) != 1 { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } } next.ServeHTTP(w, r) }) } // Sample data var users = map[string]map[string]any{ "user-1": {"id": "user-1", "name": "Alice", "email": "alice@example.com"}, "user-2": {"id": "user-2", "name": "Bob", "email": "bob@example.com"}, } type listUsersParams struct { Limit int `json:"limit"` Offset int `json:"offset"` } func listUsers(ctx context.Context, params jsonrpc3.Params, caller jsonrpc3.Caller) (any, error) { p := listUsersParams{Limit: 10, Offset: 0} if params != nil { _ = params.Decode(&p) } var result []map[string]any for _, user := range users { result = append(result, user) } return map[string]any{ "users": result, "total": len(users), }, nil } type userIDParams struct { UserID string `json:"user_id"` } func getUser(ctx context.Context, params jsonrpc3.Params, caller jsonrpc3.Caller) (any, error) { var p userIDParams if params == nil { return nil, jsonrpc3.NewInvalidParamsError("user_id is required") } if err := params.Decode(&p); err != nil { return nil, jsonrpc3.NewInvalidParamsError("invalid params") } if p.UserID == "" { return nil, jsonrpc3.NewInvalidParamsError("user_id is required") } user, ok := users[p.UserID] if !ok { return nil, jsonrpc3.NewError(-32001, "user not found", nil) } return user, nil } func clearCache(ctx context.Context, params jsonrpc3.Params, caller jsonrpc3.Caller) (any, error) { // Your cache clearing logic here return map[string]any{ "cleared": true, }, nil } ``` -------------------------------- ### miren config info example Source: https://miren.md/command/config-info Displays configuration file locations and format. ```bash miren config info ``` -------------------------------- ### Load a config file Source: https://miren.md/command/config-load Example of loading a specific configuration file using the --input flag. ```bash miren config load --input cluster-config.yaml ``` -------------------------------- ### Example: List runners Source: https://miren.md/command/runner-list Lists all registered runners using default settings. ```bash miren runner list ``` -------------------------------- ### Generate auth config example Source: https://miren.md/command/auth-generate A simple example of running the miren auth generate command to create an authentication configuration file. ```bash miren auth generate ``` -------------------------------- ### Show current cluster example Source: https://miren.md/command/cluster-current Example command to display the currently pinned cluster. ```bash miren cluster current ``` -------------------------------- ### Example output of 'miren auth ci list' Source: https://miren.md/ci-deploy Example output from 'miren auth ci list -a myapp'. Shows two bindings: one for GitHub with conditions on repository, owner, and events, and one for a generic provider with a project path condition. ```text ID PROVIDER ISSUER SUBJECT CONDITIONS abc123 github https://token.actions.githubusercontent.com repository=acme/web-app; repository_owner=acme; event_name=push,workflow_dispatch def456 generic https://gitlab.com project_path:acme/web-* ``` -------------------------------- ### Example --analyze output showing detected sources Source: https://miren.md/deployment Example output from miren deploy --analyze showing the detected source types. Automatic builds name the detected stack, while image deploys show the normalized image reference. The same source appears in miren app status after deployment. ```text Source: python (auto-detected) Source: dockerfile Source: image ghcr.io/example/myapp:latest ``` -------------------------------- ### Install required networking tools Source: https://miren.md/system-requirements Install the necessary iptables and nftables packages using your distribution's package manager. ```bash # Debian/Ubuntu sudo apt install iptables nftables # RHEL/Fedora sudo dnf install iptables nftables ``` -------------------------------- ### Join a runner and install it as a service Source: https://miren.md/distributed-runners Run on the machine being added: join the cluster with the token and install the runner as a service. ```miren miren runner join mren_... miren runner install ``` -------------------------------- ### Dockerfile.miren for Klong with socat Source: https://miren.md/guides/klong Builds the Klong app: installs KlongPy and colorama from PyPI, socat from apt, copies hello.kg, exposes port 8080, and starts the socket front-end with socat. Miren builds from this file instead of guessing the stack. ```dockerfile FROM python:3.12-slim RUN pip install --no-cache-dir klongpy colorama \ && apt-get update -y && apt-get install -y socat && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY hello.kg /app/ EXPOSE 8080 CMD ["sh", "-c", "exec socat TCP-LISTEN:$PORT,reuseaddr,fork EXEC:'kgpy /app/hello.kg'"] ``` -------------------------------- ### Dockerfile.miren for Mojolicious Source: https://miren.md/guides/perl Dockerfile.miren for a Mojolicious app. Installs Mojolicious with cpanm, copies the app, and starts it with the daemon command listening on $PORT. For a cpanfile, use RUN cpanm --notest --installdeps . instead. ```dockerfile FROM perl:5.40 WORKDIR /app RUN cpanm --notest Mojolicious COPY . /app EXPOSE 8080 CMD ["sh", "-c", "exec perl /app/app.pl daemon -l \"http://*:$PORT\""] ``` -------------------------------- ### Scale a pool to 3 instances Source: https://miren.md/command/sandbox-pool-set-desired Example shows how to set the desired count to 3 for the pool named web. ```bash miren sandbox-pool set-desired web 3 ``` -------------------------------- ### miren server container install command syntax Source: https://miren.md/command/server-container-install Shows the command syntax for installing the miren server in a container. Use this to see the available flags and global options. ```bash miren server container install [flags] ``` -------------------------------- ### miren runner start usage Source: https://miren.md/command/runner-start Shows the basic command syntax for miren runner start. ```bash miren runner start [flags] ``` -------------------------------- ### Take a route down with an explanation Source: https://miren.md/command/route-down Example command that takes a route down with a reason shown to visitors. ```bash miren route down example.com --reason "Upgrading the database" ``` -------------------------------- ### miren runner install usage Source: https://miren.md/command/runner-install Shows the basic command syntax for `miren runner install`. ```bash miren runner install [flags] ``` -------------------------------- ### miren logs examples Source: https://miren.md/command/logs Common examples: view logs, follow logs, and show last 5 minutes filtered for errors. ```bash miren logs ``` ```bash miren logs -f ``` ```bash miren logs --last 5m -g error ``` -------------------------------- ### miren server install command syntax Source: https://miren.md/command/server-install Shows the base command syntax for installing the miren server as a systemd service. Use this form to see available flags and options. ```bash miren server install [flags] ``` -------------------------------- ### Check config files example Source: https://miren.md/command/doctor-config Runs the doctor config command to check configuration files. ```bash miren doctor config ``` -------------------------------- ### Get a variable value Source: https://miren.md/command/env-get Example command to get the value of the DATABASE_URL environment variable. ```bash miren env get DATABASE_URL ``` -------------------------------- ### Dockerfile.miren for Raku with Cro Source: https://miren.md/guides/raku Dockerfile.miren for a Raku app. Uses rakudo-star:latest, installs libssl-dev before zef install (required for Cro::TLS), installs Cro::HTTP, and starts the app with CMD. ```dockerfile FROM rakudo-star:latest RUN apt-get update -y && apt-get install -y libssl-dev && rm -rf /var/lib/apt/lists/* WORKDIR /app RUN zef install --/test Cro::HTTP COPY . /app EXPOSE 8080 CMD ["raku", "/app/app.raku"] ``` -------------------------------- ### Dockerfile.miren for Laravel/Composer with Composer install Source: https://miren.md/guides/php Use this Dockerfile.miren for Laravel or Composer apps. It installs Composer from a pinned image, adds PHP extensions (pdo_pgsql, pdo_mysql, zip), installs dependencies with composer install, and starts the FrankenPHP server on 0.0.0.0:$PORT. ```dockerfile FROM dunglas/frankenphp:1-php8.3 # Composer from its official pinned image — no piping a remote installer into php COPY --from=composer:2 /usr/bin/composer /usr/bin/composer RUN install-php-extensions pdo_pgsql pdo_mysql zip WORKDIR /app # Copy the manifests first so the install layer is deterministic and cache-friendly; # committing composer.lock pins exact dependency versions. COPY composer.json composer.lock ./ RUN composer install --no-dev --optimize-autoloader --no-scripts --no-interaction COPY . /app RUN composer dump-autoload --optimize --no-interaction EXPOSE 8080 CMD ["sh", "-c", "exec frankenphp php-server --listen 0.0.0.0:$PORT --root /app/public"] ``` -------------------------------- ### Define services with commands in app.toml Source: https://miren.md/app-configuration Define multiple services with their own commands. Each service gets its own command, scaling configuration, and optionally its own container image. ```toml [services.web] command = "node server.js" [services.worker] command = "node worker.js" ``` -------------------------------- ### Install miren server without cloud Source: https://miren.md/command/server-install Installs the miren server for local-only operation, skipping cloud registration setup. Use this when you do not want to connect to miren.cloud. ```bash miren server install --without-cloud ``` -------------------------------- ### Common Lisp app.lisp: load Quicklisp, start Hunchentoot, keep alive Source: https://miren.md/guides/commonlisp Script that loads Quicklisp, defines a Hunchentoot handler, reads the PORT environment variable (default 8080), starts an easy-acceptor on 0.0.0.0, and blocks forever with (loop (sleep 3600)) so the process stays up. ```commonlisp (load "/quicklisp/setup.lisp") (ql:quickload :hunchentoot :silent t) (setf hunchentoot:*dispatch-table* (list (hunchentoot:create-prefix-dispatcher "/" (lambda () (setf (hunchentoot:content-type*) "text/plain") (format nil "Hello from Common Lisp on Miren!~%"))))) (defvar *port* (parse-integer (or (uiop:getenv "PORT") "8080"))) (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor :port *port* :address "0.0.0.0")) (format t "listening on 0.0.0.0:~a~%" *port*) (loop (sleep 3600)) ``` -------------------------------- ### Provisioning script to install runner with reusable token Source: https://miren.md/distributed-runners Idempotent provisioning script that checks for an existing service, fetches a reusable token from a secret store, and runs `miren runner install` with `--skip-system-check` and `--force`. The `systemctl cat` guard prevents re-enrollment on reboots, while `--force` cleans up half-finished attempts. ```bash # Skip if this machine already enrolled on a previous boot if systemctl cat miren-runner.service >/dev/null 2>&1; then echo "Runner already enrolled" else # Pull the reusable token from your secret store TOKEN=$(your-secret-tool read miren/runner-token) miren runner install \ --token "$TOKEN" \ --skip-system-check \ --force fi ``` -------------------------------- ### miren logs build examples Source: https://miren.md/logs View build output for an app. Replace VERSION with a version from miren app history. ```miren # Show build logs for the latest version miren logs build -a myapp # Show build logs for a specific version miren logs build -a myapp VERSION ``` -------------------------------- ### Check server logs in container with docker or podman Source: https://miren.md/troubleshooting For container installations (Docker or Podman), follow the Miren container logs. Use whichever runtime you installed with. Note: Podman is daemonless and may not restart after reboot without additional setup. ```bash docker logs -f miren # or: podman logs -f miren ``` -------------------------------- ### Example: Check authentication Source: https://miren.md/command/doctor-auth Runs the `miren doctor auth` command to check authentication and user information. ```bash miren doctor auth ``` -------------------------------- ### Dockerfile.miren for COBOL with socat Source: https://miren.md/guides/cobol Builds the COBOL program with GnuCOBOL and installs socat. The CMD starts socat to listen on $PORT and execute the program per connection. ```dockerfile FROM debian:12-slim RUN apt-get update -y \ && apt-get install -y gnucobol socat \ && apt-get clean && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY hello.cob . RUN cobc -x -o /app/hello hello.cob EXPOSE 8080 CMD ["sh", "-c", "exec socat TCP-LISTEN:$PORT,reuseaddr,fork EXEC:/app/hello"] ``` -------------------------------- ### Reveal a sensitive variable Source: https://miren.md/command/env-get Example command to get the value of the SECRET_KEY environment variable, using the --unmask flag to show the actual value instead of masking it. ```bash miren env get SECRET_KEY --unmask ``` -------------------------------- ### Initialize and deploy a Go app with Miren Source: https://miren.md/guides/go Run these commands from the project root to initialize and deploy the app. Miren auto-detects Go from go.mod and builds the binary. ```bash miren init miren deploy ``` -------------------------------- ### Dockerfile.miren and .dockerignore for JRuby Source: https://miren.md/guides/jruby The Dockerfile.miren builds on the jruby:9.4 image, installs gems with Bundler at build time, and starts Puma on the injected PORT. The .dockerignore excludes .git from the build context. ```dockerfile FROM jruby:9.4 WORKDIR /app COPY Gemfile ./ RUN bundle install COPY . /app EXPOSE 8080 CMD ["sh", "-c", "exec bundle exec puma -b tcp://0.0.0.0:$PORT"] ``` ```dockerignore .git ``` -------------------------------- ### Basic deploy Source: https://miren.md/command/deploy Deploys the application with default settings, building the image if needed and activating the resulting version. This is the basic form of the command. ```bash miren deploy ``` -------------------------------- ### Create Dockerfile.miren for Julia Source: https://miren.md/guides/julia Required because Miren doesn't auto-detect Julia. Installs and precompiles HTTP during the build to reduce cold-start JIT compile time; the CMD starts the app and no Procfile is needed. ```dockerfile FROM julia:1.10 WORKDIR /app RUN julia -e 'using Pkg; Pkg.add("HTTP"); using HTTP' COPY . /app EXPOSE 8080 CMD ["julia", "/app/app.jl"] ``` -------------------------------- ### List apps as JSON Source: https://miren.md/command/app-list Lists applications with JSON output. Use the --format flag with the value json to get machine-readable output. ```bash miren app list --format json ``` -------------------------------- ### Load and set as active cluster Source: https://miren.md/command/config-load Example of loading a configuration file and setting it as the active cluster using the --set-active flag. ```bash miren config load --input cluster-config.yaml --set-active ``` -------------------------------- ### Dockerfile.miren with socat socket front-end Source: https://miren.md/guides/bash Dockerfile that installs bash and socat, copies the script, and starts socat to listen on $PORT. Miren injects PORT and socat forks a process per connection. Suited for low-traffic endpoints. ```dockerfile FROM debian:12-slim RUN apt-get update -y && apt-get install -y bash socat && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY hello.sh . RUN chmod +x hello.sh EXPOSE 8080 CMD ["sh", "-c", "exec socat TCP-LISTEN:$PORT,reuseaddr,fork EXEC:/app/hello.sh"] ``` -------------------------------- ### Dockerfile.miren building rebar3 release and running on debian-slim Source: https://miren.md/guides/erlang Multi-stage Dockerfile that builds a rebar3 release on erlang:27 and runs it on debian:12-slim. The runtime installs libncurses6 and libssl3 for the bundled ERTS, exposes port 8080, and starts the release in foreground. ```dockerfile # ----- Build stage ----- FROM erlang:27 AS builder WORKDIR /app COPY . . RUN rebar3 release # ----- Runtime stage ----- FROM debian:12-slim RUN apt-get update -y && apt-get install -y libncurses6 libssl3 && rm -rf /var/lib/apt/lists/* COPY --from=builder /app/_build/default/rel/erlang_bench /app EXPOSE 8080 CMD ["/app/bin/erlang_bench", "foreground"] ``` -------------------------------- ### Bring a route back: miren route up example.com Source: https://miren.md/command/route-up Brings the route for `example.com` out of maintenance and back to serving normally. ```bash miren route up example.com ``` -------------------------------- ### Create environment file for DNS provider credentials Source: https://miren.md/tls Create an environment file at /var/lib/miren/server/env with the required credentials for the DNS provider. Each provider requires specific environment variables. ```bash DNSIMPLE_OAUTH_TOKEN=your-token-here ``` -------------------------------- ### Python Flask OpenTelemetry auto-instrumentation setup Source: https://miren.md/observability Set up OpenTelemetry auto-instrumentation for a Flask app. Install the required packages, configure the OTLP endpoint and service name in `.miren/app.toml`, and run the app with `opentelemetry-instrument` in a Procfile. The wrapper automatically reads the `traceparent` header and creates spans for Flask routes. ```bash pip install opentelemetry-distro opentelemetry-exporter-otlp opentelemetry-bootstrap -a install ``` ```toml [[env]] key = "OTEL_EXPORTER_OTLP_ENDPOINT" value = "https://your-otel-collector:4318" [[env]] key = "OTEL_SERVICE_NAME" value = "my-flask-app" ``` ```text # Procfile web: opentelemetry-instrument flask run --host 0.0.0.0 --port 3000 ``` -------------------------------- ### Show route details: miren route show example.com Source: https://miren.md/command/route-show Shows details for the route with hostname example.com. This is the basic invocation without any flags. ```bash miren route show example.com ``` -------------------------------- ### Multi-stage Dockerfile.miren for Node.js app Source: https://miren.md/guides Use this multi-stage Dockerfile.miren when your application requires custom build steps, system dependencies, or a language that isn't auto-detected. The first stage installs dependencies and builds the app; the second stage copies the built output and node_modules, exposes port 3000, and starts the server. ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules EXPOSE 3000 CMD ["node", "dist/index.js"] ``` -------------------------------- ### miren init command usage Source: https://miren.md/command/init Shows the basic command syntax for initializing a new application with miren init. Use this as a reference for the available flags and global options. ```bash miren init [flags] ``` -------------------------------- ### Dockerfile.miren for TruffleRuby with Puma Source: https://miren.md/guides/truffleruby Dockerfile.miren for TruffleRuby, based on the official GraalVM community image. It copies the Gemfile, runs bundle install, copies the app, exposes port 8080, and starts Puma bound to 0.0.0.0 on the $PORT environment variable. The CMD is used as the web service's startup default, so no Procfile or service command is needed. ```dockerfile FROM ghcr.io/graalvm/truffleruby-community:latest WORKDIR /app COPY Gemfile ./ RUN bundle install COPY . /app EXPOSE 8080 CMD ["sh", "-c", "exec bundle exec puma -b tcp://0.0.0.0:$PORT"] ``` -------------------------------- ### Install Miren skills for Pi Source: https://miren.md/agent-skills Install the Miren agent skills for Pi using the pi install command. ```bash pi install git:github.com/mirendev/miren-skills ``` -------------------------------- ### Initialize with a specific name Source: https://miren.md/command/init Initializes a new application with the specified name 'myapp'. Use the --name flag to override the default directory name. ```bash miren init --name myapp ``` -------------------------------- ### Install Miren skills for Claude Code Source: https://miren.md/agent-skills Install the Miren agent skills for Claude Code by adding the marketplace and installing the plugin. ```bash /plugin marketplace add mirendev/miren-skills /plugin install miren@miren ``` -------------------------------- ### Preview Miren detection with miren deploy --analyze Source: https://miren.md/guides/go Use this command to preview what Miren detects — main package, version, entrypoint — without building. ```bash miren deploy --analyze ``` -------------------------------- ### Check for updates without installing Source: https://miren.md/command/upgrade Checks for available updates without installing them. ```bash miren upgrade --check ``` -------------------------------- ### Clone and enter the sample apps demo directory Source: https://miren.md/getting-started Clones the Miren sample apps repository and changes into the demo app directory. Use this before running Miren commands on the demo app. ```bash git clone https://github.com/mirendev/sample-apps.git cd sample-apps/demo ``` -------------------------------- ### Initialize in current directory Source: https://miren.md/command/init Initializes a new application in the current directory. The application name defaults to the directory name. ```bash miren init ``` -------------------------------- ### Minimum working example: .miren/app.toml with web and worker services Source: https://miren.md/services Defines two services in .miren/app.toml. Both run from the app's primary image; web receives HTTP traffic and worker runs alongside, each scaling independently. ```toml name = "myapp" [services.web] command = "npm start" [services.worker] command = "npm run worker" ``` -------------------------------- ### Minimal .miren/app.toml Source: https://miren.md/app-configuration Minimal configuration file that names the app and defines the start command for the web service. Deploy with `miren deploy` to build the image and run the service with this command. ```toml name = "myapp" [services.web] command = "npm start" ``` -------------------------------- ### Deploy Raku app with app.toml and miren deploy Source: https://miren.md/guides/raku Create .miren/app.toml naming the app (raku-bench), then deploy from the project root with miren deploy. The Dockerfile's CMD is used as the startup command, so no Procfile is needed. ```toml name = "raku-bench" ``` ```shell miren deploy ``` -------------------------------- ### Install Plack and Starman for PSGI Source: https://miren.md/guides/perl Installs Plack and Starman for PSGI apps (Dancer2, Catalyst) in the Dockerfile. ```dockerfile RUN cpanm --notest Plack Starman ``` -------------------------------- ### Install Miren Server Without Cloud Registration Source: https://miren.md/getting-started Runs the same install but skips cloud registration and runs standalone. ```miren sudo miren server install --without-cloud ``` -------------------------------- ### List available addons Source: https://miren.md/command/addon-list-available Lists all available addons. This is the basic invocation without any flags. ```bash miren addon list-available ``` -------------------------------- ### Read PORT and start Cowboy listener in start/2 Source: https://miren.md/guides/erlang Reads the injected PORT environment variable (default 8080) and starts Cowboy's clear listener on it, binding all interfaces. The handler routes "/" to erlang_bench_handler and starts the application supervisor. ```erlang -module(erlang_bench_app). -behaviour(application). -export([start/2, stop/1]). start(_Type, _Args) -> Dispatch = cowboy_router:compile([ {'_', [{<<"/", erlang_bench_handler, []>>}]} ]), Port = list_to_integer(os:getenv("PORT", "8080")), {ok, _} = cowboy:start_clear(http_listener, [{port, Port}], #{env => #{dispatch => Dispatch}}), erlang_bench_sup:start_link(). stop(_State) -> ok. ``` -------------------------------- ### Deploy from project root with miren deploy Source: https://miren.md/deployment Run from the project root to deploy the app in the current directory. Miren reads the app name from .miren/app.toml and creates the app on the server if it is the first deploy. ```miren cd ~/myapp miren deploy ``` -------------------------------- ### Complete Multi-Service App: web, worker, and database with disks Source: https://miren.md/scaling Complete configuration for a multi-service app named 'myapp' with a web service (auto-scaling), a worker service (fixed at 3 instances), and a database (single instance with persistent storage). ```toml name = "myapp" # Web service: autoscales based on traffic [services.web.concurrency] mode = "auto" requests_per_instance = 20 scale_down_delay = "10m" # Worker service: fixed at 3 instances [services.worker.concurrency] mode = "fixed" num_instances = 3 # Database: single instance with persistent storage [services.db] image = "postgres:16" [services.db.concurrency] mode = "fixed" num_instances = 1 [[services.db.disks]] name = "postgres-data" mount_path = "/var/lib/postgresql/data" size_gb = 20 ``` -------------------------------- ### Install miren server with cloud registration Source: https://miren.md/command/server-install Installs the miren server with cloud registration enabled. This is the default behavior when no cloud-related flags are provided. ```bash miren server install ``` -------------------------------- ### Initialize and deploy a Rust app with Miren Source: https://miren.md/guides/rust Initializes and deploys a Rust app on Miren from the project root. Run these commands in order to set up and deploy the app. ```bash miren init miren deploy ``` -------------------------------- ### Deploy Deno app with miren deploy Source: https://miren.md/guides/deno Create .miren/app.toml with the app name, then run miren deploy from the project root. ```toml name = "deno-bench" ``` ```bash miren deploy ``` -------------------------------- ### miren env get usage Source: https://miren.md/command/env-get Shows the basic command syntax for miren env get. Use this to retrieve an environment variable value. ```bash miren env get [flags] ``` -------------------------------- ### Install miren server with custom HTTP port Source: https://miren.md/command/server-container-install Installs the miren server with a custom HTTP port mapping of 8080 instead of the default 80. ```bash miren server container install --http-port 8080 ``` -------------------------------- ### Create user and register node Source: https://miren.md/recipes/headscale Execute commands inside the Headscale sandbox to create a user, list users, generate a pre-authentication key, and list nodes. ```bash miren sandbox list # find the headscale web sandbox miren sandbox exec -- headscale users create alice miren sandbox exec -- headscale users list # note alice's numeric ID miren sandbox exec -- headscale preauthkeys create --user --expiration 24h miren sandbox exec -- headscale nodes list ``` -------------------------------- ### Analyze deploy with --analyze Source: https://miren.md/command/deploy Analyzes the app without building, showing the detected stack, services, and other details. Use this to preview how the deployment will be treated before actually deploying. ```bash miren deploy --analyze ``` -------------------------------- ### Start PSGI app with Starman Source: https://miren.md/guides/perl Starts a PSGI app with Starman, listening on 0.0.0.0:$PORT. Replaces the Dockerfile's CMD for PSGI apps. ```dockerfile CMD ["sh", "-c", "exec plackup -s Starman --host 0.0.0.0 --port \"$PORT\" /app/app.psgi"] ``` -------------------------------- ### Back up with custom output path (-o) Source: https://miren.md/addons Backs up the disk to a custom output path using the `-o` flag. Must be run on the server. ```miren miren disk backup -n pg-pg-myapp-sCZDabc123-data -o /backups/myapp-db.miren.zst ``` -------------------------------- ### Install Miren skills for OpenCode Source: https://miren.md/agent-skills Install the Miren agent skills for OpenCode by cloning the repository and copying the skills to the user's OpenCode skills directory. ```bash git clone https://github.com/mirendev/miren-skills cp -r miren-skills/.agents/skills/* ~/.config/opencode/skills/ ``` -------------------------------- ### Full configuration in .miren/app.toml with concurrency Source: https://miren.md/services Shows how to use .miren/app.toml for more control, including scaling with a fixed concurrency mode and num_instances for the worker service. ```toml [services.web] command = "npm start" [services.worker] command = "npm run worker" [services.worker.concurrency] mode = "fixed" num_instances = 2 ``` -------------------------------- ### Example Cargo.toml for a Rust app Source: https://miren.md/guides/rust Example Cargo.toml for a Rust app on Miren. The package name is used as the binary name unless a [[bin]] name is specified. ```toml [package] name = "myapp" version = "0.1.0" edition = "2021" [dependencies] axum = "0.7" tokio = { version = "1", features = ["full"] } ``` -------------------------------- ### List all app versions Source: https://miren.md/command/app-versions Lists all app versions with their status. This is the basic usage without any flags. ```bash miren app versions ``` -------------------------------- ### Install Miren skills for Codex CLI Source: https://miren.md/agent-skills Install the Miren agent skills for Codex CLI by cloning the repository and copying the skills to the user's skills directory. ```bash git clone https://github.com/mirendev/miren-skills cp -r miren-skills/.agents/skills/* ~/.agents/skills/ ``` -------------------------------- ### Start miren server in standalone mode Source: https://miren.md/command/server Use this command to start the miren server in standalone mode. This is the basic invocation for running the server without additional configuration. ```bash miren server --mode standalone ``` -------------------------------- ### Install miren server with unattended enroll token Source: https://miren.md/command/server-install Installs the miren server with an unattended enroll token read from a file. This registers the server without requiring browser approval. ```bash miren server install --enroll-token "$(cat /etc/miren/enroll-token)" ``` -------------------------------- ### Deploy Zig app with miren Source: https://miren.md/guides/zig Deploy configuration and command. Create `.miren/app.toml` with the app name, then run `miren deploy` from the project root. The Dockerfile's `CMD` starts the app, so no Procfile or service command is needed. ```toml name = "zig-bench" ``` ```bash miren deploy ``` -------------------------------- ### View build logs for a version Source: https://miren.md/command/logs-build Displays build logs for the specified version (e.g., v3). ```bash miren logs build v3 ``` -------------------------------- ### Install miren server behind TLS-terminating proxy Source: https://miren.md/command/server-container-install Installs the miren server behind a TLS-terminating proxy such as tailscale serve or nginx. In this mode, Miren serves plain HTTP behind the proxy. ```bash miren server container install --ingress-mode behind-proxy-http ``` -------------------------------- ### List all apps Source: https://miren.md/command/app-list Lists all applications in the default text format. This is the basic invocation without any flags. ```bash miren app list ``` -------------------------------- ### Example output of miren app history Source: https://miren.md/deployment Example output from 'miren app history -a myapp'. Shows three deployments with status icons, version identifiers, relative times, and the deploying user. The ✗ icon marks a failed deployment. ```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 ``` -------------------------------- ### Follow logs with -f Source: https://miren.md/command/logs-app Shows how to stream logs in real-time using --follow (or -f). The second example follows logs for a specific app using -a. ```bash # Follow logs as they arrive miren logs -f # Follow logs for a specific app miren logs app -a myapp -f ``` -------------------------------- ### Verify environment file for DNS-01 challenges Source: https://miren.md/tls Verify that the environment file is loaded for DNS-01 challenges. Run on the server. ```bash sudo systemctl show miren | grep EnvironmentFile ``` -------------------------------- ### Example: revoke a token Source: https://miren.md/command/runner-token-revoke Revokes the token with ID inv_abc123. ```bash miren runner token revoke inv_abc123 ``` -------------------------------- ### Deploy command usage Source: https://miren.md/command/deploy Shows the general usage syntax for the deploy command. Use this as a reference for the command's flags and options. ```bash miren deploy [flags] ``` -------------------------------- ### miren logout example Source: https://miren.md/command/logout Logs out by removing local authentication credentials. ```bash miren logout ```