目录
- 镜像操作 (Image)
- 容器操作 (Container)
- [深入 docker run](#深入 docker run)
- [修改 Nginx 首页](#修改 Nginx 首页)
- 保存容器为新的镜像文件
- 分享镜像
- 总结

欢迎来到本期的 Docker 教程!今天,我们将通过一个完整的流程化实例,带你走过 Docker 最核心的命令操作。
这个完整的流程为:
bash
下载镜像 ➡️ 启动容器 ➡️ 修改应用 ➡️ 保存为新镜像 ➡️ 分享社区
镜像操作 (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 镜像。
bash
docker pull nginx
这个命令其实是一个简写。完整的命令格式是
bash
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
- NAME 为镜像名,这里是 nginx。
- [:TAG] 标签版本号,用于区分不同版本,选填,默认值为 :latest
查看本地镜像
下载完成后,我们使用 docker images 来查看本地已有的所有镜像。
bash
docker images
你会看到一个列表:
bash
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) 删除它。
bash
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:
bash
docker run nginx
问题出现: 你会发现,Nginx 启动后,你的命令行被占用了,日志在前台 不断输出。如果你按下 Ctrl+C 退出,容器也会随之停止。这显然不是我们想要的。
对此,我们的解决策略为在 run 命令中添加 -d 的 OPTIONS,具体原因我们稍后详述。
bash
docker run -d nginx
查看容器
我们如何查看容器的状态?应用 docker ps 命令
docker ps:查看正在运行中的容器。docker ps -a:查看所有的容器(包括已停止的)。
我们执行 docker ps:
bash
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:容器的唯一身份IDIMAGE: 创建该容器所用的镜像COMMAND: 容器启动时执行的命令,命令为内部命令,忽略CREATED: 容器的创建时间STATUS: 容器当前的状态。Up(运行中),Exited(已停止)。PORTS: 容器的端口映射情况(稍后详述)。NAMES: 容器的名称。如果你不指定,Docker 会分配一个随机的名称,如本示例中的 jolly_bose。
容器的生命周期管理
假设,我们来清理一个"已停止"的容器 my_app。
删除
bash
docker rm my_app
# 或者使用 ID: docker rm f3e6a0d4a7d1
停止
docker rm 只能删除已停止的容器。如果容器正在运行,你需要先停止它:
bash
# 假设有一个运行中的容器 "my_app"
docker stop my_app
# 或者使用 ID: docker stop f3e6a0d4a7d1
强制删除
如果你想一步到位,可以使用 -f 强制删除一个正在运行的容器(它会先 stop 再 rm)。
bash
docker rm -f my_app
# 或者使用 ID: docker rm -f f3e6a0d4a7d1
启动/重启
对于已停止的容器,可以使用 docker start 重新启动它。
bash
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 给容器起一个好记的名字。
bash
docker run -d --name mynginx nginx
执行后,它只会返回一个容器ID,终端不会被占用。
此时,我们用 docker ps 查看:
bash
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)。
bash
# 语法: -p [宿主机端口]:[容器端口]
让我们删掉刚才的容器,用正确的方式重新启动:
bash
# 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 命令允许我们在一个正在运行的容器中执行命令。
go
docker exec -it mynginx /bin/bash
命令解析:
exec:进入容器固定指令,无他意-it:这是两个参数的合写,无需深究:-I:保持标准输入(STDIN)打开,允许我们与 shell 交互-t:分配一个伪终端(pseudo-TTY),给我们一个像在真实服务器上操作的命令行提示符
mynginx:目标容器的名称/bin/bash:我们要在容器内执行的命令。bash是一个常见的 shell(有些轻量级镜像可能只有 /bin/sh)。
修改 html 文件
下一步,让我们来修改这份 index.html 文件:
bash
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 可以从一个容器的当前状态,封装打包为一个新的镜像。
bash
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS 常用选项:
-a:作者(Author),例如 "Your Name"-m:提交信息(Message),类似 Git commit message
操作: 我们将正在运行的 mynginx 容器,提交为一个名为 my-custom-nginx、标签为 1.0 的新镜像。
bash
docker commit -a "My Blog User" -m "Customized index.html" mynginx my-custom-nginx:1.0
验证: 执行 docker images:
bash
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文件。bashdocker save -o my-nginx-image.tar my-custom-nginx:1.0-o:指定输出文件(output)。执行后,当前目录会多一个my-nginx-image.tar文件。
-
加载 (load): 你的同事拿到这个
.tar文件后,使用docker load命令将其导入到自己的 Docker 中。bashdocker load -i my-nginx-image.tar-i:指定输入文件(input)。执行后,再docker images就能看到my-custom-nginx:1.0了。
分享镜像
将镜像打包成 .tar 文件只适合小范围分享。如果我们希望全世界的开发者都能使用我们的镜像,我们应该将其分享到 Docker Hub。注意,需要科学上网。
主要涉及命令:
login:登录官方 Hub 系统tag:更改镜像名称为符合官方格式要求的名称push:将本地镜像推送到全世界都可以访问的 docker hub 社区中
登录仓库
首先,你需要在 Docker Hub 网站注册一个账号。假设你的用户名是 myusername。 然后在命令行登录:
bash
docker login
# Username: myusername
# Password:
# Login Succeeded
标记镜像
在登录完成后,标记镜像是非常关键的一步。如果你想把镜像推送到 Docker Hub,你必须给镜像一个符合官方规范要求的名称。我们可以应用 tag 命令来重命名。
Docker Hub 对于镜像名称的规范是:[你的用户名]/[仓库名]:[标签]
我们本地的镜像叫 my-custom-nginx:1.0,这不符合规范。我们需要使用 docker tag 给它起一个"别名":
bash
# 格式: docker tag [源镜像] [目标镜像(带用户名)]
docker tag my-custom-nginx:1.0 myusername/my-custom-nginx:1.0
验证: 再次执行 docker images,你会发现:
bash
REPOSITORY TAG IMAGE ID
my-custom-nginx 1.0 a9c5b0c8d6e3
myusername/my-custom-nginx 1.0 a9c5b0c8d6e3 <-- 新增的、符合 Docker Hub 规范的
nginx latest 605c75e6e14c
它们共享同一个 IMAGE ID,本质上是同一个镜像的两个不同标签。
推送镜像
最后,将我们新标记的镜像推送到 Docker Hub:
bash
docker push myusername/my-custom-nginx:1.0
等待上传完成后,任何人(包括你自己)在世界上任何一台安装了 Docker 的机器上,都可以通过执行 docker pull myusername/my-custom-nginx:1.0 来获取你修改过的 Nginx 镜像了!
总结
恭喜你!我们从一个最基础的 nginx 官方镜像出发,经历了 pull, run, ps, exec, commit, tag, push 等一系列核心操作,走完了一个完整的 Docker"开发-打包-分发"的生命周期。
你是否想继续了解如何使用 Dockerfile 来自动化构建镜像,或者如何使用 Volume 来管理持久化数据?请期待后续博文!
2025.10.30 G38 回北京途中