How to Create a Container Without Starting It Using `container create`
To create a container without starting it, use the container create command followed by your image reference, which initializes the container filesystem and configuration while keeping the process in a Created state until you explicitly invoke container start.
The apple/container framework provides a distinct lifecycle phase for container initialization that separates resource allocation from process execution. Unlike container run, which immediately spawns a process, the container create command allows you to create a container without starting it, enabling pre-staging, configuration validation, and resource preparation without runtime overhead.
How container create Works in the Apple Container Framework
According to the source code in Sources/CLI/ContainerCreateCommand.swift, the container create subcommand parses user arguments through Swift ArgumentParser, resolves the image reference, and constructs a ContainerSpec object. This specification captures all configuration parameters—including environment variables, resource limits, and network settings—before persisting the container to the local store.
The runtime implementation, found in Sources/ContainerRuntime/Runtime.swift and Sources/ContainerRuntime/ContainerSpec.swift, materializes the ContainerSpec into a persisted container object. During this phase, the system allocates the filesystem and metadata storage but explicitly avoids calling exec or spawning any init process. This leaves the container in a Created state, as documented in docs/command-reference.md.
Key Differences Between container create and container run
While both commands accept identical flags for process, resource, and network configuration, they diverge at the execution boundary.
Resource consumption is the primary distinction: container create does not consume CPU or memory beyond the minimal footprint required to persist the container state, whereas container run immediately allocates runtime resources and begins process execution.
Lifecycle flexibility represents another critical difference. After creation, you can inspect the container with container inspect, modify its configuration (such as adding mounts), or stage multiple containers for batch initialization. The container remains dormant until explicitly activated via container start, allowing for surgical control over initialization timing.
Supported Flags and Configuration Options
The container create command mirrors the flag interface of container run, supporting all standard configuration options. Validated parameters include:
--nameto assign a unique identifier--envor-efor environment variables--cpusand--memoryfor resource constraints--networkfor network attachment--initto enable an init process for zombie reaping--init-imageto specify a custom init image--cap-addand--cap-dropfor Linux capability management
Error validation occurs before persistence, as verified in Tests/CLITests/Subcommands/Containers/TestCLICreate.swift. Invalid configurations—such as exceeding maximum published ports or referencing unknown init images—trigger a CLIError and abort the creation process without leaving partial state.
Practical Examples for Creating Containers Without Starting
These runnable examples demonstrate common patterns for staging containers:
# Basic creation with explicit naming
container create --name my-container ubuntu:latest
# Creation with environment variables and resource constraints
container create \
--name web-svc \
-e NODE_ENV=production \
--cpus 2 \
--memory 1G \
nginx:latest
# Using an init process for proper signal handling
container create --init --name app-with-init alpine:latest
# Specifying a custom init image for VM-level boot customization
container create --init-image my-custom-init:latest --name custom-init-test ubuntu:latest
# Starting the container when ready
container start my-container
Summary
- Use
container createinstead ofcontainer runto instantiate a container without spawning processes. - The command persists a
ContainerSpecdefined inSources/ContainerRuntime/ContainerSpec.swiftto the local store, leaving the container in a Created state. - No CPU or memory runtime overhead occurs until
container startis invoked. - All configuration flags supported by
container runare available for pre-staging environment, resource, and network settings. - Validation errors trigger
CLIErrorexceptions before any persistence occurs, ensuring atomic creation semantics.
Frequently Asked Questions
Can I modify a container after creating it but before starting it?
Yes. Because container create persists the container configuration without spawning a process, you can use container inspect to review the current configuration and modify parameters such as mounts or network attachments before invoking container start. This allows for iterative configuration refinement without runtime side effects.
Does container create consume significant system resources?
No. According to the implementation in Sources/ContainerRuntime/Runtime.swift, the creation process only allocates storage for the filesystem and metadata. The container does not consume CPU cycles or memory beyond its persisted state representation, making it suitable for pre-staging large numbers of containers without runtime overhead.
What happens if I provide an invalid image reference to container create?
The command validates the image reference during the resolution phase in Sources/CLI/ContainerCreateCommand.swift. If the image cannot be found or the reference is malformed, the CLI returns a CLIError and aborts immediately without creating partial container state, as verified by the test suite in Tests/CLITests/Subcommands/Containers/TestCLICreate.swift.
How do I check if a container was created successfully without starting it?
Use the container inspect command followed by the container name or ID. A successfully created container will display a status of Created in the output, along with the full ContainerSpec configuration including image reference, environment variables, and resource limits defined during the container create invocation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →