【Docker】P2 Docker 命令:从Nginx部署到镜像分享的全流程指南
目录
- 镜像操作 (Image)
- 检索与发现镜像
- 下载镜像
- 查看本地镜像
- 删除镜像
 
- 容器操作 (Container)
- 启动第一个容器
- 查看容器
- 容器的生命周期管理
- 删除
- 停止
- 强制删除
- 启动/重启
 
 
- 深入 docker run
- 后台运行与命名
- 端口映射
 
- 修改 Nginx 首页
- 进入运行中的容器
- 修改 html 文件
- 验证与思考
 
- 保存容器为新的镜像文件
- 提交容器
- 镜像的导入与导出
 
- 分享镜像
- 登录仓库
- 标记镜像
 

欢迎来到本期的 Docker 教程!今天,我们将通过一个完整的流程化实例,带你走过 Docker 最核心的命令操作。
这个完整的流程为:
下载镜像 ➡️ 启动容器 ➡️ 修改应用 ➡️ 保存为新镜像 ➡️ 分享社区
镜像操作 (Image)
在 Docker 的世界里,一切都始于镜像 (Image)。你可以把镜像想象成一个“安装包”,它是一个只读的模板,打包了运行应用所需的所有文件、依赖和配置。
镜像操作的主要命令包含:
- 搜索镜像:
docker search- 下载镜像:
docker pull- 查看本地镜像:
docker images- 删除镜像:
docker rmi
检索与发现镜像
我们首先需要一个 Nginx 镜像。去哪里找呢?
- 命令行检索(docker search): 你可以使用docker search nginx来快速查找。
- 更推荐: 访问 Docker Hub,官方的镜像仓库。在这里搜索 nginx,你能直观的看到社区中所有的 nginx 镜像文件,包含: - Official Image (官方镜像): 带有 “Official” 标签,由 Docker 官方或应用官方维护,是我们的首选。
- 社区镜像: 如 bitnami/nginx,由第三方维护。
- 下载量 (Pulls) 和星标 (Stars): 这是判断镜像质量和受欢迎程度的重要依据。
 
