Go on Miren
Miren auto-detects Go apps from go.mod, builds them to a single binary at
/bin/app, and ships it on a minimal runtime image — no Dockerfile required.
Ask your AI coding agent to "set up this Go app on Miren" after installing the Miren agent skills. It finds your main package, proposes a start command, wires up environment variables, and deploys — using this page as its reference.
Do you need a Dockerfile?
No. Miren detects Go from go.mod and compiles the binary for you. The Go version
comes from the go directive in your go.mod (falling back to 1.23). Provide a
Dockerfile.miren only for custom build steps — see
Using Dockerfile.miren.
Set up the app
From your project root:
miren init
miren deploy
Preview what Miren detects — main package, version, entrypoint — without building:
miren deploy --analyze
Which package gets built
Miren looks for your main package in cmd/:
- If
cmd/has a single subdirectory, that one is built. - If
cmd/has a subdirectory matching the app name, that one is built. - Otherwise, Miren builds from the project root.
If your project has a vendor/ directory, Miren builds with -mod=vendor for faster,
network-free builds.
Start command
The compiled binary is at /bin/app. Your server must bind to 0.0.0.0 on $PORT —
Miren injects PORT and routes traffic to it. Read it with os.Getenv("PORT"):
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe("0.0.0.0:"+port, nil))
Use a Procfile to set flags or define additional processes:
# Run the compiled binary
web: /bin/app
# With flags
web: /bin/app -addr=0.0.0.0:$PORT
# Background worker
worker: /bin/app -mode=worker
See Services for running multiple processes.
Runtime files
The runtime image is minimal but carries your non-Go files (templates, migrations,
static assets, data directories) alongside the binary so the app can read them at
runtime relative to /app. Go source, go.mod, go.sum, and vendor/ are excluded —
the compiled binary needs none of them.
If your app depends on files it must have at runtime, embed them with
go:embed rather than relying on them being copied. Embedded
files are compiled into the binary and always present.
Environment variables
Set variables with miren env set — -e for plain values, -s for secrets (masked
in output and logs):
miren env set -e LOG_LEVEL=info
miren env set -s DATABASE_URL
miren env set -s API_TOKEN
miren env set -s API_TOKEN (no value) prompts with masked input. You can also declare
variables in .miren/app.toml:
[[env]]
key = "DATABASE_URL"
value = ""
required = true
sensitive = true
description = "Postgres connection string"
See App Configuration — Environment Variables.
Agent quick reference
- Detection:
go.modin the project - Version: parsed from the
godirective ingo.mod(fallback 1.23) - Binary: built to
/bin/app; main package resolved fromcmd/(see rules above) - Vendored deps:
vendor/present → build uses-mod=vendor - Start command:
web: /bin/app; bind0.0.0.0:$PORTviaos.Getenv("PORT") - Runtime files: non-Go files carried to
/app; prefergo:embedfor required assets - Env vars:
miren env set -e KEY=VALUE,-sfor secrets, or[[env]]inapp.toml - Dockerfile: not needed; add
Dockerfile.mirenonly for custom builds
Next steps
- Supported Languages — Go — full build detail
- App Configuration — customize
.miren/app.toml - Services — web + workers
- Deployment — how deploys build and activate