Skip to main content

app.toml Reference

Complete reference for .miren/app.toml — the configuration file for Miren applications.

For a guide-style introduction, see App Configuration.

File Structure

name = "myapp"
post_import = "make db-migrate"
include = ["configs/"]

# Global environment variables
[[env]]
key = "DATABASE_URL"
value = "postgres://db.app.miren:5432/myapp"

# Build configuration
[build]
version = "3.12"
dockerfile = "Dockerfile.miren"
onbuild = ["npm run build"]

# Service definitions
[services.web]
command = "node server.js"
port = 3000

[services.web.concurrency]
mode = "auto"
requests_per_instance = 10
scale_down_delay = "15m"
shutdown_timeout = "10s"

[services.worker]
command = "node worker.js"

[services.worker.concurrency]
mode = "fixed"
num_instances = 2
shutdown_timeout = "10s"

[services.db]
image = "postgres:16"

[[services.db.disks]]
name = "pgdata"
mount_path = "/var/lib/postgresql/data"
size_gb = 20

# Addons
[addons.storage]
variant = "minio"

Top-Level Fields

FieldTypeDescriptionDefault
namestringApplication nameInferred from directory name
post_importstringCommand to run after importing a new version (e.g. database migrations)
includestring[]Extra files or directories to include in the build context
concurrencyintLegacy. Global concurrency target. Use [services.<name>.concurrency] instead.

[[env]] — Environment Variables

Declares environment variables available to all services. Service-level [[services.<name>.env]] entries are merged with these.

[[env]]
key = "DATABASE_URL"
value = "postgres://db.app.miren:5432/myapp"

[[env]]
key = "SECRET_KEY"
required = true
sensitive = true
description = "Used for session signing"
FieldTypeDescriptionDefault
keystringVariable name. Required.
valuestringVariable value""
requiredboolFail deploy if value is emptyfalse
sensitiveboolMask value in CLI output and logsfalse
descriptionstringHuman-readable explanation of this variable
Validation

Every env entry must have a non-empty key. If required is true and value is empty at deploy time, the deploy fails.

[build] — Build Configuration

Controls how Miren builds your container image.

[build]
version = "3.12"
dockerfile = "Dockerfile.custom"
onbuild = ["npm run build", "npm prune --production"]
alpine_image = "alpine:3.19"
FieldTypeDescriptionDefault
versionstringLanguage/runtime version (e.g. "20" for Node, "3.12" for Python)Detected from project files
dockerfilestringPath to a custom DockerfileAuto-detected (Dockerfile.miren or built-in)
onbuildstring[]Commands to run in /app after the main build steps
alpine_imagestringCustom Alpine base image for the runtime stageBuilt-in default

[services.<name>] — Service Configuration

Each named section under services defines a process in your app. See Services for usage patterns.

[services.web]
command = "node server.js"
port = 3000
port_name = "http"
port_type = "http"

[services.postgres]
image = "postgres:16"
FieldTypeDescriptionDefault
commandstringCommand to runImage's default entrypoint
portintPort the service listens on (single-port shorthand)3000 (web only)
port_namestringNamed port identifier (single-port shorthand)Service name
port_typestring"http" or "tcp" (single-port shorthand)"http"
ports[port]Multi-port configuration array
imagestringContainer image to use instead of the app's built imageApp's built image
env[env]Service-specific environment variables (same schema as global [[env]])
concurrencyconcurrencyScaling configurationSee defaults below
disks[disk]Persistent disk attachments
note

You cannot mix the single-port fields (port, port_name, port_type) with the ports array on the same service.

[services.<name>.concurrency] — Scaling

Controls how many instances of a service run. See Application Scaling for tuning guidance.

Default for web: auto mode, 10 requests per instance, 15m scale-down delay, 10s shutdown timeout.

Default for all other services: fixed mode, 1 instance, 10s shutdown timeout.

# Autoscaling
[services.web.concurrency]
mode = "auto"
requests_per_instance = 10
scale_down_delay = "15m"
shutdown_timeout = "10s"

# Fixed instances
[services.worker.concurrency]
mode = "fixed"
num_instances = 2
shutdown_timeout = "10s"
FieldTypeDescriptionDefault
modestring"auto" or "fixed""auto" for web, "fixed" for others
requests_per_instanceintTarget concurrent requests per instance (auto mode only)10
scale_down_delaydurationTime to wait before removing idle instances (auto mode only)"15m"
num_instancesintExact number of instances to run (fixed mode only)1
shutdown_timeoutdurationTime to wait for graceful shutdown during redeploy"10s"
Validation
  • mode must be "auto" or "fixed".
  • In auto mode: requests_per_instance must be non-negative, scale_down_delay must be a valid Go duration, and num_instances must not be set.
  • In fixed mode: num_instances must be at least 1, and requests_per_instance / scale_down_delay must not be set.
  • shutdown_timeout must be a valid Go duration (e.g. "10s", "30s").

[[services.<name>.ports]] — Ports

Configures network ports for a service. Use this when a service needs multiple ports or non-HTTP protocols. See Traffic Routing for usage patterns and examples.

[[services.app.ports]]
port = 3000
name = "http"
type = "http"

[[services.app.ports]]
port = 7000
name = "data"
type = "tcp"
node_port = 7000
FieldTypeDescriptionDefault
portintPort your process listens on (1–65535). Required.
namestringUnique name for this port. Required.
typestring"http" for web traffic, "tcp" for raw TCP, "udp" for UDP"http"
node_portintPort to expose on the host machine (1–65535)(none)
Validation
  • port must be between 1 and 65535.
  • name is required and must be unique within the service.
  • type must be "http", "tcp", or "udp".
  • Each (port, type) pair must be unique within the service ("tcp" and "http" share the TCP transport, so port 8080 with type "http" and port 8080 with type "tcp" conflict, but port 53 with "tcp" and port 53 with "udp" are allowed).
  • node_port must be between 1 and 65535 and unique across the cluster.

[[services.<name>.disks]] — Persistent Disks

Attaches persistent storage to a service. See Persistent Storage for details on local shared storage vs. Miren Disks.

[[services.db.disks]]
name = "pgdata"
mount_path = "/var/lib/postgresql/data"
size_gb = 20
filesystem = "ext4"
read_only = false
lease_timeout = "30s"
FieldTypeDescriptionDefault
namestringUnique disk name. Required.
mount_pathstringMount point inside the container. Required.
size_gbintDisk size in gigabytes (required for new disks, ignored for existing)
filesystemstring"ext4", "xfs", or "btrfs""ext4"
read_onlyboolMount as read-onlyfalse
lease_timeoutdurationHow long to wait when acquiring the exclusive disk lease
Validation
  • name and mount_path are required.
  • filesystem must be ext4, xfs, or btrfs.
  • size_gb must be non-negative.
  • lease_timeout must be a valid Go duration (e.g. "30s", "2m").
  • Services with disks must use mode = "fixed" and num_instances = 1.

[addons.<name>] — Addons

Configures add-on services managed by Miren.

[addons.storage]
variant = "minio"
FieldTypeDescriptionDefault
variantstringAddon variant to use

Duration Format

Fields marked as duration accept Go duration strings: a sequence of decimal numbers with unit suffixes. Valid units are s (seconds), m (minutes), h (hours).

Examples: "10s", "2m", "1h30m", "15m".