Docker run 命令参数

DockerBeginner
立即练习

简介

本实验专门介绍 docker run 命令及其各种参数。docker run 是 Docker 的基础命令,可用于创建并启动按指定配置运行的容器。

掌握该命令的参数后,你就能更好地控制容器化应用,从而更有效地部署和管理 Docker 容器。

本实验将介绍多种参数,包括用于设置容器名称、以分离模式运行、映射端口、挂载卷、设置环境变量、限制资源等的参数。

其中有些参数你可能已经熟悉,有些则可能是第一次接触。

Docker run 基础与容器命名

本步骤从 docker run 的基础用法开始,并介绍如何为容器命名。

先运行一个基础的 Nginx 容器:

docker run nginx

这条命令会在前台运行 Nginx 容器。你会在终端中看到持续输出的日志,因为容器正在前台运行,日志会直接显示在终端中。

按 Ctrl+C 停止容器。容器可能需要几秒钟才能停止,这是正常的:Docker 会留出时间,让容器正常关闭。

接下来,以分离模式运行容器并为其指定名称:

docker run -d --name my-nginx nginx

下面逐项说明这条命令:

  • docker run:运行容器的基础命令。
  • -d:以分离模式运行容器,也就是在后台运行。终端不会显示容器的输出。
  • --name my-nginx:将容器命名为「my-nginx」。如果不指定名称,Docker 会自动分配一个随机名称。
  • nginx:用于创建容器的镜像名称。

运行命令后,你会看到一串较长的字符,这是容器 ID。此时 Docker 已在后台启动容器。

如果遇到提示名称已被占用的错误,说明已有容器使用了该名称。你可以改用其他名称,也可以删除已有容器(后续实验会介绍如何删除容器)。

端口映射

本步骤使用 docker run 的 -p 参数,将容器端口映射到主机端口。这样,你就可以从主机访问容器内运行的服务。

运行一个配置了端口映射的 Nginx 容器:

docker run -d --name nginx-mapped -p 8080:80 nginx

下面说明这条命令中的新参数:

  • -p 8080:80:将主机的 8080 端口映射到容器的 80 端口。格式始终为 host_port:container_port。

Nginx 默认在容器内使用 80 端口。将该端口映射到主机的 8080 端口后,你就可以在 Web 浏览器中访问 localhost:8080。

接下来,用 curl 检查是否能访问 Nginx 欢迎页。curl 可以在命令行中发送 HTTP 请求:

curl --retry 5 --retry-all-errors --retry-delay 1 http://localhost:8080

你应该会看到 Nginx 欢迎页的 HTML 内容。如果尚未安装 curl,可以运行以下命令安装:

sudo apt-get update && sudo apt-get install -y curl

如果仍然无法访问页面,可以检查以下几项:

  • 确认容器正在运行:docker ps | grep nginx-mapped
  • 确认端口已映射:docker port nginx-mapped
  • 如果你使用的是云服务器,请确认防火墙允许通过 8080 端口的流量。

卷挂载

本步骤使用 docker run 的 -v 参数挂载卷,在主机和容器之间共享数据。这种方式适用于持久化数据,或向容器提供配置文件。

先在主机上创建一个简单的目录结构:

mkdir -p ~/project/nginx-data
echo "<html><body><h1>Hello from mounted volume</h1></body></html>" > ~/project/nginx-data/index.html

这两条命令会执行以下操作:

  • 在主目录中的 project 目录下创建 nginx-data 目录。
  • 在新建的目录中创建名为 index.html 的简单 HTML 文件。

接下来,运行 Nginx 容器并挂载该目录:

docker run -d --name nginx-volume -p 8081:80 -v ~/project/nginx-data:/usr/share/nginx/html nginx

