From 72903f5d6bbcafd58aa6d176bd65061c40f3aac4 Mon Sep 17 00:00:00 2001 From: MirageTurtle <60972592+MirageTurtle@users.noreply.github.com> Date: Fri, 16 Oct 2026 18:13:42 +0800 Subject: [PATCH 1/5] docs(ch08): update docker commands and examples for modern versions --- docs/Ch08/index.md | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/docs/Ch08/index.md b/docs/Ch08/index.md index f8783de2..d2537bf4 100644 --- a/docs/Ch08/index.md +++ b/docs/Ch08/index.md @@ -121,41 +121,41 @@ For more examples and ideas, visit: `-it` 是为了获得可交互的 Shell 所必须的。`-i` 会将容器的 init(主进程,这里是 `/bin/bash`)的标准输入与 `docker` 这个程序的标准输入相连接;而 `-t` 会告知主进程输入为终端(TTY)设备。 -在执行以上命令之后,你会获得一个 Ubuntu(版本为 `latest` 即最新的 LTS;如果需要指定版本,可以使用类似 `20.04` 的版本号替换 `latest`,推荐在生产环境中这么做,因为 `latest` 指定的最新版本可能随时间变化)的容器环境,退出 Shell 之后容器就会被销毁。 +在执行以上命令之后,你会获得一个 Ubuntu(版本为 `latest` 即最新的 LTS;如果需要指定版本,可以使用类似 `26.04` 的版本号替换 `latest`,推荐在生产环境中这么做,因为 `latest` 指定的最新版本可能随时间变化)的容器环境,退出 Shell 之后容器就会被销毁。 如果没有加上 `--rm`,退出后可以使用 `docker ps -a` 查看系统中所有的容器。 ```console -$ sudo docker ps -a +$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -39d8ef1d4acf ubuntu:20.04 "bash" 4 seconds ago Exited (0) 2 seconds ago ubuntu-container +39d8ef1d4acf ubuntu:latest "bash" 4 seconds ago Exited (0) 2 seconds ago ubuntu-container ``` 之后使用 `docker start` 启动容器。 ```console -$ sudo docker start -ai ubuntu-container +$ docker start -ai ubuntu-container root@39d8ef1d4acf:/# ``` `-a` 代表连接输出以及信号。最后的 `ubuntu-container` 代指我们刚刚创建的那个容器。也可以输入容器的 ID 来启动(不需要输入完整的 ID,只需要前几位即可): ```console -$ sudo docker start -ai 39d +$ docker start -ai 39d root@39d8ef1d4acf:/# ``` 如果忘记加上了参数直接启动,也可以使用 `docker attach` 将容器的主进程的输入输出接上。 ```console -$ sudo docker attach ubuntu-container +$ docker attach ubuntu-container root@39d8ef1d4acf:/# ``` `docker exec` 也可以完成相似的事情:它可以在容器中执行指定的命令(当然也包括 Shell 了)。 ```console -$ sudo docker exec -it ubuntu-container bash +$ docker exec -it ubuntu-container bash root@39d8ef1d4acf:/# ``` @@ -164,9 +164,9 @@ root@39d8ef1d4acf:/# 与 `docker start` 相对应,`docker stop` 可以关闭一个容器,`docker rm` 可以删除一个容器。 ```console -$ sudo docker stop ubuntu-container +$ docker stop ubuntu-container 39d -$ sudo docker rm ubuntu-container +$ docker rm ubuntu-container 39d ``` @@ -217,20 +217,20 @@ flowchart TD `docker commit` 命令可以从当前运行的容器新建镜像。以下是一个简单的例子: ```console -$ sudo docker run -it ubuntu +$ docker run -it ubuntu root@82d245a5a4a1:/# apt update && apt install curl (输出省略) root@82d245a5a4a1:/# exit exit -$ sudo docker ps -a +$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 82d245a5a4a1 ubuntu "/bin/bash" 2 minutes ago Exited (0) 23 seconds ago laughing_elgamal -$ sudo docker commit 82d245a5a4a1 +$ docker commit 82d245a5a4a1 sha256:fe0a84d81b867949b27bacec4794303852b05ae76df14818bae85751b14f6e20 -$ sudo docker images +$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE fe0a84d81b86 54 seconds ago 116MB -$ sudo docker save fe0a84d81b86 > example.tar +$ docker save fe0a84d81b86 > example.tar $ ls -lh example.tar -rw-r--r-- 1 ustc ustc 114M Feb 10 17:48 example.tar ``` @@ -246,12 +246,12 @@ Dockerfile 是构建 Docker 镜像的标准格式,下面会举一些例子。 这个例子尝试使用 Debian 仓库中的 RISC-V [交叉编译](../Ch07/supplement.md#cross-compile-example)工具链与 QEMU 模拟器构建一个简单的用于交叉编译的环境。 ```Dockerfile -FROM debian:buster-slim +FROM debian:trixie-slim -RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && \ +RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/debian.sources && \ apt update && apt install -y --no-install-recommends \ gcc-riscv64-linux-gnu g++-riscv64-linux-gnu libc6-dev-riscv64-cross \ - binutils-riscv64-linux-gnu libstdc++-dev-riscv64-cross \ + binutils-riscv64-linux-gnu libstdc++-14-dev-riscv64-cross \ qemu-system-misc qemu-user-static qemu-user binfmt-support \ fish vim @@ -264,13 +264,13 @@ CMD ["fish"] 通过使用 `docker build`,我们可以构建出镜像。 ```console -sudo docker build -t riscv-cross:example . +$ docker build -t riscv-cross:example . ``` `-t riscv-cross:example` 代表为这个镜像打上 `riscv-cross:example` 的标签,`.` 表示从当前目录下寻找 Dockerfile 并以当前目录作为构建过程的“工作路径”。构建完成后,使用 `docker run` 执行即可: ```console -$ sudo docker run -v ${PWD}/workspace:/workspace -it riscv-cross:example +$ docker run -v ${PWD}/workspace:/workspace -it riscv-cross:example Welcome to fish, the friendly interactive shell root@dec3d33003ee /workspace# vim helloworld.c root@dec3d33003ee /workspace# riscv64-linux-gnu-gcc helloworld.c @@ -331,7 +331,7 @@ Docker 在根据 Dockerfile 构建时,会从上到下执行这些指令,每 Flask 是一个知名的 Python web 框架。本例子包含了一个运行 Flask 编写的网站的简单 Dockerfile(不包含数据库等部分): ```dockerfile -FROM tiangolo/uwsgi-nginx-flask:python3.8 +FROM tiangolo/uwsgi-nginx-flask:python3.12 RUN pip3 config set global.index-url https://mirrors.ustc.edu.cn/pypi/simple RUN pip3 install pyopenssl @@ -346,7 +346,7 @@ COPY ./app /app Docker Compose 是一个方便的小型容器编排工具。如果前面安装的是 `docker.io` 软件包,那么系统中可能未安装 `docker-compose`,使用以下命令安装: ```console -$ sudo apt install docker-compose +$ sudo apt install docker-compose-v2 ``` ### 使用 Docker Compose 创建 WordPress 博客 {#use-docker-compose-build-wordpress-with-mysql} @@ -356,7 +356,6 @@ WordPress 是一个知名的博客应用。本例子使用 Docker Compose,创 新建一个文件夹,在其中放入一个名为 `docker-compose.yml` 的配置文件: ```yaml -version: "3" services: db: image: mysql:5.7 @@ -385,4 +384,4 @@ services: WORDPRESS_DB_PASSWORD: linux101-test ``` -在文件夹中运行 `docker-compose up` 命令即可启动样例,在 127.0.0.1:80 上即可看到 WordPress 的初始化界面。用 `docker-compose up -d` 命令可以让容器分离(detach)命令行。运行完成后,可以使用 `docker-compose down` 停止并删除容器。 +在文件夹中运行 `docker compose up` 命令即可启动样例,在 127.0.0.1:80 上即可看到 WordPress 的初始化界面。用 `docker compose up -d` 命令可以让容器分离(detach)命令行。运行完成后,可以使用 `docker compose down` 停止并删除容器。 From e33c1d013ca66c1fd1d067da77953e5987bea7a1 Mon Sep 17 00:00:00 2001 From: MirageTurtle <60972592+MirageTurtle@users.noreply.github.com> Date: Sun, 18 Oct 2026 21:28:31 +0800 Subject: [PATCH 2/5] docs(Ch08): add sudo back to docker commands --- docs/Ch08/index.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/Ch08/index.md b/docs/Ch08/index.md index d2537bf4..f86c89cc 100644 --- a/docs/Ch08/index.md +++ b/docs/Ch08/index.md @@ -126,7 +126,7 @@ For more examples and ideas, visit: 如果没有加上 `--rm`,退出后可以使用 `docker ps -a` 查看系统中所有的容器。 ```console -$ docker ps -a +$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 39d8ef1d4acf ubuntu:latest "bash" 4 seconds ago Exited (0) 2 seconds ago ubuntu-container ``` @@ -134,28 +134,28 @@ CONTAINER ID IMAGE COMMAND CREATED STATUS 之后使用 `docker start` 启动容器。 ```console -$ docker start -ai ubuntu-container +$ sudo docker start -ai ubuntu-container root@39d8ef1d4acf:/# ``` `-a` 代表连接输出以及信号。最后的 `ubuntu-container` 代指我们刚刚创建的那个容器。也可以输入容器的 ID 来启动(不需要输入完整的 ID,只需要前几位即可): ```console -$ docker start -ai 39d +$ sudo docker start -ai 39d root@39d8ef1d4acf:/# ``` 如果忘记加上了参数直接启动,也可以使用 `docker attach` 将容器的主进程的输入输出接上。 ```console -$ docker attach ubuntu-container +$ sudo docker attach ubuntu-container root@39d8ef1d4acf:/# ``` `docker exec` 也可以完成相似的事情:它可以在容器中执行指定的命令(当然也包括 Shell 了)。 ```console -$ docker exec -it ubuntu-container bash +$ sudo docker exec -it ubuntu-container bash root@39d8ef1d4acf:/# ``` @@ -164,9 +164,9 @@ root@39d8ef1d4acf:/# 与 `docker start` 相对应,`docker stop` 可以关闭一个容器,`docker rm` 可以删除一个容器。 ```console -$ docker stop ubuntu-container +$ sudo docker stop ubuntu-container 39d -$ docker rm ubuntu-container +$ sudo docker rm ubuntu-container 39d ``` @@ -217,20 +217,20 @@ flowchart TD `docker commit` 命令可以从当前运行的容器新建镜像。以下是一个简单的例子: ```console -$ docker run -it ubuntu +$ sudo docker run -it ubuntu root@82d245a5a4a1:/# apt update && apt install curl (输出省略) root@82d245a5a4a1:/# exit exit -$ docker ps -a +$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 82d245a5a4a1 ubuntu "/bin/bash" 2 minutes ago Exited (0) 23 seconds ago laughing_elgamal -$ docker commit 82d245a5a4a1 +$ sudo docker commit 82d245a5a4a1 sha256:fe0a84d81b867949b27bacec4794303852b05ae76df14818bae85751b14f6e20 -$ docker images +$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE fe0a84d81b86 54 seconds ago 116MB -$ docker save fe0a84d81b86 > example.tar +$ sudo docker save fe0a84d81b86 > example.tar $ ls -lh example.tar -rw-r--r-- 1 ustc ustc 114M Feb 10 17:48 example.tar ``` @@ -264,13 +264,13 @@ CMD ["fish"] 通过使用 `docker build`,我们可以构建出镜像。 ```console -$ docker build -t riscv-cross:example . +$ sudo docker build -t riscv-cross:example . ``` `-t riscv-cross:example` 代表为这个镜像打上 `riscv-cross:example` 的标签,`.` 表示从当前目录下寻找 Dockerfile 并以当前目录作为构建过程的“工作路径”。构建完成后,使用 `docker run` 执行即可: ```console -$ docker run -v ${PWD}/workspace:/workspace -it riscv-cross:example +$ sudo docker run -v ${PWD}/workspace:/workspace -it riscv-cross:example Welcome to fish, the friendly interactive shell root@dec3d33003ee /workspace# vim helloworld.c root@dec3d33003ee /workspace# riscv64-linux-gnu-gcc helloworld.c From f1bd33d486b3cf8cc1ce5c04edd191f9627369d9 Mon Sep 17 00:00:00 2001 From: MirageTurtle <60972592+MirageTurtle@users.noreply.github.com> Date: Sun, 18 Oct 2026 21:39:46 +0800 Subject: [PATCH 3/5] docs(ch08): update dive example and add Incus to LXC section --- docs/Ch08/supplement.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Ch08/supplement.md b/docs/Ch08/supplement.md index fd79e531..308658c7 100644 --- a/docs/Ch08/supplement.md +++ b/docs/Ch08/supplement.md @@ -18,7 +18,7 @@ $ sudo apt install ./dive_0.9.2_linux_amd64.deb 之后直接使用即可: ```console -$ dive ubuntu:20.04 # 查看 Ubuntu 20.04 镜像中的内容 +$ dive ubuntu:26.04 # 查看 Ubuntu 26.04 镜像中的内容 ``` ## Docker 以外的容器工具 {#other-container-tools} @@ -31,7 +31,7 @@ Podman 是由 Red Hat 编写的容器工具。相比于 Docker,Podman 是无 ### LXC {#lxc} -相比于 Docker 专注应用容器化而言,LXC(Linux Containers)更加注重完整 Linux 系统的容器虚拟化,用户可以使用 LXC 启动一个近似完整的 Linux 系统。Canonical 公司基于 LXC 编写的 LXD 工具则为管理员提供了一个方便的管理接口。 +相比于 Docker 专注应用容器化而言,LXC(Linux Containers)更加注重完整 Linux 系统的容器虚拟化,用户可以使用 LXC 启动一个近似完整的 Linux 系统。Canonical 公司基于 LXC 编写的 LXD 工具则为管理员提供了一个方便的管理接口。2023 年 Canonical 收回 LXD 的社区管理权后,Linux Containers 社区从 LXD 分叉出了 Incus,由社区维护。 ### systemd-nspawn {#systemd-nspawn} From 7f39827b30a36397a327c807c97d757f751361b4 Mon Sep 17 00:00:00 2001 From: MirageTurtle <60972592+MirageTurtle@users.noreply.github.com> Date: Mon, 19 Oct 2026 14:24:51 +0800 Subject: [PATCH 4/5] docs(ch08): clarify docker-compose-v2 installation and add note --- docs/Ch08/index.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/Ch08/index.md b/docs/Ch08/index.md index f86c89cc..d0bf0c8f 100644 --- a/docs/Ch08/index.md +++ b/docs/Ch08/index.md @@ -127,7 +127,7 @@ For more examples and ideas, visit: ```console $ sudo docker ps -a -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 39d8ef1d4acf ubuntu:latest "bash" 4 seconds ago Exited (0) 2 seconds ago ubuntu-container ``` @@ -343,12 +343,18 @@ COPY ./app /app ## 使用 Docker Compose 自动运行容器 {#docker-compose} -Docker Compose 是一个方便的小型容器编排工具。如果前面安装的是 `docker.io` 软件包,那么系统中可能未安装 `docker-compose`,使用以下命令安装: +Docker Compose 是一个方便的小型容器编排工具。如果前面安装的是 `docker.io` 软件包,那么系统中可能未安装 `docker-compose-v2`,使用以下命令安装: ```console $ sudo apt install docker-compose-v2 ``` +!!! note "`docker-compose` 与 `docker-compose-v2`" + + Docker Compose 有两代实现:Docker Compose V1 提供独立的 `docker-compose` 命令,已于 2023 年停止维护;Docker Compose V2 作为 Docker CLI 插件,提供 `docker compose` 子命令。 + + 在 Ubuntu 中,Docker Compose V2 由 `docker-compose-v2` 软件包提供。而 `docker-compose` 软件包提供什么,则取决于发行版本和软件源:它可能是 Docker Compose V1 的软件包,也可能是由 `docker-compose-v2` 提供的虚拟包。为了确保安装 Docker Compose V2,建议直接指定 `docker-compose-v2`。 + ### 使用 Docker Compose 创建 WordPress 博客 {#use-docker-compose-build-wordpress-with-mysql} WordPress 是一个知名的博客应用。本例子使用 Docker Compose,创建了一个使用 MySQL 数据库的 WordPress。 From d53c5164acd49b7ddff0f36fc8e91e1dbff45db2 Mon Sep 17 00:00:00 2001 From: MirageTurtle <60972592+MirageTurtle@users.noreply.github.com> Date: Mon, 19 Oct 2026 15:57:43 +0800 Subject: [PATCH 5/5] docs(ch08): remove draft warning --- docs/Ch08/index.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/Ch08/index.md b/docs/Ch08/index.md index d0bf0c8f..aa8adb14 100644 --- a/docs/Ch08/index.md +++ b/docs/Ch08/index.md @@ -4,8 +4,6 @@ icon: simple/docker # Docker -!!! Warning "本文已基本完稿,正在审阅和修订中,不是正式版本。" - !!! abstract "导言" 「容器」,是近年来非常热门的一个概念。它通过操作系统内核提供的隔离技术,实现轻量级的虚拟化环境。目前,它在软件的开发、部署等方面有着非常广泛的应用。