# How to Create a Container Without Starting It Using `container create`

> Learn to create a container without starting it using the `container create` command. Initialize your container filesystem and configuration for later use.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-28

---

**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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/Sources/ContainerRuntime/Runtime.swift) and [`Sources/ContainerRuntime/ContainerSpec.swift`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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:

- `--name` to assign a unique identifier
- `--env` or `-e` for environment variables
- `--cpus` and `--memory` for resource constraints
- `--network` for network attachment
- `--init` to enable an init process for zombie reaping
- `--init-image` to specify a custom init image
- `--cap-add` and `--cap-drop` for Linux capability management

Error validation occurs before persistence, as verified in [`Tests/CLITests/Subcommands/Containers/TestCLICreate.swift`](https://github.com/apple/container/blob/main/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:

```bash

# 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 create` instead of `container run` to instantiate a container without spawning processes.
- The command persists a `ContainerSpec` defined in [`Sources/ContainerRuntime/ContainerSpec.swift`](https://github.com/apple/container/blob/main/Sources/ContainerRuntime/ContainerSpec.swift) to the local store, leaving the container in a **Created** state.
- No CPU or memory runtime overhead occurs until `container start` is invoked.
- All configuration flags supported by `container run` are available for pre-staging environment, resource, and network settings.
- Validation errors trigger `CLIError` exceptions 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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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.