Linux容器篇、第一章_02Rocky9.5 系统下 Docker 的持久化操作与 Dockerfile 指令详解
Linux_docker篇
欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神!
题目:Rocky9.5 系统下 Docker 的持久化操作与 Dockerfile 指令详解
版本号: 1.0,0
作者: @老王要学习
日期: 2025.05.28
适用环境: Rocky9.5
文档说明
本文围绕 Linux 系统下 Docker 的使用展开,涵盖环境准备,包含硬件和软件要求。介绍持久化集成操作,如清除镜像、修改网页持久化等;还阐述 Dockerfile 多种指令用法,如 VOLUME、USER 等。提供操作示例与命令,适用于学习 Docker 的人员参考
环境准备
硬件要求
- 服务器: 2核CPU、2GB内存,20GB硬盘空间
- 网络: 确保服务器具有固定的IP地址,并且防火墙允许FTP端口(默认22端口)的通信
软件要求
- 操作系统:Rocky9.5
- FTP软件:SecureCRT
- 软件包:
一、持久化集成
1.1清除镜像
# 备份Rocky9
docker save -o rk9.tar rockylinux:9 # 我们做的例子越来越多,删除全部镜像
docker rm -f $(docker ps -aq)
docker rmi $(docker images -qa)# 查看镜像
docker images
#输出如下:
REPOSITORY TAG IMAGE ID CREATED SIZE
mydf v1 9cc24f05f309 18 months ago 176MB
rockylinux 9 9cc24f05f309 18 months ago 176MB# 在单独删除这两个镜像
docker rmi mydf:v1
#输出如下:
Untagged: mydf:v1docker rmi rockylinux:9
#输出如下:
Untagged: rockylinux:9
Untagged: rockylinux@sha256:d7be1c094cc5845ee815d4632fe377514ee6ebcf8efaed6892889657e5ddaaa6
Deleted: sha256:9cc24f05f309508aa852967ab1e3b582b302afc92605c24ce27715c683acd805# 查看镜像全部清除
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE# 导入备份镜像
docker load -i lwimages.tar
docker load -i rk9.tar
1.2修改NGINX的web网页(不持久化)
# 启动NGINX服务
docker run -d -p 88:80 nginx:latest
docker exec -it cbc66b46672 bash# 修改web网页
root@cbc66b466727:/# echo "lw web test" > /usr/share/nginx/html/index.html # 查看网页
curl localhost:88
lw web test# 删除容器
docker kill cbc66b466727
cbc66b466727
docker rm cbc66b466727
cbc66b466727# 在次启动进入容器docker run -d -p 88:80 nginx:latest
0c9736959030a365c1a67ef2844ad23529b4d1dcb92e514279aa6387851f160b# 查看web网页(回复默认)
curl localhost:88
1.3修改web网页(持久化)
# 删除容器
docker kill 0c973695
0c973695
docker rm 0c973695
0c973695# 创建目录
mkdir /myweb# 启动并挂载目录(将宿主机的/myweb挂载到容器 /usr/share/nginx/html目录)
docker run --name web -d -p 88:80 -v /myweb:/usr/share/nginx/html nginx:latest
#输出如下:
d5db1e7ad13fc674506e8261e211634c1c1a780a1c5dea5b198bb8f77d127439# 进入容器写入数据
docker exec -it d5db1e7ad13fc67 bash
root@d5db1e7ad13f:/# echo "lw web test" > /usr/share/nginx/html/index.html # 删除容器
docker kill web
web
docker rm web
web# 再次启动容器
docker run --name web -d -p 88:80 -v /myweb:/usr/share/nginx/html nginx:latest
#输出如下:
d60f08a775354e70dfc71ddae67e0fba5b86fb94ba274ffe7f95baa53391bd17# 查看web网页信息(持久化完成)curl localhost:88
lw web test
1.4挂载到卷
# 启动容器
docker run -d -p 89:80 --name web02 -v /usr/share/nginx/html/ nginx:latest
#输出如下:
ec48d062b4022102eba8178f6ff6e3e53ce9d3fc5167ba039d1d9abd37af59e2# 查看网页
curl localhost:89# 查看web02信息
docker inspect web02
#输出如下: "Name": "overlay2"},"Mounts": [{"Type": "volume","Name": "e0d65f09d3c0a5ac316fe89430780932414fa4984fa444c8ea155cbd2a4c3202","Source": "/var/lib/docker/volumes/e0d65f09d3c0a5ac316fe89430780932414fa4984fa444c8ea155cbd2a4c3202/_data", <<<<<<<<<< # 卷地址"Destination": "/usr/share/nginx/html","Driver": "local","Mode": "","RW": true,"Propagation": ""}
# 进入查看卷内信息
cd /var/lib/docker/volumes/e0d65f09d3c0a5ac316fe89430780932414fa4984fa444c8ea155cbd2a4c3202/_data# 写入新的web网页
echo "lw web test" > index.html # 再次访问web网页
curl localhost:89
lw web test# 结论
挂载到卷,可以进入容器进行修改web网页,也可以早卷中直接修改
1.5删除卷
# 我在创建多个卷
docker run -d -p 90:80 --name web03 -v /usr/share/nginx/html/ nginx:latest
docker run -d -p 91:80 --name web04 -v
/usr/share/nginx/html/ nginx:latest
docker run -d -p 92:80 --name web05 -v /usr/share/nginx/html/ nginx:latest # 删除全部容器
docker rm -f $(docker ps -a)# 查看卷都存在
docker volume ls
#输出如下:
DRIVER VOLUME NAME
local 5b94e040d5b68f7d807383fd4e67814a6cef4ba7f6628518024ceb4a0bc01557
local ac87ca74646fe2ccb7fa5a5dd0490fe8e697de29845a6d06a1964144b5767e5f
local c96d102580ee08b2cc8d6026c4be6565548a00e944b20cb08cd4d22af06f739c
local c4718c70de5d1a5c13d0b0c2bae0113a67646b47db1bb472033518c02dffe5ea
local e0d65f09d3c0a5ac316fe89430780932414fa4984fa444c8ea155cbd2a4c3202# 我们删除一个容器
docker volume rm 5b94e040d5b68f7d807383fd4e67814a6cef4ba7f6628518024ceb4a0bc01557
5b94e040d5b68f7d807383fd4e67814a6cef4ba7f6628518024ceb4a0bc01557# 查看容器(已删除)
[root@docker-5 volumes]# docker volume ls
DRIVER VOLUME NAME
local ac87ca74646fe2ccb7fa5a5dd0490fe8e697de29845a6d06a1964144b5767e5f
local c96d102580ee08b2cc8d6026c4be6565548a00e944b20cb08cd4d22af06f739c
local c4718c70de5d1a5c13d0b0c2bae0113a67646b47db1bb472033518c02dffe5ea
local e0d65f09d3c0a5ac316fe89430780932414fa4984fa444c8ea155cbd2a4c3202# 删除孤儿卷(我们删除了所以人容器,倒是卷在,这是的卷了没有东西,就是孤儿卷)
docker volume prune
#输出如下:
WARNING! This will remove anonymous local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
ac87ca74646fe2ccb7fa5a5dd0490fe8e697de29845a6d06a1964144b5767e5f
c96d102580ee08b2cc8d6026c4be6565548a00e944b20cb08cd4d22af06f739c
e0d65f09d3c0a5ac316fe89430780932414fa4984fa444c8ea155cbd2a4c3202
c4718c70de5d1a5c13d0b0c2bae0113a67646b47db1bb472033518c02dffe5eaTotal reclaimed space: 206.9MB# 查看当前有的卷(为空)
docker volume ls
#输出如下:
DRIVER VOLUME NAME
二、Dockerfile
2.1VOLUME(卷)
2.1.1写入Dockerfile
echo "VOLUME /lw666" >> /mydockerfile/Dockerfile
2.1.2从 Dockerfile 创建镜像
docker build -t lwvo .#输出如下:
[+] Building 0.1s (5/5) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 226B 0.0s=> [internal] load metadata for docker.io/library/rockylinux:9 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> CACHED [1/1] FROM docker.io/library/rockylinux:9 0.0s=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:01d87fa169d0b82ea1e2cfce29d7f18afdebb85d1eb6781ad73 0.0s=> => naming to docker.io/library/lwvo
2.1.3查看VOLUME挂载
# 启动并查看容器IDdocker run -dit lwvo:latest #输出如下:
f89de21b6bfb25693d94350b1ee7bed23eb19e38ce46eac62f5b797d25114114docker ps -l
#输出如下:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f89de21b6bfb lwvo:latest "/bin/bash" 5 seconds ago Up 5 seconds priceless_bassi```# 查看容器信息
docker inspect f89de21b6b
#输出如下: "Mounts": [{"Type": "volume","Name": "870fadc5dc5afb17df2a9e59e7fac69de40c8471fee389d0685fab7321ce2ed3","Source": "/var/lib/docker/volumes/870fadc5dc5afb17df2a9e59e7fac69de40c8471fee389d0685fab7321ce2ed3/_data","Destination": "/lw666", <<<<<<<<<<<<<<<< # 这里查看到挂载的卷"Driver": "local","Mode": "","RW": true,"Propagation": ""
2.2USR(切换用户)
2.2.1写入Dockerfile
sed -i 's|VOLUME /lw666|#VOLUME /lw666|' /mydockerfile/Dockerfileecho "RUN useradd user1" >> /mydockerfile/Dockerfile
echo "USER user1" >> /mydockerfile/Dockerfile
2.2.2创建镜像
docker build -t user1 .
#输出如下:
[+] Building 0.8s (6/6) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 256B 0.0s=> [internal] load metadata for docker.io/library/rockylinux:9 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> CACHED [1/2] FROM docker.io/library/rockylinux:9 0.0s=> [2/2] RUN useradd user1 0.7s=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:fb698e2a51eb325d936844f3a18f9459ca8d5f058b0b5c732c0 0.0s=> => naming to docker.io/library/user1 0.0s# 运行容器(查看进入user1)
docker run -it user1
[user1@2cf82fa5d004 /]$
2.3WORKDIR(设置工作目录)
2.3.1写入Dockerfile
sed -i 's|USER user1|#USER user1|' /mydockerfile/Dockerfilesed -i 's|RUN useradd user1|#RUN useradd user1|' /mydockerfile/Dockerfileecho "WORKDIR /lw" >> /mydockerfile/Dockerfile
echo "RUN touch test" >> /mydockerfile/Dockerfile
2.3.2创建镜像
docker build -t lwwor .
#输出如下:
[+] Building 0.2s (7/7) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 285B 0.0s=> [internal] load metadata for docker.io/library/rockylinux:9 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> CACHED [1/3] FROM docker.io/library/rockylinux:9 0.0s=> [2/3] WORKDIR /lw 0.0s=> [3/3] RUN touch test 0.2s=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:8a57f509df371df0e8993ca73529500145aabb316b02f8c0506 0.0s=> => naming to docker.io/library/lwwor 0.0s
2.3.3查看创建结果
[root@docker-5 mydockerfile]# docker run -it lwwor:latest
[root@0a3dd88da6dc lw]# pwd
/lw
[root@0a3dd88da6dc lw]# ls
test
2.4ARG(变量镜像构建完成不保留)
2.4.1写入Dockerfile
sed -i 's|WORKDIR /lw|#WORKDIR /lw|' /mydockerfile/Dockerfilesed -i 's|RUN touch test|#RUN touch test|' /mydockerfile/Dockerfileecho "ARG lw=666" >> /mydockerfile/Dockerfile
echo "RUN echo \$lw" >> /mydockerfile/Dockerfile
2.4.2创建镜像
docker build -t lwarg .
#输出如下:
[+] Building 0.2s (6/6) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 311B 0.0s=> [internal] load metadata for docker.io/library/rockylinux:9 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> CACHED [1/2] FROM docker.io/library/rockylinux:9 0.0s=> [2/2] RUN echo 666 0.2s <<<<<<<<<< 变量输出在这里=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:03b3c7525d5b09213cfe3d08a7962f862e9d7a819788308299f 0.0s=> => naming to docker.io/library/lwarg
2.4.3ARG扩展(不使用Dockerfile直接修复内容)
docker build --build-arg lw=666888 -t lwarg2 .
#输出如下:
[+] Building 0.5s (6/6) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 311B 0.0s=> [internal] load metadata for docker.io/library/rockylinux:9 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> CACHED [1/2] FROM docker.io/library/rockylinux:9 0.0s=> [2/2] RUN echo 666888 0.4s <<<<<<<<<<< 修改成功=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:fea67c899fba49a52c72a90eb01644d736c7b2ed8087e4cee5f 0.0s=> => naming to docker.io/library/lwarg2 0.0s
2.5ONBUILD(后续基于当前镜像构建的子镜像添加触发器)
2.5.1写入Dockerfile
sed -i 's|ARG lw=666|#ARG lw=666|' /mydockerfile/Dockerfilesed -i 's|RUN echo $lw|#RUN echo $lw|' /mydockerfile/Dockerfileecho "ONBUILD RUN touch 6666666.txt" >> /mydockerfile/Dockerfile
2.5.2创建镜像
docker build -t lwonb .
[+] Building 0.0s (5/5) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 343B 0.0s=> [internal] load metadata for docker.io/library/rockylinux:9 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> CACHED [1/1] FROM docker.io/library/rockylinux:9 0.0s=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:24387294b51f2975113e7706ffa6f62db7e7234699fd670d812 0.0s=> => naming to docker.io/library/lwonb 0.0s
2.5.3启动容器
# 启动容器(并没有我们创建的文件)
docker run -it lwonb:latest
[root@01d0292eef5f /]# ls
afs dev home lib64 media opt root sbin sys usr
bin etc lib lost+found mnt proc run srv tmp var
2.5.4创建新的Dockerfile
mkdir /newdofi
cd /newdofi
cat >/newdofi/Dockerfile<<LW
FROM lwonb
LW# 创建镜像
docker build -t newdf .
#输出如下: ] Building 0.2s (6/6) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 48B 0.0s=> [internal] load metadata for docker.io/library/lwonb:latest 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> CACHED [1/1] FROM docker.io/library/lwonb:latest 0.0s=> [2/2] ONBUILD RUN touch 6666666.txt 0.2s <<<<<<<<=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:01b361d549c4c34479553f553937d819dbed07ca294d1f1db7e 0.0s=> => naming to docker.io/library/newdf 0.0s# 查看容器内容(发现创建了66666)
[root@docker-5 newdofi]# docker run -it newdf:latest
[root@040779cbcda8 /]# ls
6666666.txt bin etc lib lost+found mnt proc run srv tmp var
afs dev home lib64 media opt root sbin sys usr
2.6HEALTHCHECK(健康状态)
2.6.1写入Dockerfile
sed -i 's|ONBUILD RUN touch 6666666.txt|#ONBUILD RUN touch 6666666.txt|' /mydockerfile/Dockerfilesed -i 's|FROM rockylinux:9|FROM nginx|' /mydockerfile/Dockerfileecho "HEALTHCHECK --interval=5s --timeout=5s CMD curl -f http://localhost/test.html || exit 1" >> /mydockerfile/Dockerfile
2.6.2创建镜像
docker build -t lw4 .
[+] Building 0.0s (5/5) FINISHED docker:default=> [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 425B 0.0s=> [internal] load metadata for docker.io/library/nginx:latest 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> [1/1] FROM docker.io/library/nginx:latest 0.0s=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:a3c84f30ee4e74fa993d5f441b9e2972ebd1b17bbbb1a801837 0.0s=> => naming to docker.io/library/lw4 0.0s
2.6.3启动容器查看状态
docker run -d -P lw4
220a2e134632bb8915b8874d8fd86bb2a2d051fbc660c6d2bdbc179c2d81b9bb# 查看状态变化前
docker ps -l
#输出如下:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
220a2e134632 lw4 "/docker-entrypoint.…" 9 seconds ago Up 9 seconds (health: starting) 0.0.0.0:32768->80/tcp, [::]:32768->80/tcp amazing_bassi# 查看状态变化后
docker ps -l
#输出如下:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
220a2e134632 lw4 "/docker-entrypoint.…" About a minute ago Up About a minute (unhealthy) 0.0.0.0:32768->80/tcp, [::]:32768->80/tcp amazing_bassi# 总结
--interval=5s:每 5 秒执行一次健康检查。
--timeout=5s:如果 curl 命令在 5 秒内没有完成,视为失败。
CMD curl -f ...:使用 curl 发送 HTTP 请求:
-f 选项:当服务器返回 4xx 或 5xx 状态码时,curl 会返回非零退出状态码,触发健康检查失败。
|| exit 1:确保如果 curl 命令失败(例如连接超时、服务器返回错误码),整个健康检查命令返回状态码 1(表示不健康)。
三、总结表
命令 | 功能 | 示例 |
---|---|---|
VOLUME | 定义数据卷 | VOLUME /lw666 |
USER | 切换用户 | RUN useradd user1 USER user1 |
WORKDIR | 设置工作目录 | WORKDIR /lw |
ARG | 变量镜像构建完成不保留 | ARG lw=666 |
ONBUILD | 后续基于当前镜像构建的子镜像添加触发器 | ONBUILD RUN touch 6666666.txt |
HEALTHCHECK | 健康状态 | HEALTHCHECK --interval=5s --timeout=5s CMD curl -f http://localhost/test.html || exit 1 |