mirror of
https://github.com/apple/container.git
synced 2026-09-24 00:25:43 +00:00
README updates (#17)
- break up readme into separate files - rework hedaings on Code of Conduct - Add a CONTRIBUTORS.txt
This commit is contained in:
@@ -0,0 +1,315 @@
|
||||
# Tutorial
|
||||
|
||||
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:
|
||||
|
||||
```shellsession
|
||||
% container system start
|
||||
Verifying apiserver is running...
|
||||
Done
|
||||
Missing required runtime dependencies:
|
||||
1. Initial Filesystem
|
||||
2. Kernel
|
||||
Would like to install them now? [Y/n]: Y
|
||||
Installing default kernel from [https://github.com/kata-containers/kata-containers/releases/download/3.17.0/kata-static-3.17.0-arm64.tar.xz]...
|
||||
Installing initial filesystem from [ghcr.io/apple/containerization/vminit:0.1.34]...
|
||||
%
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
```shellsession
|
||||
% container list --all
|
||||
ID IMAGE OS ARCH STATE ADDR
|
||||
%
|
||||
```
|
||||
|
||||
### Get CLI help
|
||||
|
||||
You can get help for any `container` CLI command by appending the `--help` option:
|
||||
|
||||
```shellsession
|
||||
% container --help
|
||||
OVERVIEW: A container platform for macOS
|
||||
|
||||
USAGE: container [--debug] <subcommand>
|
||||
|
||||
OPTIONS:
|
||||
--debug Enable debug output [environment: CONTAINER_DEBUG]
|
||||
--version Show the version.
|
||||
-h, --help Show help information.
|
||||
|
||||
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
|
||||
images, image, i Manage images
|
||||
registry, r Manage registry configurations
|
||||
|
||||
SYSTEM SUBCOMMANDS:
|
||||
builder Manage an image builder instance
|
||||
system, s Manage system components
|
||||
|
||||
%
|
||||
```
|
||||
|
||||
### 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`:
|
||||
|
||||
```shellsession
|
||||
% container ls -a
|
||||
ID IMAGE OS ARCH STATE ADDR
|
||||
%
|
||||
```
|
||||
|
||||
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 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.
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
Download an image file for your web server can use:
|
||||
|
||||
```bash
|
||||
curl -L -o logo.jpg https://github.com/apple/container/tree/main/docs/assets/logo.jpg
|
||||
```
|
||||
|
||||
In the `web-test` directory, create a file named `Dockerfile` with this content:
|
||||
|
||||
```docker
|
||||
FROM docker.io/python:slim
|
||||
WORKDIR /content
|
||||
COPY logo.jpg ./
|
||||
RUN echo '<!DOCTYPE html><html><head><title>Hello</title></head><body><p><img src="logo.jpg" style="width: 2rem; height: 2rem;">Hello, world!</p></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 `COPY` command copies the image file `logo.jpg` from your build context to the image. See the following section for a description of the build context.
|
||||
|
||||
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.
|
||||
|
||||
### 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:
|
||||
|
||||
```shellsession
|
||||
% container images list
|
||||
NAME TAG DIGEST
|
||||
docker.io/library/python slim 56a11364ffe0fee3bd60af6d...
|
||||
web-test latest bf91dc9d42f0110d3aac41dd...
|
||||
%
|
||||
```
|
||||
|
||||
## 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 --dns-domain test --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`:
|
||||
|
||||
```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
|
||||
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 the full hostname for the container:
|
||||
|
||||
```bash
|
||||
open http://my-web-server.test
|
||||
```
|
||||
|
||||
### 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:
|
||||
|
||||
```shellsession
|
||||
% container exec my-web-server ls /content
|
||||
index.html
|
||||
logo.jpg
|
||||
%
|
||||
```
|
||||
|
||||
If you want to poke around in the container, run a shell and issue one or more commands:
|
||||
|
||||
```shellsession
|
||||
% container exec --tty --interactive my-web-server bash
|
||||
root@my-web-server:/content# ls
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
```shellsession
|
||||
% container run -it --rm web-test curl http://192.168.64.3
|
||||
<!DOCTYPE html><html><head><title>Hello</title></head><body><p><img src="logo.jpg" style="width: 2rem; height: 2rem;">Hello, world!</p></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 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 `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 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 images tag web-test registry.example.com/fido/web-test:latest
|
||||
```
|
||||
|
||||
Then, push the image:
|
||||
|
||||
```bash
|
||||
container images push registry.example.com/fido/web-test:latest
|
||||
```
|
||||
|
||||
### Pull and run your image
|
||||
|
||||
To validate your published image, remove your existing web server image, and then run using the remote image:
|
||||
|
||||
```bash
|
||||
container images delete web-test registry.example.com/fido/web-test:latest
|
||||
container run --name my-web-server --dns-domain test --detach --rm 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:
|
||||
|
||||
```bash
|
||||
% container ls --all
|
||||
ID IMAGE OS ARCH STATE ADDR
|
||||
buildkit ghcr.io/apple/container-builder-shim/builder:2.1.1 linux arm64 running 192.168.64.2
|
||||
%
|
||||
```
|
||||
|
||||
To shut down and remove all containers, run:
|
||||
|
||||
```bash
|
||||
container rm --all --force
|
||||
```
|
||||
|
||||
### Stop the container service
|
||||
|
||||
When you want to stop `container` completely, run:
|
||||
|
||||
```bash
|
||||
container system stop
|
||||
```
|
||||
Reference in New Issue
Block a user