Where to Find the Apple Container Source Code: CLI Commands Explained
The source code for Apple's container CLI commands is located in the apple/container GitHub repository, with the main entry point at Sources/CLI/ContainerCLI.swift and individual command implementations organized under Sources/ContainerCommands/.
Apple's container tool is a Swift-based command-line interface for managing containers on macOS. The entire codebase is open-sourced under the apple/container repository and follows a clean, modular architecture that separates argument parsing, command logic, and API communication into distinct layers.
Architecture Overview
The repository organizes functionality into three primary layers, each with specific responsibilities and source file locations.
CLI Entry Point (Sources/CLI/ContainerCLI.swift): This file handles the initial argument parsing using Apple's ArgumentParser library. It constructs an Application instance from the ContainerCommands package and executes Application.main() to dispatch control to the appropriate subcommand.
Command Definitions (Sources/ContainerCommands/*): Each top-level subcommand—such as run, build, image, machine, and system—is implemented as a Swift struct conforming to the ParsableCommand protocol. These structs declare their arguments, options, and configuration metadata that automatically generates help text.
API Client (Sources/ContainerAPIClient/*): This layer manages low-level gRPC and HTTP communications with the container runtime daemon. When a command's run() method executes, it ultimately calls into this client to perform actions like creating containers, pulling images, or managing container machines.
Key Source File Locations
Entry Point and Dispatch
The primary entry point is Sources/CLI/ContainerCLI.swift. This file contains the main() function that parses raw command-line arguments and builds the command hierarchy. It relies on the ContainerCommands Swift package to instantiate the command tree before execution begins.
Command Implementations
Individual commands reside in Sources/ContainerCommands/ with logical grouping by function:
- Core commands (
Sources/ContainerCommands/Core/): IncludesRunCommand.swift,BuildCommand.swift, and other primary container operations. - Image management (
Sources/ContainerCommands/Image/): Contains subcommands forpull,push,list, and image inspection. - Machine operations (
Sources/ContainerCommands/Machine/): Handles virtual machine lifecycle management for the container runtime. - System utilities (
Sources/ContainerCommands/System/): Provides system-level information and configuration commands.
Each file exports a struct that implements the run() method, which bridges the parsed arguments to the ContainerAPIClient for daemon communication.
Supporting Files
- Documentation:
docs/command-reference.mdmirrors the source code hierarchy and provides human-readable command references. - Tests:
Tests/IntegrationTests/contains end-to-end tests that exercise the CLI commands against live container operations. - Package Manifest:
Package.swiftdefines the Swift package targets forContainerCLI,ContainerCommands, andContainerAPIClient.
Working with the Source Code
Running Commands Programmatically
You can invoke commands directly from Swift code by importing the ContainerCommands and ContainerAPIClient modules:
import ContainerAPIClient
import ContainerCommands
@main
struct RunExample {
static func main() async throws {
let args = ["run", "-it", "--name", "my-shell", "ubuntu:latest", "/bin/bash"]
var app = try Application.parse(args)
try await app.run()
}
}
This pattern mirrors the execution flow in ContainerCLI.swift, where arguments are parsed into the Application hierarchy before invoking the runtime daemon through ContainerAPIClient.
Adding Custom Subcommands
To extend the CLI with custom functionality, create a new ParsableCommand struct in the ContainerCommands package:
import ArgumentParser
import ContainerAPIClient
struct MyCustomCommand: AsyncParsableCommand {
static let configuration = CommandConfiguration(
commandName: "mycmd",
abstract: "A demo custom command."
)
@Option(name: .shortAndLong, help: "An example integer option.")
var number: Int = 0
func run() async throws {
print("Custom command invoked with number = \(number)")
}
}
Register this command in Sources/ContainerCommands/CommandRegistry.swift to include it in the Application's command tree.
Terminal Usage Mapping
User-facing commands map directly to the Swift source structures:
# Pull an image (maps to Image/PullCommand.swift)
container image pull alpine:latest
# Run a container (maps to Core/RunCommand.swift)
container run -it --name demo alpine:latest /bin/sh
The --help output for each command is generated automatically from the CommandConfiguration metadata defined in each command struct.
Summary
- The entry point for all container commands is
Sources/CLI/ContainerCLI.swift. - Command implementations live in
Sources/ContainerCommands/organized by functional area (Core, Image, Machine, System). - The API client layer at
Sources/ContainerAPIClient/handles daemon communication via gRPC/HTTP. - Commands are implemented as Swift structs conforming to
ParsableCommandfrom Apple's ArgumentParser framework. - The repository includes comprehensive integration tests at
Tests/IntegrationTests/and documentation atdocs/command-reference.md.
Frequently Asked Questions
What programming language is the container CLI written in?
The Apple container tool is written entirely in Swift. It leverages Apple's ArgumentParser library for command-line parsing and uses Swift's async/await patterns for non-blocking communication with the container daemon.
Where is the exact file that handles the container run command?
The run subcommand is implemented in Sources/ContainerCommands/Core/RunCommand.swift. This file defines a struct (typically named RunCommand) that conforms to ParsableCommand, declares the accepted arguments and flags, and implements the run() method that coordinates with ContainerAPIClient to create and start the container.
How are subcommands organized in the repository?
Subcommands are organized hierarchically under Sources/ContainerCommands/ with subdirectories matching the command structure. For example, container image pull maps to Sources/ContainerCommands/Image/PullCommand.swift, while container machine operations reside in Sources/ContainerCommands/Machine/. This structure makes it easy to locate specific functionality when browsing the source.
Can I extend the container CLI with my own custom commands?
Yes. You can create custom commands by implementing the ParsableCommand protocol in a new Swift file within the ContainerCommands package. After defining your command's configuration, arguments, and run() method, you must register it in Sources/ContainerCommands/CommandRegistry.swift to include it in the Application's command hierarchy. The existing commands in Sources/ContainerCommands/Core/ provide working templates for implementation.
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 →