Corrections and refinements for user documentation. (#35)

This commit is contained in:
J Logan
2025-06-07 21:00:47 -07:00
committed by GitHub
parent 7020082723
commit 6690f6d076
6 changed files with 48 additions and 47 deletions
+8 -8
View File
@@ -1,9 +1,9 @@
# Building the project
To build the Containerization package, your system needs either:
To build the `container` project, your system needs either:
- macOS 15 or newer and Xcode 17 beta.
- macOS 16 Developer Preview.
- macOS Sequoia 15 or newer and Xcode 17 beta.
- macOS Developer Preview.
## Compile and test
@@ -39,7 +39,7 @@ To make changes to `container` that require changes to the Containerization proj
cd container
```
3. If the application services are already running, stop them.
3. If the `container` services are already running, stop them.
```
bin/container system stop
@@ -52,10 +52,10 @@ To make changes to `container` that require changes to the Containerization proj
swift package update containerization
```
5. Build the init filesystem for your local copy of containerization.
5. Build the init filesystem for your local copy of the Containerization project.
```
(cd ../swiftcontainerization && make clean all)
(cd ${CONTAINERIZATION_PATH} && make clean all)
```
6. Build `container`.
@@ -64,7 +64,7 @@ To make changes to `container` that require changes to the Containerization proj
make clean all
```
7. Start the application services.
7. Start the `container` services.
```
bin/container system start
@@ -85,7 +85,7 @@ To revert to using the Containerization dependency from your `Package.swift`:
make clean all
```
3. Restart application services.
3. Restart the `container` services.
```
bin/container system restart
+12 -12
View File
@@ -1,25 +1,25 @@
# `container`
`container` is an application that you can use to create and run Linux containers as lightweight virtual machines on your Mac. It's written in Swift, and optimized for Apple silicon.
`container` is a tool that you can use to create and run Linux containers as lightweight virtual machines on your Mac. It's written in Swift, and optimized for Apple silicon.
The application consumes and produces OCI-compliant container images, so you can pull and run images from any standard container registry. You can push images that you build to those registries as well, and run the images in any other OCI-compliant application.
The tool consumes and produces OCI-compliant container images, so you can pull and run images from any standard container registry. You can push images that you build to those registries as well, and run the images in any other OCI-compliant application.
`container` uses the [Containerization](https://github.com/apple/containerization) Swift package for low level container, image and process management.
`container` uses the [Containerization](https://github.com/apple/containerization) Swift package for low level container, image, and process management.
![introductory movie showing some basic commands](./docs/assets/landing-movie.gif)
## Get started
Install the `container` application on your Mac.
Install `container` on your Mac.
### Requirements
You need an Apple silicon Mac to run `container`. To build the application, see the [BUILDING](./BUILDING.md) document.
You need an Apple silicon Mac to run `container`. To build it, see the [BUILDING](./BUILDING.md) document.
`container` is designed to take advantage of the features of the macOS 16 Developer Preview. You can run the application on macOS Sequoia, but the `container` maintainers typically will not address Sequoia issues that cannot be reproduced on the macOS 16 Developer Preview.
`container` is designed to use the new features in the macOS Developer Preview. You can run the tool on macOS Sequoia 15, but the `container` maintainers typically will not address issues discovered on macOS Sequoia 15 that cannot be reproduced on the macOS Developer Preview.
There are [significant networking limitations](https://github.com/apple/container#macos-sequoia-limitations) that impact the usability `container` on macOS Sequoia.
There are [significant networking limitations](/docs/technical-overview.md#macos-sequoia-15-limitations) that impact the usability `container` on macOS Sequoia 15.
### Install or upgrade
@@ -29,13 +29,13 @@ If you're upgrading, first uninstall your existing `container` while preserving
uninstall-container.sh -k
```
Download the latest application installer package from the [Github release page](https://github.com/apple/container/releases).
Download the latest installer package for `container` from the [Github release page](https://github.com/apple/container/releases).
To install the application, double click the package file and follow the instructions. Enter your administrator password when prompted to give the installer permission to place the application under `/usr/local`.
To install the tool, double click the package file and follow the instructions. Enter your administrator password when prompted, to give the installer permission to place the installed files under `/usr/local`.
### Uninstall
Use the `uninstall-container.sh` script to remove the application from your system. To remove your user data along with the application, run:
Use the `uninstall-container.sh` script to remove `container` from your system. To remove your user data along with the tool, run:
```bash
uninstall-container.sh -d
@@ -52,8 +52,8 @@ uninstall-container.sh -k
- Take [a guided tour of `container`](./docs/tutorial.md) by building, running, and publishing a simple web server image.
- Learn how to [use various `container` features](./docs/how-to.md).
- Read a brief description and [technical overview](./docs/technical-overview.md) of `container`.
- View the project [API documentation](https://pages.github.com/apple/container/).
## Contributing
Contributions to Containerization are welcomed and encouraged. Please see our [main contributing guide](https://github.com/apple/containerization/blob/main/CONTRIBUTING.md) for more information.
Contributions to `container` are welcomed and encouraged. Please see our [main contributing guide](https://github.com/apple/containerization/blob/main/CONTRIBUTING.md) for more information.
+6 -6
View File
@@ -4,7 +4,7 @@ How to use the features of `container`.
## Configure memory and CPUs for your containers
Since the containers created by `container` are lightweight virtual machines, you need to consider the needs of your containerized application when you `container run` a container. The `--memory` and `--cpus` options allow you to override the default memory and CPU limits for the virtual machine. The default values are 1 gigabyte of RAM and 4 CPUs. You can use abbreviations for memory units; for example, to run a container for image `big` with 8 CPUs and 32 gigabytes of memory, use:
Since the containers created by `container` are lightweight virtual machines, consider the needs of your containerized application when you use `container run`. The `--memory` and `--cpus` options allow you to override the default memory and CPU limits for the virtual machine. The default values are 1 gigabyte of RAM and 4 CPUs. You can use abbreviations for memory units; for example, to run a container for image `big` with 8 CPUs and 32 gigabytes of memory, use:
```bash
container run --rm --cpus 8 --memory 32g big
@@ -12,7 +12,7 @@ container run --rm --cpus 8 --memory 32g big
## Configure memory and CPUs for large builds
When you first run `container build`, `container` starts a *builder*, which is a utility container that performs image build. As with anything you run with `container run`, the builder runs in a lightweight virtual machine, so for resource-intensive builds, you may need to increase the memory and CPU limits for the builder VM.
When you first run `container build`, `container` starts a *builder*, which is a utility container that builds images from your `Dockerfile`s. As with anything you run with `container run`, the builder runs in a lightweight virtual machine, so for resource-intensive builds, you may need to increase the memory and CPU limits for the builder VM.
By default, the builder VM receives 2 gigabytes of RAM and 2 CPUs. You can change these limits by starting the builder container before running `container build`:
@@ -46,7 +46,7 @@ total 4
The argument to `--volume` in the example consists of the full pathname for the host folder and the full pathname for the mount point in the container, separated by a colon.
The `--mount` option uses a comma separated `key=value` syntax to achieve the same result:
The `--mount` option uses a comma-separated `key=value` syntax to achieve the same result:
```shellsession
% container run --mount source=${HOME}/Desktop/assets,target=/content/assets docker.io/python:slim ls -l /content/assets
@@ -57,9 +57,9 @@ total 4
## Build and run a multiplatform image
Using the [project from the tutorial example](/documentation/tutorial/#set-up-a-simple-project), you can create an image to use both on Apple Silicon Macs and on AMD64 servers.
Using the [project from the tutorial example](/documentation/tutorial/#set-up-a-simple-project), you can create an image to use both on Apple silicon Macs and on x86-64 servers.
When building the image, just add `--arch` options that directs the builder to create an image supporting both the `arm64` and `amd64` architectures:
When building the image, just add `--arch` options that direct the builder to create an image supporting both the `arm64` and `amd64` architectures:
```bash
container build --arch arm64 --arch amd64 --tag registry.example.com/fido/web-test:latest --file Dockerfile .
@@ -73,7 +73,7 @@ Linux 7932ce5f-ec10-4fbe-a2dc-f29129a86b64 6.1.68 #1 SMP Mon Mar 31 18:27:51 UTC
%
```
When you run the command with the `amd64` architecture, the AMD64 version of `uname` of Python using Rosetta translation, so that you will see information for an AMD64 system:
When you run the command with the `amd64` architecture, the x86-64 version of `uname` runs under Rosetta translation, so that you will see information for an x86-64 system:
```shellsession
container run --arch amd64 --rm registry.example.com/fido/web-test:latest uname -a
+17 -16
View File
@@ -8,9 +8,9 @@ Containers are a way to package an application and its dependencies into a singl
Containerization is an important server-side technology that is used throughout the software lifecycle:
- Backend developers use containers on their personal systems to create predictable execution environments for applications, and to develop and test their applications under conditions that better approximate how it runs in the datacenter.
- Backend developers use containers on their personal systems to create predictable execution environments for applications, and to develop and test their applications under conditions that better approximate how they would run in the datacenter.
- Continuous integration and deployment (CI/CD) systems use containerization to perform reproducible builds of applications, package the results as deployable images, and deploy them to the datacenter.
- Datacenters run container orchestration platforms that use the images to run containerized applications in a reliable, highly available computing cluster.
- Datacenters run container orchestration platforms that use the images to run containerized applications in a reliable, highly available compute cluster.
None of this workflow would be practical without ensuring interoperability between different container implementations. The Open Container Initiative (OCI) creates and maintains these standards for container images and runtimes.
@@ -18,7 +18,7 @@ None of this workflow would be practical without ensuring interoperability betwe
Many operating systems support containers, but the most commonly encountered containers are those that run on the Linux operating system. On macOS, the typical way to run Linux containers is to launch a Linux virtual machine (VM) that hosts all of your containers.
`container` runs containers differently. Using the open source Containerization library, it runs a lightweight VM for each container that you create. This approach has the following properties:
`container` runs containers differently. Using the open source [Containerization](https://github.com/apple/containerization) package, it runs a lightweight VM for each container that you create. This approach has the following properties:
- Security: Each container has the isolation properties of a full VM, using a minimal set of core utilities and dynamic libraries to reduce resource utilization and attack surface.
- Privacy: When sharing host data using `container`, you mount only necessary data into each VM. With a shared VM, you need to mount all data that you may ever want to use into the VM, so that it can be mounted selectively into containers.
@@ -26,21 +26,22 @@ Many operating systems support containers, but the most commonly encountered con
Since `container` consumes and produces standard OCI images, you can easily build with and run images produced by other container applications, and the images that you build will run everywhere.
`container` and the underlying Containerization library integrate with many of the key technologies and frameworks of macOS:
`container` and the underlying Containerization package integrate with many of the key technologies and frameworks of macOS:
- The Virtualization framework for managing Linux virtual machines and their attached devices.
- The vmnet framework for managing the virtual network to which the containers attach.
- XPC for interprocess communication.
- Launchd for service management.
- Keychain services for access to registry credentials.
- The unified logging system for application logging.
You use the `container` command line interface (CLI) to start and manage your containers, build container images, and transfer images from and to OCI container registries. The CLI uses a client library that communicates with `container-apiserver` and its helpers.
The process `container-apiserver` is a launch agent that launches when you run the `container system start` command, and terminates when you run `container system stop`. It provides the client APIs for managing container, and network resources.
The `container-apiserver` is a launch agent that launches when you run the `container system start` command, and terminates when you run `container system stop`. It provides the client APIs for managing container and network resources.
When `container-apiserver` starts, it launches an XPC helper `container-core-images` that exposes an API for image management and manages the local content store, and another XPC helper `container-network-vmnet` for the virtual network. For each container that you create, `container-apiserver` launches a container runtime helper `container-runtime-linux` that exposes the management API for that specific container.
![diagram showing application functional organization](/docs/assets/functional-model-light.svg)
![diagram showing `container` functional organization](/docs/assets/functional-model-light.svg)
## What limitations does `container` have today?
@@ -48,11 +49,11 @@ With the initial release of `container`, you get basic facilities for building a
### Container to host networking
In the initial release, there is no way to route traffic directly from a client in a container to an host-based application listening on the loopback loopback interface at 127.0.0.1. If you were to configure the application in your container to connect to 127.0.0.1 or `localhost`, requests will simply go to the loopback interface in the container, and not to your host-based service.
In the initial release, there is no way to route traffic directly from a client in a container to an host-based application listening on the loopback interface at 127.0.0.1. If you were to configure the application in your container to connect to 127.0.0.1 or `localhost`, requests would simply go to the loopback interface in the container, rather than your host-based service.
You can work around this limitation configuring the host-based application to listen on the wildcard address 0.0.0.0, but this practice is insecure and not recommended because, without firewall rules, this opens up the application to external clients.
You can work around this limitation by configuring the host-based application to listen on the wildcard address 0.0.0.0, but this practice is insecure and not recommended because, without firewall rules, this exposes the application to external requests.
A more secure approach is to use `socat` to redirect traffic from the container network gateway to the host-based service. For example, to forward traffic for port 8000, configure your containerized application to connect to `192.68.64.1:8000` instead of `127.0.0.1:8000`, and then run the following command in a terminal on your Mac to forward the port traffic from the gateway to the host:
A more secure approach uses `socat` to redirect traffic from the container network gateway to the host-based service. For example, to forward traffic for port 8000, configure your containerized application to connect to `192.68.64.1:8000` instead of `127.0.0.1:8000`, and then run the following command in a terminal on your Mac to forward the port traffic from the gateway to the host:
```bash
socat TCP-LISTEN:8000,fork,bind=192.168.64.1 TCP:127.0.0.1:8000
@@ -60,23 +61,23 @@ socat TCP-LISTEN:8000,fork,bind=192.168.64.1 TCP:127.0.0.1:8000
### Releasing container memory to macOS
The macOS Virtualization framework implements only partial support for memory ballooning, which is a technology that allows virtual machines to dynamically receive and relinquish memory from the host. When you create a container, the underlying virtual machine only uses the amount of memory that the containerized application needs. So you might start a container using the option `--memory 16g`, but see that the application is only using 2 gigabytes of system memory.
The macOS Virtualization framework implements only partial support for memory ballooning, which is a technology that allows virtual machines to dynamically use and relinquish host memory. When you create a container, the underlying virtual machine only uses the amount of memory that the containerized application needs. For example, you might start a container using the option `--memory 16g`, but see that the application is only using 2 gigabytes of RAM in the macOS Activity Monitor.
The current limitation, however, is that memory pages freed by the application to Linux in the container cannot be relinquished to the host. If you run many memory-intensive containers, you may need to occasionally restart them to reduce memory utilization.
Currently, memory pages freed to the Linux operating system by processes running in the container's VM are not relinquished to the host. If you run many memory-intensive containers, you may need to occasionally restart them to reduce memory utilization.
### macOS Sequoia limitations
### macOS Sequoia 15 limitations
`container` relies on the new features and enhancements present in the macOS 16 Developer Preview. You can run `container` on macOS Sequoia, but you will need to be aware of some user experience quirks and functional limitations. There is no plan to address issues found on Sequoia that cannot be reproduced in the Developer Preview.
`container` relies on the new features and enhancements present in the macOS Developer Preview. You can run `container` on macOS Sequoia 15, but you will need to be aware of some user experience quirks and functional limitations. There is no plan to address issues found with macOS Sequoia 15 that cannot be reproduced in the macOS Developer Preview.
#### Network isolation
The vmnet framework in Sequoia can only provide networks where the attached containers are isolated from one another. Container-to-container communication over the virtual network is not possible.
The vmnet framework in macOS Sequoia 15 can only provide networks where the attached containers are isolated from one another. Container-to-container communication over the virtual network is not possible.
#### Container IP addresses
In Sequoia, limitations in the vmnet framework mean that the container network can only be created when the first container starts. Since the network XPC helper provides IP addresses to containers, and the helper has to start before the first container, it is possible for the network helper and vmnet to disagree on the subnet address, resulting in containers that are completely cut off from the network.
In macOS Sequoia 15, limitations in the vmnet framework mean that the container network can only be created when the first container starts. Since the network XPC helper provides IP addresses to containers, and the helper has to start before the first container, it is possible for the network helper and vmnet to disagree on the subnet address, resulting in containers that are completely cut off from the network.
Normally, vmnet creates the container network using the CIDR address 192.168.64.1/24, and on Sequoia, `container` defaults to using this CIDR address in the network helper. To diagnose and resolve issues where due to disagreement between vmnet and the network helper:
Normally, vmnet creates the container network using the CIDR address 192.168.64.1/24, and on macOS Sequoia 15, `container` defaults to using this CIDR address in the network helper. To diagnose and resolve issues stemming from a subnet address mismatch between vmnet and the network helper:
- Before creating the first container, scan the output of the command `ifconfig` for all bridge interface named similarly to `bridge100`.
- After creating the first container, run `ifconfig` again, and locate the new bridge interface to determine container the subnet address.
+4 -4
View File
@@ -142,7 +142,7 @@ The `RUN` line creates a simple HTML landing page named `/content/index.html`.
The `CMD` line configures the container to run a simple web server in Python on port 80. Since the working directory is `/content`, the web server runs in that directory and delivers the content of the file `/content/index.html` when a user requests the index page URL.
The server binds to the wildcard address `0.0.0.0` to allow connections from the host and other containers. To ensure security, the virtual network used by the containers is not accessible by external systems.
The server listens on the wildcard address `0.0.0.0` to allow connections from the host and other containers. You can safely use the listen address `0.0.0.0` inside the container, because external systems have no access to the virtual network to which the container attaches.
### Build the web server image
@@ -183,7 +183,7 @@ When you list containers now, `my-web-server` is present, along with the contain
```shellsession
% container ls
ID IMAGE OS ARCH STATE ADDR
buildkit ghcr.io/apple/container-builder-shim/builder:2.1.1 linux arm64 running 192.168.64.2
buildkit ghcr.io/apple/container-builder-shim/builder:2.1.1 linux arm64 running 192.168.64.2
my-web-server web-test:latest linux arm64 running 192.168.64.3
%
```
@@ -220,10 +220,10 @@ index.html logo.jpg
root@my-web-server:/content# uname -a
Linux my-web-server 6.1.68 #1 SMP Mon Mar 31 18:27:51 UTC 2025 aarch64 GNU/Linux
root@my-web-server:/content# exit
exit%
%
```
The `--tty` and `--interactive` flag allow you to interact with the shell from your host terminal. The `--tty` flag tells the shell in the container that its input is a terminal device, and the `--interacive` flag connects what you input in your host terminal to the input of the shell in the container.
The `--tty` and `--interactive` flag allow you to interact with the shell from your host terminal. The `--tty` flag tells the shell in the container that its input is a terminal device, and the `--interactive` flag connects what you input in your host terminal to the input of the shell in the container.
You will often see these two options abbreviated and specified together as `-ti` or `-it`.
+1 -1
View File
@@ -75,7 +75,7 @@ for ((i=${#DIRS[@]}-1; i>=0; i--)); do
done
sudo pkgutil --forget com.apple.container-installer > /dev/null
echo 'Removed `container` application'
echo 'Removed `container` tool and helpers'
if [ "$DELETE_DATA" = true ]; then
echo 'Removing `container` user data'