下载镜像
让我们来使用官方的 nginx 镜像。
docker pull nginx
这个命令其实是一个简写。完整的命令格式是
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
- NAME 为镜像名,这里是 nginx。
- [:TAG] 标签版本号,用于区分不同版本,选填,默认值为 :latest
查看本地镜像
下载完成后,我们使用 docker images 来查看本地已有的所有镜像。
docker images
你会看到一个列表:
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
nginx         latest    605c75e6e14c   3 weeks ago    141.5MB
让我们来详细解析每一列的含义:
- REPOSITORY: 镜像仓库名称
- TAG: 镜像标签(版本)
- IMAGE ID: 镜像的唯一标识符,一个SHA256哈希值
- CREATED: 镜像的创建时间
- SIZE: 镜像文件占用的存储空间
删除镜像
如果某个镜像不再需要,可以使用 docker rmi (remove image) 删除它。
docker rmi [OPTIONS] [IMAGE_ID 或 REPOSITORY:TAG]
# 例如:docker rmi 605c75e6e14c
- 注意: 如果一个镜像已经被某个容器(哪怕是已停止的容器)所使用,你是无法直接删除它的。你必须先删除所有使用该镜像的容器(详见下文 docker rm),或者在命令中[OPTIONS]部分使用-f强制删除(不推荐)。
容器操作 (Container)
有了镜像(安装包),我们就可以运行它,创建容器 (Container)。容器是镜像的运行时实例,是一个被隔离的、正在运行的应用环境。
容器操作的主要命令包含:
- 启动容器:
docker run- 查看容器:
docker ps- 删除容器:
docker rm- 停止容器:
docker stop- 启动容器:
docker start- 重启容器:
docker restart
启动第一个容器
我们以最简单的方式启动 Nginx:
docker run nginx
问题出现: 你会发现,Nginx 启动后,你的命令行被占用了,日志在前台不断输出。如果你按下 Ctrl+C 退出,容器也会随之停止。这显然不是我们想要的。
对此,我们的解决策略为在 run 命令中添加 -d 的 OPTIONS,具体原因我们稍后详述。
docker run -d nginx
查看容器
我们如何查看容器的状态?应用 docker ps 命令
- docker ps:查看正在运行中的容器。
- docker ps -a:查看所有的容器(包括已停止的)。
我们执行 docker ps:
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
f3e6a0d4a7d1   nginx     "/docker-entrypoint.…"   2 minutes ago    UP 2 minutes ago              jolly_bose
我们来解析 docker ps 展示出的列的含义:
- CONTAINER ID:容器的唯一身份ID
- IMAGE: 创建该容器所用的镜像
- COMMAND: 容器启动时执行的命令,命令为内部命令,忽略
- CREATED: 容器的创建时间
- STATUS: 容器当前的状态。- Up(运行中),- Exited(已停止)。
- PORTS: 容器的端口映射情况(稍后详述)。
- NAMES: 容器的名称。如果你不指定,Docker 会分配一个随机的名称,如本示例中的 jolly_bose。
容器的生命周期管理
假设,我们来清理一个“已停止”的容器 my_app。
删除
docker rm my_app
# 或者使用 ID: docker rm f3e6a0d4a7d1
停止
docker rm 只能删除已停止的容器。如果容器正在运行,你需要先停止它:
# 假设有一个运行中的容器 "my_app"
docker stop my_app
# 或者使用 ID: docker stop f3e6a0d4a7d1
强制删除
如果你想一步到位,可以使用 -f 强制删除一个正在运行的容器(它会先 stop 再 rm)。
docker rm -f my_app
# 或者使用 ID: docker rm -f f3e6a0d4a7d1
启动/重启
对于已停止的容器,可以使用 docker start 重新启动它。
docker start jolly_bose
# 或者使用 ID: docker start f3e6a0d4a7d1
docker restart jolly_bose # 重启
# 或者使用 ID: docker restart f3e6a0d4a7d1
深入 docker run
docker run 是 Docker 中最重要、最复杂的命令。我们现在用更合理的方式来启动 Nginx,解决之前遇到的两个问题:
- 前台运行,占用终端。
- 容器运行了,但我们从主机(电脑)无法访问。
为了解决上述两个问题,我们对
run补充三个 OPTIONS:
-d:运行在后台
--name:起名
-p:端口映射
后台运行与命名
我们使用 -d (Detached) 参数,让容器在后台运行。同时,使用 --name 给容器起一个好记的名字。
docker run -d --name mynginx nginx
执行后,它只会返回一个容器ID,终端不会被占用。
此时,我们用 docker ps 查看:
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
a1b2c3d4e5f6   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   80/tcp    mynginx
STATUS 显示 Up,NAMES 是我们指定的 mynginx。
端口映射
现在容器在后台运行了。我们尝试在浏览器访问 http://localhost:80 或 http://IP:80 失败了。
这是为什么呢? Docker 容器是隔离的。当你启动 mynginx 容器时,它在自己的“小黑屋”(独立的网络空间)里运行。Nginx 在这个小黑屋里监听了 80 端口。但是,我们的主机(你的电脑)并不知道这个小黑屋的存在,更无法访问它内部的 80 端口。
我们需要在主机和小黑屋之间架设一座桥梁,这就是端口映射 (-p)。
# 语法: -p [宿主机端口]:[容器端口]
让我们删掉刚才的容器,用正确的方式重新启动:
# 1. 先停止并删除旧的
docker rm -f mynginx# 2. 启动新容器,并添加端口映射
docker run -d --name mynginx -p 88:80 nginx
命令解析:
- -p 88:80:将主机的- 88端口映射到容器的- 80端口。
现在,访问 http://localhost:88 的所有请求,都会被 Docker 自动转发到 mynginx 容器内部的 80 端口上。
修改 Nginx 首页
我们成功运行了 Nginx,但我们想修改默认的欢迎页面。此时,我们需要进入 mynginx 容器的内部,修改 Nginx 存放 index.html 的默认路径(通常是 /usr/share/nginx/html)
主要涉及命令:
exec:进入到运行的容器中
进入运行中的容器
docker exec 命令允许我们在一个正在运行的容器中执行命令。
docker exec -it mynginx /bin/bash
命令解析:
- exec:进入容器固定指令,无他意
- -it:这是两个参数的合写,无需深究:- -I:保持标准输入(STDIN)打开,允许我们与 shell 交互
- -t:分配一个伪终端(pseudo-TTY),给我们一个像在真实服务器上操作的命令行提示符
 
