Menu

Containers

Containers are the primary runtime unit in MacTain. The CLI exposes commands to create, start, stop, restart, remove, inspect, list, fetch logs, execute commands, copy files, inspect stats, and map a VM PID back to a running container. Use containers for one-off tools, standalone services, and the runtime units that Blueprints create for repeatable applications.

Container Defaults

When you define a container with mactain container create or the define-and-start form of mactain container start --name ... --image ..., MacTain applies these defaults unless you pass different flags:

SettingDefaultWhen to override it
CPU allocation2 CPUsUse fewer CPUs for small background helpers; use more for build jobs, databases, or services that need parallel work.
Memory allocation2048 MiBUse less for tiny tools; use more for databases, JVM services, language servers, or anything that exits under memory pressure.
Networkmactain-defaultAdd --network-scope when containers need explicit service discovery, grouping, or isolation.
AutostartoffAdd --autostart for services that should return after the Engine starts.
Autostart delay0 secondsAdd a delay when dependencies need time to start first.
Docker API shim accessnoneKeep this default unless the workload needs Docker-compatible API calls inside the container.
Health retries3Increase retries for slow-starting services; use --health-start-period to ignore expected warm-up failures.
Persistent loggingoffEnable it for services where logs must survive container exits.
Persistent log file size1000000 bytesTune when a service is chatty and you need more or less retained output.
Persistent log file count5 files per streamTune with file size to control retained log history.

Container definitions are immutable for define-time options such as resources, mounts, published ports, DNS settings, --init, and --enable-tun. If those settings are wrong, create a replacement definition with the corrected flags instead of expecting mactain container start <name> to change them.

Command Reference

CommandDescriptionTypical use
mactain container listLists defined and running containers.Find names, IDs, states, and inventory before acting.
mactain container status <name>Shows detailed runtime status for one running container.Confirm IP, ports, health, and runtime details.
mactain container stats [name]Shows CPU, memory, state, and uptime telemetry.Decide whether resource defaults should be changed.
mactain container inspect <name>Shows persisted container definition details.Review image, resources, mounts, publishes, env redaction, and config.
mactain container create --name ... --image ...Defines a standalone container without starting it.Set resources, mounts, ports, DNS, health, logging, and lifecycle options once.
mactain container start <name>Starts an existing container definition.Start a reusable container after it has been defined.
mactain container start --name ... --image ...Defines a new container and starts it in one command.MacTain's create-and-start path for first runs, short-lived jobs, and Docker run-style workflows.
mactain container start --allStarts all containers.Bring back a local environment after Engine start.
mactain container stop <name>Stops a running container.Gracefully shut down one workload.
mactain container restart <name>Restarts a running container.Apply runtime restart without changing the definition.
mactain container remove <name>Removes a container definition.Replace an immutable definition or clean up unused containers.
mactain container logs <name>Fetches container logs.Diagnose startup and application behavior.
mactain container exec <name> -- shRuns a command in a running container.Inspect runtime state from inside the workload.
mactain container copy <src> <dest>Copies a regular file between host and running container.Move a config file or inspect a generated file.
mactain container pid <pid>Maps a VM PID back to a running container.Investigate Activity Monitor process usage.
mactain container docsShows built-in container examples.Get installed-release examples from the CLI.

Run mactain container <subcommand> --help for exact flags in your installed release.

Mounts And Storage

Use --mount when a container needs files or scratch storage beyond the image filesystem. MacTain supports three mount types on container create and define-and-start commands:

Mount typeSyntaxUse it for
Bind mounttype=bind,source=/host/path,target=/container/path[,readonly]Sharing a specific host directory or file tree with a container.
Named volumetype=volume,source=name,target=/container/path[,readonly]Durable app data that should outlive container replacement.
Tmpfstype=tmpfs,target=/container/path[,size=1G]Ephemeral in-memory scratch space that should disappear with the container.

Mount targets must be absolute paths inside the container. Bind mount sources can be absolute host paths or relative paths resolved from the current working directory. Named volumes can be created explicitly with mactain volume create or created on first use when a container references a missing named volume. Tmpfs mounts do not use source and do not support readonly.

