Docker
Docker 是一个容器工具,而容器是一种非常现代的环境解决方案
容器是一种轻量级的环境,它把应用程序及其依赖打包在一起
相比虚拟机,容器直接共享主机内核,无需虚拟化硬件。同时容器之间相互隔离,可以避免冲突
容器可以通过镜像生成,而镜像可以通过 Dockerfile 构建出来
这使得我们可以轻松复现出相同的环境,确保了开发、测试、生产等各种场景中的环境一致性
镜像可以上传到仓库进行共享,容器可以跨平台,这都使得协作、配置环境变得更加方便
目前有许多容器工具,Docker 仅仅是其中一种。Podman 被认为是一种更好的容器工具,主要优势有
- 架构更先进。Docker 使用 客户端 - 守护进程 架构;而 Podman 使用 无守护进程 架构
- 安全性更好。Docker 默认情况下需要 root 权限运行守护进程,存在安全隐患;而 Podman 有原生且完善的 rootless 模式
- 更易使用。Docker 需要先启动守护进程;而 Podman 不需要
如果不使用 Docker Desktop,只使用 Docker CLI,那么启动一个容器会非常麻烦。下面是在 Windows 系统里使用 Docker 运行一个容器需要的步骤
# 安装 Docker CLIscoop install docker# 然后以管理员权限启动新的终端,因为后面的命令需要管理员权限# 将守护进程注册为服务dockerd --register-service# 启动守护进程sasv dockerd# 运行容器docker run hello-world这时你大概率会得到一个报错。因为在 Windows 上 dockerd 只支持运行 Windows 容器。一个可能正确的做法应该是这样的
- 在 WSL 里安装 Docker 并启动守护进程
dockerd。当然,这个过程是需要 root 权限的 - 在 Windows 里安装 Docker,并通过配置让 Windows 里的
docker连接到 WSL 里的dockerd
而在 Windows 里使用 Podman CLI 运行容器就比较简单
# 安装 Podman CLIscoop install podman# 初始化一个 WSL 虚拟机podman machine init# 启动并连接到虚拟机podman machine start# 运行容器podman run hello不需要新打开一个管理员权限的终端,不需要复杂的配置。除了可能的网络问题外,即使是第一次使用也基本上不会遇到报错
Windows
Section titled “Windows”首先在 Windows 的文件系统里安装 podman
scoop install podman然后初始化 WSL 虚拟机
podman machine init也可以直接在 WSL 里安装 podman
# Ubuntuapt install podman如果 podman 在 Windows 的文件系统里安装,那么在运行别的命令前记得先启动虚拟机
podman machine start# 在 ubi8-micro 容器里运行 date 命令podman run ubi8-micro date# 与 ubi8-micro 容器交互podman run -it ubi8-micro不过 ubi8-micro 这个镜像非常小,只有 25.8 MB,因此功能有限。你可以拉取一个更大的镜像来玩
# 拉取 ubuntu 镜像并运行 bashpodman run -it ubuntu bash# 可以为这个容器实例取个名字podman run -it --name hello-ubuntu ubuntu bash手动构建镜像
Section titled “手动构建镜像”start 和 stop 子命令可以启动容器实例和停止容器实例,其中 CONTAINER-ID 和 CONTAINER-NAME 可以通过 podman ps -a 查看
# 启动容器实例podman start -ai CONTAINER-ID/CONTAINER-NAME# 停止容器实例podman stop CONTAINER-ID/CONTAINER-NAMEexec 子命令可以让一个正在运行的容器实例执行命令。如果遇到问题,我们可以使用它来进行容器的调试
podman exec -it CONTAINER-ID/CONTAINER-NAME bash当你对容器做出了一些修改后,可以通过 commit 进行保存
podman commit CONTAINER-ID/CONTAINER-NAME NEW-IMAGE-NAME这会本地生成一个新的镜像,然后你可以基于这个镜像再创建新的容器实例
自动构建镜像
Section titled “自动构建镜像”除了通过 podman run -it ubuntu bash 这种方式在交互式 shell 会话中对容器进行操作外,还有别的修改容器的方式,比如 podman container cp index.js hello-node:/usr/src/app/index.js 可以把本地文件 index.js 复制到 hello-node 容器的 /usr/src/app/index.js 位置
不过,以上这些自己手动修改容器,再保存为新镜像的做法不是创建容器镜像的最佳方法。一个更好的方法是使用 Dockerfile,这通过一个配置文件来让创建镜像的过程自动化
FROM node:20
WORKDIR /usr/src/app
COPY ./index.js ./index.js
CMD node index.js以上示例非常简单,你可以在 Docker 官方文档 里获得更详细的参考。有了 Dockerfile 后修改容器构建新镜像就变得非常简单了
# 根据配置文件自动构建镜像podman build -t node-hello-world .然后可以照常使用这个容器
# 运行容器podman run node-hello-world# 可以覆盖默认的命令podman run -it node-hello-world bash# 还可以把主机端口映射到容器端口podman run -p 3000:3000 express-server显然像 podman run -p 3000:3000 express-server 这样的命令有点长,不仅需要我们记住端口的映射,还需要记住镜像的名字。如果我们的应用要启动非常多个容器,这会很麻烦。因此就有了 docker compose 这种工具帮我们管理容器
podman 可以直接使用 docker-compose,这也是默认的行为。而 podman-compose 在 Windows 环境里好像有点问题
安装 docker-compose 时建议把 docker 也一起安装了
# Windowsscoop install docker docker-compose一个简单的 docker-compose.yml 示例如下,更详细的内容请参考 Docker 官方文档
services: app: image: express-server build: . ports: - 3000:3000有了 docker-compose.yml 管理容器就会变得非常轻松
# 启动服务podman compose up# 关闭服务podman compose down# 重新构建镜像并启动服务podman compose up --build# 后台运行服务podman compose up -d# -f 参数可以指定文件podman compose -f docker-compose.dev.yml up -d以下命令可以用来管理存储空间
# 列出存储概览podman system df# 列出存储详情podman system df -v# 一键清理podman system prune或者你也可以手动删除指定的容器或镜像
# 删除指定容器podman container rm CONTAINER-ID/CONTAINER-NAME# 删除所有容器podman container rm --all# 删除指定镜像podman image rm IMAGE-ID/IMAGE-NAME# 删除所有镜像podman image rm --all