下面逐项说明这条命令:

  • docker run:运行新容器的命令。
  • -d:以分离模式运行容器,也就是在后台运行。
  • --name nginx-volume:将容器命名为「nginx-volume」。
  • -p 8081:80:将主机的 8081 端口映射到容器的 80 端口。
  • -v ~/project/nginx-data:/usr/share/nginx/html:将主机上的 nginx-data 目录挂载到容器内的 /usr/share/nginx/html 目录。Nginx 会从该目录读取要提供的网页内容。
  • nginx:用于创建容器的镜像名称。

现在,检查自定义页面是否已成功提供:

curl --retry 5 --retry-all-errors --retry-delay 1 http://localhost:8081

你应该会看到自定义 HTML 文件的内容:「Hello from mounted volume!」。

如果没有看到自定义内容,可以检查以下几项:

  • 确认主机上的 ~/project/nginx-data/index.html 文件存在。
  • 确认容器正在运行:docker ps | grep nginx-volume
  • 检查 Nginx 日志中是否有错误:docker logs nginx-volume

将主机目录挂载到容器中的方法称为绑定挂载。这是一种在主机和容器之间共享文件的直接方式。请记住以下几点:

  • 主机目录必须使用绝对路径。
  • 如果主机目录不存在,Docker 会自动创建该目录。
  • 在该目录中的文件(无论是在主机上还是容器中)发生更改后,主机和容器会立即看到这些更改。
  • 注意权限问题:容器默认以 root 身份运行,因此可能会创建主机用户无法修改的文件。

使用这种方法可以避免「not a directory」错误,因为挂载的是目录,而不是单个文件。这样,你就可以灵活地添加、删除或修改文件,而无需重新创建容器。

环境变量

本步骤使用 docker run 的 -e 参数在容器中设置环境变量。这样可以在不修改应用代码的情况下配置应用。

运行一个带有环境变量的容器:

docker run -d --name nginx-env -e NGINX_HOST=mywebsite.com -e NGINX_PORT=80 nginx

下面说明新增的参数:

  • -e NGINX_HOST=mywebsite.com:设置名为 NGINX_HOST、值为 mywebsite.com 的环境变量。
  • -e NGINX_PORT=80:设置另一个环境变量 NGINX_PORT,其值为 80。

环境变量由键值对组成,容器内运行的进程可以读取这些变量。许多 Docker 镜像会使用特定的环境变量进行配置。

运行以下命令,检查环境变量是否已设置:

docker exec nginx-env env | grep NGINX_

这条命令会执行以下操作:

  • docker exec nginx-env:让 Docker 在正在运行的 nginx-env 容器中执行命令。
  • env:打印所有环境变量。
  • | grep NGINX_:筛选输出,只显示包含「NGINX_」的行。

你应该会看到刚才设置的两个环境变量。

如果没有看到这些环境变量,请检查:

  • 容器是否正在运行?运行 docker ps | grep nginx-env 进行确认。
  • docker run 命令中的环境变量名称是否拼写正确?

资源限制

本步骤使用 docker run 的参数为容器设置资源限制。管理主机系统的性能和稳定性时,这一点很重要,尤其是在同时运行多个容器的情况下。

运行一个设置了内存和 CPU 限制的容器:

docker run -d --name nginx-limited --memory 256m --cpus 0.5 nginx

下面说明新增的参数:

  • --memory 256m:将容器可用内存限制为 256 MB。m 表示 MB,也可以用 g 表示 GB。
  • --cpus 0.5:将容器的 CPU 使用量限制为最多半个 CPU 核心。

这些限制可以防止容器使用超过指定上限的资源,避免单个容器独占主机资源。

运行以下命令,检查这些限制是否已正确应用:

docker inspect -f '{{.HostConfig.Memory}}' nginx-limited
docker inspect -f '{{.HostConfig.NanoCpus}}' nginx-limited

第一条命令应该输出 268435456(256 MB 换算成字节后的值),第二条命令应该输出 500000000(以纳核为单位表示的 0.5 个 CPU)。