- mynginx:目标容器的名称
- /bin/bash:我们要在容器内执行的命令。- bash是一个常见的 shell(有些轻量级镜像可能只有 /bin/sh)。
修改 html 文件
下一步,让我们来修改这份 index.html 文件:
cd /usr/share/nginx/html
# 查看文件:
ls
# 你会看到 index.html 和 50x.html
# 修改 index.html
echo "<h1>Hello! This is My Custom Nginx Page!</h1>" > index.html
验证与思考
此时,回到我们的浏览器,刷新 http://localhost:88。你会发现页面内容已经变成了 “Hello! This is My Custom Nginx Page!”。
实际上,读者在实操时也能感受到,每次都 exec 进去修改文件非常不方便,而且如果容器被删除(docker rm mynginx),所有修改都会丢失。 后面,我们将介绍更实用的技能,应用 Volume(卷)映射 (-v),将主机目录直接映射到容器内,实现文件持久化和实时同步。
保存容器为新的镜像文件
我们已经修改了 mynginx 容器。如果我们希望把这个“被修改过的状态”保存下来,变成一个新的镜像(例如 my-custom-nginx:1.0),以便将来重复使用或分享,该怎么办?
主要涉及命令:
commit:容器封装为镜像
save -o:镜像保存为 .tar 文件
load -I:.tar 文件导入为镜像
提交容器
docker commit 可以从一个容器的当前状态,封装打包为一个新的镜像。
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS 常用选项:
- -a:作者(Author),例如 “Your Name”
- -m:提交信息(Message),类似 Git commit message
操作: 我们将正在运行的 mynginx 容器,提交为一个名为 my-custom-nginx、标签为 1.0 的新镜像。
docker commit -a "My Blog User" -m "Customized index.html" mynginx my-custom-nginx:1.0
验证: 执行 docker images:
REPOSITORY          TAG       IMAGE ID       CREATED          SIZE
my-custom-nginx     1.0       a9c5b0c8d6e3   5 seconds ago    141.5MB  <-- 我们新创建的
nginx               latest    605c75e6e14c   3 weeks ago      141.5MB
我们成功制作了一个新镜像!
镜像的导入与导出
docker commit 创建的镜像是保存在本地的。如果我想把这个镜像拷贝给没有网络的同事,该怎么办?
- 保存 (save):- docker save命令可以将一个镜像打包成一个- .tar文件。- docker save -o my-nginx-image.tar my-custom-nginx:1.0- -o:指定输出文件(output)。执行后,当前目录会多一个- my-nginx-image.tar文件。
 
- 加载 (load): 你的同事拿到这个 .tar文件后,使用docker load命令将其导入到自己的 Docker 中。docker load -i my-nginx-image.tar- -i:指定输入文件(input)。执行后,再- docker images就能看到- my-custom-nginx:1.0了。
 
分享镜像
将镜像打包成 tar 文件只适合小范围分享。如果我们希望全世界的开发者都能使用我们的镜像,我们应该将其分享到 Docker Hub,注意,需要科学上网。
登录仓库
首先,你需要在 Docker Hub 网站注册一个账号。假设你的用户名是 myusername。 然后在命令行登录:
docker login
# Username: myusername
# Password: 
# Login Succeeded
标记镜像
这是非常关键的一步。如果你想把镜像推送到 Docker Hub,你必须给镜像一个“符合规范”的名称。
Docker Hub 的规范是:[你的用户名]/[仓库名]:[标签]
