mirror of
https://github.com/apple/container.git
synced 2026-07-13 21:17:05 +00:00
e3c49803a0
- Discussion topic #1336. - This change migrates away from using `UserDefaults`, instead providing a TOML configuration mechanism for user configurable settings. All existing system property settings keys are supported in the new configuration file. However, users will have to migrate any settings they have configured in the `UserDefaults` into TOML for these settings to take effect. - Breaking changes: * `container system property get` is removed in favor of users directly utilizing `container system property list --format toml | jq<>`. * `container system property set` is removed since the TOML configuration is effectively immutable during the lifetime of the `container` daemon. Uses can edit the TOML they have in their home directory, however no changes will take effect until the daemon is restarted via `container system stop && container system start` * `container system property list --format table` is removed as generating tabular format is non-trivial and the new TOML format is intended to be human readable
353 lines
12 KiB
Markdown
353 lines
12 KiB
Markdown
# Tutorial
|
|
|
|
> [!IMPORTANT]
|
|
> This file contains documentation for the CURRENT BRANCH. To find documentation for official releases, find the target release on the [Release Page](https://github.com/apple/container/releases) and click the tag corresponding to your release version.
|
|
>
|
|
> Example: [release 0.4.1 tag](https://github.com/apple/container/tree/0.4.1)
|
|
|
|
Take a guided tour of `container` by building, running, and publishing a simple web server image.
|
|
|
|
## Try out the `container` CLI
|
|
|
|
Start the application, and try out some basic commands to familiarize yourself with the command line interface (CLI) tool.
|
|
|
|
### Start the container service
|
|
|
|
Start the services that `container` uses:
|
|
|
|
```bash
|
|
container system start
|
|
```
|
|
|
|
If you have not installed a Linux kernel yet, the command will prompt you to install one:
|
|
|
|
<pre>
|
|
% container system start
|
|
|
|
Verifying apiserver is running...
|
|
Installing base container filesystem...
|
|
No default kernel configured.
|
|
Install the recommended default kernel from [https://github.com/kata-containers/kata-containers/releases/download/3.17.0/kata-static-3.17.0-arm64.tar.xz]? [Y/n]: y
|
|
Installing kernel...
|
|
%
|
|
</pre>
|
|
|
|
Then, verify that the application is working by running a command to list all containers:
|
|
|
|
```bash
|
|
container list --all
|
|
```
|
|
|
|
If you haven't created any containers yet, the command outputs an empty list:
|
|
|
|
<pre>
|
|
% container list --all
|
|
ID IMAGE OS ARCH STATE ADDR
|
|
%
|
|
</pre>
|
|
|
|
### Get CLI help
|
|
|
|
You can get help for any `container` CLI command by appending the `--help` option:
|
|
|
|
<pre>
|
|
% container --help
|
|
OVERVIEW: A container platform for macOS
|
|
|
|
USAGE: container [--debug] <subcommand>
|
|
|
|
OPTIONS:
|
|
--debug Enable debug output [environment: CONTAINER_DEBUG]
|
|
--version Show the CLI version (single line).
|
|
-h, --help Show help information.
|
|
|
|
Detailed version information is available under the system command:
|
|
|
|
```
|
|
container system version [--format json|table]
|
|
```
|
|
|
|
CONTAINER SUBCOMMANDS:
|
|
create Create a new container
|
|
delete, rm Delete one or more containers
|
|
exec Run a new command in a running container
|
|
inspect Display information about one or more containers
|
|
kill Kill one or more running containers
|
|
list, ls List containers
|
|
logs Fetch container stdio or boot logs
|
|
run Run a container
|
|
start Start a container
|
|
stop Stop one or more running containers
|
|
|
|
IMAGE SUBCOMMANDS:
|
|
build Build an image from a Dockerfile
|
|
image, i Manage images
|
|
registry, r Manage registry configurations
|
|
|
|
SYSTEM SUBCOMMANDS:
|
|
builder Manage an image builder instance
|
|
system, s Manage system components
|
|
|
|
%
|
|
</pre>
|
|
|
|
### Abbreviations
|
|
|
|
You can save keystrokes by abbreviating commands and options. For example, abbreviate the `container list` command to `container ls`, and the `--all` option to `-a`:
|
|
|
|
<pre>
|
|
% container ls -a
|
|
ID IMAGE OS ARCH STATE ADDR
|
|
%
|
|
</pre>
|
|
|
|
Use the `--help` flag to see which abbreviations exist.
|
|
|
|
### Set up a local DNS domain (optional)
|
|
|
|
`container` includes an embedded DNS service that simplifies access to your containerized applications. If you want to configure a local DNS domain named `test` for this tutorial, run:
|
|
|
|
```bash
|
|
sudo container system dns create test
|
|
```
|
|
|
|
Enter your administrator password when prompted. The first command requires administrator privileges to create a file containing the domain configuration under the `/etc/resolver` directory, and to tell the macOS DNS resolver to reload its configuration files.
|
|
|
|
With the domain set to `test`, if you use `--name my-web-server` to start a container, queries to `my-web-server.test` will respond with that container's IP address. You can customize the domain in `~/.config/container/runtime-config.toml`.
|
|
|
|
## Build an image
|
|
|
|
Set up a `Dockerfile` for a basic Python web server, and use it to build a container image named `web-test`.
|
|
|
|
### Set up a simple project
|
|
|
|
Start a terminal, create a directory named `web-test` for the files needed to create the container image:
|
|
|
|
```bash
|
|
mkdir web-test
|
|
cd web-test
|
|
```
|
|
|
|
In the `web-test` directory, create a file named `Dockerfile` with this content:
|
|
|
|
```dockerfile
|
|
FROM docker.io/python:alpine
|
|
WORKDIR /content
|
|
RUN apk add curl
|
|
RUN echo '<!DOCTYPE html><html><head><title>Hello</title></head><body><h1>Hello, world!</h1></body></html>' > index.html
|
|
CMD ["python3", "-m", "http.server", "80", "--bind", "0.0.0.0"]
|
|
```
|
|
|
|
The `FROM` line instructs the `container` builder to start with a base image containing the latest production version of Python 3.
|
|
|
|
The `WORKDIR` line creates a directory `/content` in the image, and makes it the current directory.
|
|
|
|
The first `RUN` line adds the `curl` command to your image, and the second `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 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
|
|
|
|
Run the `container build` command to create an image with the name `web-test` from your `Dockerfile`:
|
|
|
|
```bash
|
|
container build --tag web-test --file Dockerfile .
|
|
```
|
|
|
|
The last argument `.` tells the builder to use the current directory (`web-test`) as the root of the build context. You can copy files within the build context into your image using the `COPY` command in your Dockerfile.
|
|
|
|
After the build completes, list the images. You should see both the base image and the image that you built in the results:
|
|
|
|
<pre>
|
|
% container image list
|
|
NAME TAG DIGEST
|
|
python alpine b4d299311845147e7e47c970...
|
|
web-test latest 25b99501f174803e21c58f9c...
|
|
%
|
|
</pre>
|
|
|
|
## Run containers
|
|
|
|
Using your container image, run a web server and try out different ways of interacting with it.
|
|
|
|
### Start the webserver
|
|
|
|
Use `container run` to start a container named `my-web-server` that runs your webserver:
|
|
|
|
```bash
|
|
container run --name my-web-server --detach --rm web-test
|
|
```
|
|
|
|
The `--detach` flag runs the container in the background, so that you can continue running commands in the same terminal. The `--rm` flag causes the container to be removed automatically after it stops.
|
|
|
|
When you list containers now, `my-web-server` is present, along with the container that `container` started to build your image. Note that its IP address, shown in the `ADDR` column, is `192.168.64.3`:
|
|
|
|
<pre>
|
|
% container ls
|
|
ID IMAGE OS ARCH STATE ADDR
|
|
buildkit ghcr.io/apple/container-builder-shim/builder:0.0.3 linux arm64 running 192.168.64.2
|
|
my-web-server web-test:latest linux arm64 running 192.168.64.3
|
|
%
|
|
</pre>
|
|
|
|
Open the website, using the container's IP address in the URL:
|
|
|
|
```bash
|
|
open http://192.168.64.3
|
|
```
|
|
|
|
If you configured the local domain `test` earlier in the tutorial, you can also open the page with the full hostname for the container:
|
|
|
|
```bash
|
|
open http://my-web-server.test
|
|
```
|
|
|
|
### Monitor container resource usage
|
|
|
|
Now that your web server is running, you can monitor its resource usage with the `container stats` command:
|
|
|
|
```bash
|
|
container stats my-web-server
|
|
```
|
|
|
|
This displays real-time statistics about CPU usage, memory consumption, network traffic, disk I/O, and the number of running processes:
|
|
|
|
<pre>
|
|
% container stats --no-stream my-web-server
|
|
Container ID Cpu % Memory Usage Net Rx/Tx Block I/O Pids
|
|
my-web-server 0.23% 12.45 MiB / 1.00 GiB 856.00 KiB / 1.2 KiB 2.10 MiB / 512 KiB 2
|
|
%
|
|
</pre>
|
|
|
|
> [!NOTE]
|
|
> Without the `--no-stream` flag, `container stats` continuously updates the display in real-time, similar to the `top` command. Press Ctrl+C to exit the live view.
|
|
|
|
### Run other commands in the container
|
|
|
|
You can run other commands in `my-web-server` by using the `container exec` command. To list the files under the content directory, run an `ls` command:
|
|
|
|
<pre>
|
|
% container exec my-web-server ls /content
|
|
index.html
|
|
%
|
|
</pre>
|
|
|
|
If you want to poke around in the container, run a shell and issue one or more commands:
|
|
|
|
<pre>
|
|
% container exec --tty --interactive my-web-server sh
|
|
/content # ls
|
|
index.html
|
|
/content # uname -a
|
|
Linux my-web-server 6.12.28 #1 SMP Tue May 20 15:19:05 UTC 2025 aarch64 Linux
|
|
/content # exit
|
|
%
|
|
</pre>
|
|
|
|
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`.
|
|
|
|
### Access the web server from another container
|
|
|
|
Your web server is accessible from other containers as well as from your host. Launch a second container using your `web-test` image, and this time, specify a `curl` command to retrieve the `index.html` content from the first container.
|
|
|
|
> [!NOTE]
|
|
> Container relies on the new features and enhancements present in macOS 26.
|
|
> As a result, the functionality of accessing the web server from another container will not work on macOS 15.
|
|
> See https://github.com/apple/container/blob/main/docs/technical-overview.md#macos-15-limitations for more details.
|
|
|
|
```bash
|
|
container run -it --rm web-test curl http://192.168.64.3
|
|
```
|
|
|
|
The output should appear as:
|
|
|
|
<pre>
|
|
% container run -it --rm web-test curl http://192.168.64.3
|
|
<!DOCTYPE html><html><head><title>Hello</title></head><body><h1>Hello, world!</h1></body></html>
|
|
%
|
|
</pre>
|
|
|
|
If you set up the `test` domain earlier, you can achieve the same result with:
|
|
|
|
```bash
|
|
container run -it --rm web-test curl http://my-web-server.test
|
|
```
|
|
|
|
## Run a published image
|
|
|
|
Push your image to a container registry, publishing it so that you and others can use it.
|
|
|
|
### Publish the web server image
|
|
|
|
To publish your image, you need to push images to a registry service that stores the image for future use. Typically, you need to authenticate with a registry to push an image. This example assumes that you have an account at a hypothetical registry named `some-registry.example.com` with username `fido` and a password or token `my-secret`, and that your personal repository name is the same as your username.
|
|
|
|
To sign into a secure registry with your login credentials, enter your username and password at the prompts after running:
|
|
|
|
```bash
|
|
container registry login some-registry.example.com
|
|
```
|
|
|
|
Create another name for your image that includes the registry name, your repository name, and the image name, with the tag `latest`:
|
|
|
|
```bash
|
|
container image tag web-test some-registry.example.com/fido/web-test:latest
|
|
```
|
|
|
|
Then, push the image:
|
|
|
|
```bash
|
|
container image push some-registry.example.com/fido/web-test:latest
|
|
```
|
|
|
|
> [!NOTE]
|
|
> By default `container` is configured to use Docker Hub.
|
|
> You can change the default registry by setting `domain` under `[registry]` in `~/.config/container/runtime-config.toml`:
|
|
> ```toml
|
|
> [registry]
|
|
> domain = "some-registry.example.com"
|
|
> ```
|
|
> See the other sub commands under `container registry` for more options.
|
|
|
|
### Pull and run your image
|
|
|
|
To validate your published image, stop your current web server container, remove the image that you built, and then run using the remote image:
|
|
|
|
```bash
|
|
container stop my-web-server
|
|
container image delete web-test some-registry.example.com/fido/web-test:latest
|
|
container run --name my-web-server --detach --rm some-registry.example.com/fido/web-test:latest
|
|
```
|
|
|
|
## Clean up
|
|
|
|
Stop your container and shut down the application.
|
|
|
|
### Shut down the web server
|
|
|
|
Stop your web server container with:
|
|
|
|
```bash
|
|
container stop my-web-server
|
|
```
|
|
|
|
If you list all running and stopped containers, you will see that the `--rm` flag you supplied with the `container run` command caused the container to be removed:
|
|
|
|
<pre>
|
|
% container list --all
|
|
ID IMAGE OS ARCH STATE ADDR
|
|
buildkit ghcr.io/apple/container-builder-shim/builder:0.0.3 linux arm64 running 192.168.64.2
|
|
%
|
|
</pre>
|
|
|
|
### Stop the container service
|
|
|
|
When you want to stop `container` completely, run:
|
|
|
|
```bash
|
|
container system stop
|
|
```
|