如果输出的值不同,请重新检查 docker run 命令,确认资源限制设置正确。

注意:资源限制设置得过低,可能会导致容器运行缓慢,甚至崩溃。如果容器运行异常,可以尝试提高这些限制。

网络设置

本步骤使用 docker run 的 --network 参数将容器连接到某个网络。这适用于容器之间的通信,也可以隔离不同的容器组。

先创建一个自定义桥接网络:

docker network create my-custom-network

这条命令会创建名为 my-custom-network 的桥接网络。桥接网络是 Docker 中最常见的网络类型。

接下来,运行一个连接到该网络的容器:

docker run -d --name nginx-networked --network my-custom-network nginx

--network my-custom-network 参数会将容器连接到刚才创建的网络。

同一网络中的容器可以使用彼此的容器名称作为主机名进行通信。这样可以方便地将多个服务连接起来。

如果出现网络不存在的错误,请确认已使用 docker network create 命令正确创建网络。

重启策略

本步骤使用 docker run 的 --restart 参数为容器设置重启策略。这样,即使容器崩溃或 Docker 守护进程重启,也能帮助容器继续运行。

运行一个设置了重启策略的容器:

docker run -d --name nginx-restart --restart unless-stopped nginx

--restart unless-stopped 参数会将重启策略设为 unless-stopped,也就是说,除非用户明确停止容器,否则容器会自动重启。

其他重启策略包括:

  • no:默认策略,不自动重启容器。
  • on-failure:仅当容器以非零状态退出时才重启。
  • always:无论容器以何种状态退出,都会重启。

运行以下命令,检查重启策略:

docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' nginx-restart

命令应该输出 unless-stopped。

如果输出不符合预期,请重新检查 docker run 命令,确认重启策略设置正确。

工作目录与命令

本步骤介绍如何设置容器内的工作目录,以及如何在容器启动时运行自定义命令。

docker run 的 -w 参数用于设置容器内的工作目录。镜像名称后面可以指定要运行的命令。

下面组合使用这两种设置:

docker run -d --name nginx-custom -w /app nginx sh -c "mkdir -p /app && touch newfile.txt && nginx -g 'daemon off;'"

下面逐项说明这条命令:

  • -d:以分离模式运行容器,也就是在后台运行。
  • --name nginx-custom:将容器命名为「nginx-custom」。
  • -w /app:将容器内的工作目录设为 /app。
  • nginx:要使用的镜像名称。
  • sh -c "...":运行一条 shell 命令。
    • mkdir -p /app:如果 /app 目录不存在,就创建该目录。
    • &&:只有前一条命令成功时,才运行下一条命令。
    • touch newfile.txt:创建名为 newfile.txt 的空文件。
    • &&:只有前一条命令成功时,才运行下一条命令。
    • nginx -g 'daemon off;':在前台启动 Nginx,使容器保持运行。

接下来,检查容器是否正在运行,以及文件是否已创建:

docker ps | grep nginx-custom
docker exec nginx-custom ls -l /app/newfile.txt

第一条命令应该显示容器正在运行。第二条命令应该列出容器内 /app 目录中 newfile.txt 文件的详细信息。

总结

本实验深入介绍了 docker run 命令及其各种参数和选项,涵盖以下内容:

  1. 运行容器的基础用法与容器命名
  2. 将容器服务的端口映射到主机,以便从主机访问服务
  3. 挂载卷,在主机和容器之间共享数据
  4. 设置环境变量来配置容器
  5. 设置资源限制,限制容器的资源使用量
  6. 设置网络,支持容器之间的通信
  7. 设置重启策略,提高容器运行的可靠性
  8. 设置工作目录和启动命令

docker run 的这些参数为配置和管理 Docker 容器提供了强大工具。掌握这些选项后,你就能部署更复杂、更符合需求的容器。你可以控制容器与主机系统的交互方式、容器可使用的资源,以及容器在不同情况下的行为。