# 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:
% 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... %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:
% container list --all ID IMAGE OS ARCH STATE IP %### Get CLI help You can get help for any `container` CLI command by appending the `--help` option:
% container --help OVERVIEW: A container platform for macOS USAGE: container [--debug]### 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`: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 %
% container ls -a ID IMAGE OS ARCH STATE IP %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/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 '
% container image list NAME TAG DIGEST python alpine b4d299311845 web-test latest 25b99501f174 %## 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 `IP` column, is `192.168.64.3`:
% container ls ID IMAGE OS ARCH STATE IP 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 %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:
% 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 %> [!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:
% container exec my-web-server ls /content index.html %If you want to poke around in the container, run a shell and issue one or more commands:
% 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 %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:
% 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> %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/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:
% container list --all ID IMAGE OS ARCH STATE IP buildkit ghcr.io/apple/container-builder-shim/builder:0.0.3 linux arm64 running 192.168.64.2 %### Stop the container service When you want to stop `container` completely, run: ```bash container system stop ```