How to Set Up a Development Environment for apple/container: Complete Guide
To set up a development environment for apple/container, you need an Apple Silicon Mac running macOS 15 or later with Xcode 26 and Swift 6.2 installed, then clone the repository alongside its sibling containerization package and run make APP_ROOT=test-data all test integration to build the project and verify functionality.
The apple/container repository provides a Swift-based command-line tool that runs OCI-compatible containers as lightweight VM-based sandboxes on Apple Silicon Macs. Setting up a proper development environment requires specific hardware, toolchain versions, and a particular directory layout when working with dependencies. This guide covers the complete setup process using the actual build configuration from Package.swift and Makefile in the source tree.
Prerequisites for apple/container Development
Hardware and Operating System Requirements
Developing apple/container requires specific Apple hardware and recent macOS versions:
- Apple Silicon (M1, M2, M3, or M4 chips) is mandatory; Intel Macs are not supported
- macOS 15 minimum; macOS 26 is recommended according to the README requirements
- Standard development tools (
make,git,bash) available on macOS by default
Xcode and Swift Toolchain Setup
The project requires modern Apple development tools:
- Xcode 26 must be set as the active developer directory
- Swift 6.2 as declared in the
Package.swiftmanifest - Command-line tools configured via
xcode-select
Set the active developer directory:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
Verify your Swift version matches the requirement:
swift --version # Should display Swift 6.2
Optional Dependencies for Protocol Buffer Development
If you plan to regenerate gRPC code or modify protocol definitions, install additional tools via Homebrew:
brew install protobuf grpc swift-protobuf
Clone the Repository and Dependencies
Basic Repository Clone
Start by cloning the main container repository:
git clone https://github.com/apple/container.git
cd container
Side-by-Side Layout for Local Development
The apple/container project depends on the containerization package (referenced in Package.swift as https://github.com/apple/containerization.git). To enable simultaneous development on both projects, clone them side-by-side:
cd ..
git clone https://github.com/apple/containerization.git
Your directory structure should look like:
~/projects/
├── container/
└── containerization/
This layout is required because the build scripts in BUILDING.md assume the sibling directory structure when you edit the low-level containerization code locally.
Build the Project with Swift Package Manager
Using the Makefile Wrapper
The repository includes a Makefile that wraps Swift Package Manager commands. The standard development workflow uses the following targets:
# Clean previous build artifacts
make clean
# Build all binaries and run tests with isolated test data
make APP_ROOT=test-data all test integration
The APP_ROOT=test-data environment variable forces services to use an isolated directory, preventing modifications to real user data. The all target builds binaries into bin/ and libexec/, while test runs unit tests and integration runs the integration suite.
Release Configuration Builds
For production-optimized binaries:
BUILD_CONFIGURATION=release make all
System-Wide Installation
Install the built binaries to system directories:
sudo make install
This places the container command-line tool in your system path.
Run the Container System Locally
Start the Container Daemon
After building, start the container system:
bin/container system start
Execute Container Commands
Run a test container to verify the system:
bin/container run -d --name hello debian:bookworm echo "Hello, world!"
Stop the System
When finished testing, stop the daemon:
bin/container system stop
Advanced Development Workflows
Develop Using a Local Copy of Containerization
When modifying low-level container primitives in the sibling repository:
- Ensure both repositories are in the side-by-side layout described above
- Edit the dependency in
Package.swiftor use Swift Package Manager commands:
/usr/bin/swift package edit --path ../containerization containerization
/usr/bin/swift package update containerization
- Rebuild with
make clean all
To revert to the remote dependency later:
swift package unedit containerization
Debug XPC Helpers
The Sources/Plugins/RuntimeLinux/ directory contains XPC helpers that implement the Linux runtime inside a VM. To debug these helpers, set the environment variable:
export CONTAINER_DEBUG_LAUNCHD_LABEL=com.apple.container.container-runtime-linux.test
bin/container system start
The helper will pause waiting for a debugger attachment, as documented in BUILDING.md.
Pre-Commit Hooks
Install formatting and license header checks before committing:
make pre-commit
This configures git hooks that run swift-format and enforce license headers before each commit.
Summary
- Hardware requirement: Apple Silicon Mac with macOS 15+ is mandatory; Xcode 26 and Swift 6.2 are required as specified in
Package.swift - Repository layout: Clone
apple/containerand optionallyapple/containerizationside-by-side for local dependency development - Build command: Use
make APP_ROOT=test-data all test integrationto build binaries and verify functionality - Installation: Run
sudo make installto install system-wide, or execute directly frombin/ - Development workflow: Use
swift package editto work with local copies of dependencies, and setCONTAINER_DEBUG_LAUNCHD_LABELto debug XPC helpers
Frequently Asked Questions
Can I develop apple/container on an Intel Mac?
No. The apple/container repository requires Apple Silicon (M1/M2/M3/M4) as explicitly stated in the README requirements section. The codebase relies on ARM64-specific virtualization features available only on Apple Silicon Macs.
Why do I need to clone the containerization repository separately?
While Package.swift references the remote containerization dependency by URL, placing both repositories side-by-side enables local development workflows. This layout allows you to use swift package edit to test changes across both projects simultaneously, which is necessary when modifying low-level primitives in Sources/Plugins/RuntimeLinux/ or related components.
How do I switch between debug and release builds?
Set the BUILD_CONFIGURATION environment variable before running make. For debug builds (default), use make all. For release-optimized builds, run BUILD_CONFIGURATION=release make all. The Makefile passes this variable to the Swift Package Manager to compile with appropriate optimizations.
Where are the built binaries located after compilation?
The Makefile places executables in the bin/ and libexec/ directories at the repository root. The main CLI entry point is at bin/container, which corresponds to the source code in Sources/CLI/ContainerCLI.swift. You can run these binaries directly or install them system-wide using sudo make install.
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 →