Skip to content

Commit a9ff9f3

Browse files
committed
docs: restructure how-to.md into focused topic pages
how-to.md had become a catch-all with no way to discover it beyond README's single link to it. Split its remaining sections into topic pages (resource usage, host integration, logs, multiplatform images, runtime configuration, inspection, shell completions), merge tmpfs into volumes.md as "Mounts and volumes", and move system-properties docs into container-system-config.md. how-to.md itself becomes a short index. README also gains a minimal "Run your first container" step before "Next steps". Signed-off-by: Eric Ernst <eric_ernst@apple.com>
1 parent a39525d commit a9ff9f3

13 files changed

Lines changed: 872 additions & 657 deletions

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ Start the system service with:
3131
container system start
3232
```
3333

34+
### Run your first container
35+
36+
```bash
37+
container run --rm alpine echo hello
38+
```
39+
40+
This pulls the `alpine` image, runs it in a lightweight Linux VM, prints `hello`, and
41+
removes the container when it exits. See the [tutorial](./docs/tutorials/start-here.md)
42+
for a fuller walkthrough that builds and publishes an image of your own.
43+
3444
### Upgrade or downgrade
3545

3646
For both upgrading and downgrading, you can manually download and install the signed installer package by following the steps from [initial install](#initial-install) or use the `update-container.sh` script (installed to `/usr/local/bin`).

docs/container-inspection.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Inspecting containers and images
2+
3+
Get detailed, machine-readable information about your containers and images.
4+
5+
## Get container or image details
6+
7+
`container image list` and `container list` provide basic information for all of your images and containers. You can also use `list` and `inspect` commands to print detailed machine-readable output for resources.
8+
9+
Use the `inspect` command and send the result to the `jq` command to get pretty-printed JSON for the images or containers that you specify:
10+
11+
<pre>
12+
% container image inspect web-test | jq
13+
[
14+
{
15+
"configuration": {
16+
"name": "web-test:latest",
17+
...
18+
},
19+
"variants": [
20+
{
21+
"platform": {
22+
"os": "linux",
23+
"architecture": "arm64"
24+
},
25+
"config": {
26+
"created": "2025-05-08T22:27:23Z",
27+
"architecture": "arm64",
28+
...
29+
% container inspect my-web-server | jq
30+
[
31+
{
32+
"configuration": {
33+
"mounts": [],
34+
"id": "my-web-server",
35+
"resources": {
36+
"cpus": 4,
37+
"memoryInBytes": 1073741824,
38+
},
39+
...
40+
},
41+
"status": {
42+
"state": "running",
43+
"networks": [
44+
{
45+
"ipv4Address": "192.168.64.3/24",
46+
"ipv4Gateway": "192.168.64.1",
47+
"hostname": "my-web-server.test.",
48+
"network": "default"
49+
}
50+
],
51+
...
52+
}
53+
}
54+
]
55+
</pre>
56+
57+
Use the `list` command with the `--format` option to display information for all images or containers. In this example, the `--all` option shows stopped as well as running containers, and `jq` selects the IP address for each running container:
58+
59+
<pre>
60+
% container ls --format json --all | jq '.[] | select ( .status.state == "running" ) | [ .configuration.id, .status.networks[0].ipv4Address ]'
61+
[
62+
"my-web-server",
63+
"192.168.64.3/24"
64+
]
65+
[
66+
"buildkit",
67+
"192.168.64.2/24"
68+
]
69+
</pre>
70+
71+
See [Networking](./networking.md) for how to publish ports, reach the host from a
72+
container, set a custom MAC address, and create isolated networks.

docs/container-system-config.md

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,43 @@ For a guided walk-through on setting default values, see [Container system confi
99

1010
Source of truth: [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](../Sources/ContainerPersistence/ContainerSystemConfig.swift).
1111

12+
## Viewing your configuration
13+
14+
Use `container system property list` (alias `ls`) to print the merged configuration
15+
the `container` service is actually using — combining your `config.toml` with
16+
hardcoded defaults for anything you haven't set:
17+
18+
```console
19+
% container system property list
20+
[build]
21+
cpus = 2
22+
memory = "2048mb"
23+
rosetta = true
24+
image = "ghcr.io/apple/container-builder-shim/builder:0.13.1"
25+
26+
[container]
27+
cpus = 4
28+
memory = "1gb"
29+
30+
[dns]
31+
domain = "test"
32+
33+
[kernel]
34+
binaryPath = "opt/kata/share/kata-containers/vmlinux-6.18.15-186"
35+
url = "https://github.com/kata-containers/kata-containers/releases/download/3.28.0/kata-static-3.28.0-arm64.tar.zst"
36+
digest = "sha256:f63d54507d1f18635d94475077e4c2330de4d8e05cedf25f7c38f063b0e66a91"
37+
38+
[network]
39+
40+
[registry]
41+
domain = "docker.io"
42+
43+
[vminit]
44+
image = "ghcr.io/apple/containerization/vminit:0.34.0"
45+
```
46+
47+
Pass `--format json` for machine-readable output.
48+
1249
## Top-level schema
1350

1451
```toml
@@ -35,6 +72,16 @@ Resources and image used for the builder VM that runs `container build`.
3572
| `memory` | [MemorySize](#memorysize-format) | `"2048mb"` | RAM allocation for the builder VM. |
3673
| `image` | `String` | `ghcr.io/apple/container-builder-shim/builder:<tag>` | Reference for the builder image. The tag segment is taken from the project's bundled `container-builder-shim` version. |
3774

75+
To prevent the use of Rosetta translation during container builds on a Mac with Apple
76+
silicon, set `rosetta = false`:
77+
78+
```toml
79+
[build]
80+
rosetta = false
81+
```
82+
83+
This ensures builds only produce native arm64 images, with no x86_64 emulation.
84+
3885
## `[container]`
3986

4087
Defaults applied when `container run` / `container create` is invoked without `--cpus` or `--memory`.
@@ -48,11 +95,7 @@ Defaults applied when `container run` / `container create` is invoked without `-
4895

4996
| Key | Type | Default | Description |
5097
|----------|-----------|---------|----------------------------------------------------------------------------|
51-
| `domain` | `String?` | unset | Local DNS domain appended to container hostnames (e.g. `"test"` makes `my-web-server` resolvable as `my-web-server.test`). When unset, no domain is appended. |
52-
53-
Setting `domain` here tells the `container` service what domain to register container
54-
hostnames under. See [Networking: Set up DNS-based container
55-
names](./networking.md#set-up-dns-based-container-names) for the full walkthrough.
98+
| `domain` | `String?` | unset | Local DNS domain appended to container hostnames (e.g. `"test"` makes `my-web-server` resolvable as `my-web-server.test`). When unset, no domain is appended. See [Networking: Set up DNS-based container names](./networking.md#set-up-dns-based-container-names) for the full walkthrough. |
5699

57100
## `[kernel]`
58101

docs/host-integration.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Host integration
2+
3+
Bridge your container and your Mac: forward your SSH agent in, or reach a host
4+
service from inside a container.
5+
6+
## Mount your host SSH authentication socket in your container
7+
8+
Use the `--ssh` option to mount the macOS SSH authentication socket into your container, so that you can clone private git repositories and perform other tasks requiring passwordless SSH authentication.
9+
10+
When you use `--ssh`, it performs the equivalent of the options `--volume "${SSH_AUTH_SOCK}:/var/host-services/ssh-auth.sock" --env SSH_AUTH_SOCK=/var/host-services/ssh-auth.sock"`. The added benefit of `--ssh` is that when you stop your container, log out, log back in, and restart your container, the system automatically updates the target path for the socket mount to the new value of `SSH_AUTH_SOCK`, so that socket forwarding continues to function.
11+
12+
```console
13+
% container run -it --rm --ssh alpine:latest sh
14+
/ # env
15+
SHLVL=1
16+
HOME=/root
17+
TERM=xterm
18+
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
19+
SSH_AUTH_SOCK=/var/host-services/ssh-auth.sock
20+
PWD=/
21+
/ # apk add openssh-client
22+
(1/6) Installing openssh-keygen (10.0_p1-r7)
23+
(2/6) Installing ncurses-terminfo-base (6.5_p20250503-r0)
24+
(3/6) Installing libncursesw (6.5_p20250503-r0)
25+
(4/6) Installing libedit (20250104.3.1-r1)
26+
(5/6) Installing openssh-client-common (10.0_p1-r7)
27+
(6/6) Installing openssh-client-default (10.0_p1-r7)
28+
Executing busybox-1.37.0-r18.trigger
29+
OK: 12 MiB in 22 packages
30+
/ # ssh-add -l
31+
...auth key output...
32+
/ # apk add git
33+
(1/12) Installing brotli-libs (1.1.0-r2)
34+
(2/12) Installing c-ares (1.34.5-r0)
35+
(3/12) Installing libunistring (1.3-r0)
36+
(4/12) Installing libidn2 (2.3.7-r0)
37+
(5/12) Installing nghttp2-libs (1.65.0-r0)
38+
(6/12) Installing libpsl (0.21.5-r3)
39+
(7/12) Installing zstd-libs (1.5.7-r0)
40+
(8/12) Installing libcurl (8.14.1-r1)
41+
(9/12) Installing libexpat (2.7.1-r0)
42+
(10/12) Installing pcre2 (10.43-r1)
43+
(11/12) Installing git (2.49.1-r0)
44+
(12/12) Installing git-init-template (2.49.1-r0)
45+
Executing busybox-1.37.0-r18.trigger
46+
OK: 24 MiB in 34 packages
47+
/ # git clone git@github.com:some-org/some-private-repo.git
48+
Cloning into 'some-private-repo'...
49+
...
50+
```
51+
52+
## Access a host service from a container
53+
54+
> [!IMPORTANT]
55+
> Due to macOS security constraints around packet filter rules, this feature has limited functionality:
56+
> - Creating a localhost domain disables Private Relay.
57+
> - The local domain packet filter rule is removed on a restart.
58+
59+
Create a DNS domain with `--localhost <ipv4-address>` to make a domain used by a container to access a host service. Any IPv4 address can be used as `<ipv4-address>`, which will be assigned to the domain name in container.
60+
61+
Choose an IP address that is least likely to conflict with any networks or reserved IP addresses in your environment. Reasonably safe address ranges include:
62+
63+
- The documentation ranges 192.0.2.0/24, 198.51.100.0/24, and 203.0.113.0/24.
64+
- The 172.16.0.0/12 private range.
65+
66+
To connect a host HTTP server from a container, run:
67+
68+
```bash
69+
mkdir -p /tmp/test; cd /tmp/test; echo "hello" > index.html
70+
python3 -m http.server 8000 --bind 127.0.0.1
71+
```
72+
73+
Create a domain for host connection:
74+
75+
```bash
76+
sudo container system dns create host.container.internal --localhost 203.0.113.113
77+
```
78+
79+
Test access to the host HTTP server from a container:
80+
81+
```console
82+
% container run -it --rm alpine/curl curl http://host.container.internal:8000
83+
hello
84+
```
85+
86+
This uses the same underlying DNS mechanism described in [Networking: Set up DNS-based
87+
container names](./networking.md#set-up-dns-based-container-names), just with
88+
`--localhost` pointing the domain at a host address instead of a container.

0 commit comments

Comments
 (0)