Choose mount types by intent:

  • Use bind mounts for source code, local config files, or host folders you want to edit directly from macOS.
  • Use named volumes for databases, app state, caches, and data that should survive container removal.
  • Use tmpfs for temporary scratch paths, caches, or secrets material that should not persist.

Defaults And Behavior

The default table above applies when defining a container. These behavior rules matter most when moving from examples to daily use:

  • Define-time settings are immutable: recreate the container to change resources, mounts, published ports, DNS, --init, or --enable-tun.
  • mactain container start <name> starts an existing definition; it does not apply new define-time flags.
  • mactain container start --name ... --image ... is the shortcut that both defines and starts a new container.
  • This is intentionally different from Docker. Docker separates docker run for create-and-start from docker start for existing containers. MacTain uses mactain container start for both modes: pass only a name or ID to start an existing definition; pass --name and --image to define and start a new container.
  • Add --remove to a define-and-start command when the container should be removed automatically after it stops.
  • Mounts are define-time settings. Recreate the container to change bind, volume, or tmpfs mounts.
  • Named volumes are single-attach for running containers: one running container can attach a named volume at a time.
  • JSON output redacts sensitive env and command values by default. Use --json-full only in trusted automation.
  • container restart restarts a running container; restart policy is configured when defining the container with --restart.

Practical Use Cases

Use case: start a web service and publish it locally

Use this when you want a local service reachable from your Mac, such as a web server or API. The --publish flag maps a host port to a container port. This example relies on the default 2 CPUs and 2048 MiB because a small web server usually does not need custom resources.

mactain container start \
  --name web \
  --image docker.io/library/nginx:latest \
  --publish 8080:80 \
  --detach
mactain container logs web --lines 50

Open http://localhost:8080 after the container starts. If it is not reachable, check Networking before changing the image or container command.

Use case: define a reusable container without starting it

Use this when you want to set environment, ports, mounts, restart policy, or resource limits once, then start the same definition later.

mactain container create \
  --name api \
  --image ghcr.io/acme/api:latest \
  --publish 8080:8080 \
  --memory-mib 2048 \
  --cpus 2
mactain container start api

Container definitions are immutable. If you need different flags later, create a replacement container definition rather than expecting start <name> to change the existing one.

Use case: bind mount a local project directory

Use this when a container should read files you edit on your Mac, such as source code, test fixtures, or a local config directory.

mactain container start \
  --name docs-preview \
  --image ghcr.io/acme/docs-preview:latest \
  --mount type=bind,source=./docs,target=/workspace/docs,readonly \
  --publish 5173:5173 \
  --detach

Use readonly when the container only needs to read host files. Omit readonly only when the container should write back to the host path.

Use case: mount a named volume for durable app data

Use this for app state that should survive container replacement, such as a database data directory or media index.

mactain volume create app-data
mactain container create \
  --name app \
  --image ghcr.io/acme/app:latest \
  --mount type=volume,source=app-data,target=/var/lib/app
mactain container start app

Inspect and back up named volumes before removing or pruning them:

mactain volume inspect app-data
mactain volume backup app-data

Use case: add tmpfs scratch space

Use this for temporary data that should not persist after the container stops, such as build scratch space or transient cache files.

mactain container start \
  --name scratch-job \
  --image ghcr.io/acme/worker:latest \
  --mount type=tmpfs,target=/tmp,size=1G \
  --command /bin/sh \
  --args -lc \
  --args "make test" \
  --remove

Do not put durable data in tmpfs. Use a named volume when you need the data after the container exits.

Use case: run a one-time container and remove it after exit

Use this for a short job, smoke check, or command you do not want to keep as a container definition. MacTain creates the container, starts it, waits for the foreground command, and removes the container after it stops.

mactain container start \
  --name hello-once \
  --image docker.io/library/alpine:latest \
  --command /bin/sh \
  --args -lc \
  --args "echo hello from MacTain" \
  --remove

Do not use --remove for services or containers that own data you still need. Use Volumes for durable data.

Use case: right-size resources for the workload

Use this when the default 2 CPUs and 2048 MiB are either too generous or too small. Start with the default for unknown workloads, then check runtime telemetry before changing limits.

mactain container start \
  --name worker \
  --image ghcr.io/acme/worker:latest \
  --cpus 1 \
  --memory-mib 1024 \
  --detach
mactain container stats worker

For a heavier service, define a larger allocation up front:

mactain container create \
  --name postgres \
  --image docker.io/library/postgres:16 \
  --memory-mib 4096 \
  --cpus 4 \
  --env POSTGRES_PASSWORD=change-me \
  --mount type=volume,source=pg-data,target=/var/lib/postgresql/data
mactain container start postgres

Prefer explicit resources for databases, build runners, and services with known memory needs. Prefer defaults for first-run experiments and small stateless services.

Use case: keep a service running after Engine restarts

Use this for local services you expect to return automatically, such as a dev database, cache, or private registry. --restart controls process recovery; --autostart controls whether MacTain starts the container again after the Engine starts.

mactain container create \
  --name cache \
  --image docker.io/library/redis:7 \
  --autostart \
  --autostart-delay-seconds 10 \
  --restart unless-stopped \
  --memory-mib 1024
mactain container start cache

Use a delay when several services autostart and one depends on another service or on local DNS becoming available.

Use case: retain logs after the container exits

Use this for services where post-failure logs matter. Without persistent logging, use mactain container logs while the relevant runtime log is still available.

mactain container create \
  --name job-runner \
  --image ghcr.io/acme/job-runner:latest \
  --persistent-logging \
  --log-max-file-size-bytes 2000000 \
  --log-retained-files 4
mactain container start job-runner
mactain container logs job-runner --lines 200

The default retained log policy is 1000000 bytes per file and 5 retained files per stream when persistent logging is enabled.

Use case: give a workload custom DNS settings

Use this when a container must resolve names through a specific DNS server or search domain, for example on a VPN-connected development network.

mactain container create \
  --name internal-api \
  --image ghcr.io/acme/internal-api:latest \
  --dns 10.0.0.53 \
  --dns-search corp.example \
  --dns-opt ndots:1
mactain container start internal-api

Use Networking for service discovery between containers. Use per-container DNS settings only when the resolver itself must change.

Use case: allow Docker-compatible tools inside one container

Use this only when a workload inside the container needs Docker API compatibility. The default --docker-api-access none is the safest setting and should remain the normal choice.

mactain container create \
  --name ci-helper \
  --image ghcr.io/acme/ci-helper:latest \
  --docker-api-access read \
  --docker-api-socket-path /var/run/docker.sock
mactain container start ci-helper

Start with read for inventory-style tools. Use broader access only when the specific workload requires lifecycle operations and the risk is acceptable.

Use case: route one container through Secure Egress

Stop the container before assigning a saved VPN connection. In Container Settings, use the Secure Egress section, or assign it with the CLI:

mactain container stop qbittorrent
mactain container secure-egress assign qbittorrent \
  --connection media-vpn \
  --local-route-policy network_scopes \
  --json
mactain container start qbittorrent

See Secure Egress to create and test the VPN connection first, choose inbound-port behavior, and verify protection.

Use case: inspect a running workload before troubleshooting

Use this when a container starts but does not behave as expected. Start with status, inspect details, then logs.

mactain container status web
mactain container inspect web
mactain container logs web --lines 100

Start With One Container

Use Run your first container to create and start a simple standalone container before moving to Blueprints.

Troubleshooting Entry Points

  • If the image cannot be pulled, check registry access and Troubleshooting.
  • If a service is slow or exits under load, compare the default resource allocation with mactain container stats <name>.
  • If a container starts but the app is not reachable, review Networking.
  • If data disappears after a container is removed, review Volumes.
  • If host files are not visible in the container, check the bind mount source path and absolute container target.
  • If --env, --entrypoint, --command, or --args include sensitive values, use normal --json output for redaction and avoid --json-full unless you explicitly need full values.
  • If a Secure Egress container remains blocked, verify its saved VPN connection and follow Secure Egress troubleshooting.

Next Steps

Continue to Run your first container, then use Blueprints for repeatable workflows.

Related