Dockerfile
Dockerfile概述#
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
从应用软件的角度来看,Dockerfile,Docker镜像,Docker容器分别代表软件的三个不同阶段
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器可以认为是软件的运行态
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及运维和部署,合力充当Docker体系的基石。
Dockerfile定义了进程需要的一切东西,Dockerfile涉及的内容包括执行代码或者文件,环境变量,依赖包,运行时环境,动态链接库,操作系统发行版,服务进程和内核进程(当应用程序需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等。
Docker镜像,在用Dockerfile定义了一个构建文件之后,docker build
时会产生一个Docker镜像,当运行Docker镜像时,会开始真正的提供服务。
Docker容器,是直接提供服务的进程。
Dockerfile构建过程:
- docker从基础镜像运行一个容器
- 执行一条指令,并对容器进行修改
- 执行类似
docker commit
的操作,提交一个新的镜像层 - docker再基于刚刚提交的镜像运行一个新容器
- 继续执行Dockerfile的下一条指令,直到所有指令都执行完成
Dockerfile的保留字指令#
Dockerfile每个保留字指令均为大写,且后面至少跟随一个参数,指令从上到下顺序执行,用#
表示注释。
-
FROM
基本出现在第一行,意思是要构建的新镜像继承于或者说基于哪个已存在的镜像。
FROM ubuntu:20.04
-
MAINTAINR
维护者信息(姓名和邮箱地址)
-
ENV
用于在构建镜像的过程中设置环境变量,这个环境变量可以在后续的任何
RUN
指令中使用,就像在命令前面指定了环境变量一样,也可以在其他指令中直接使用这些环境变量,比如WORKDIR $JAVA_HOME
ENV PATH="/usr/local/bin:${PATH}"
-
RUN
容器构建(docker build)时需要运行的命令,分为
shell
和exec
两种格式shell
RUN apt-get update && apt-get install -y curl
exec
RUN ["apt-get", "install", "-y", "curl"]
-
EXPOSE
声明容器运行时应该开放的端口。它不会自动开启端口,但为外部用户或其他容器提供信息
EXPOSE 80 443
-
WORKDIR
指定在创建容器后,终端默认登录进来的工作目录,当执行
docker run -it 镜像ID /bash
进入容器内部的时候,会默认落脚在哪个目录里 -
USER
指定镜像以什么用户去执行,如果不指定,默认是
root
USER myuser
-
VOLUME
容器数据卷,用于数据的保存和持久化,声明容器内的哪个目录需要在运行时挂载数据卷到宿主机上
VOLUME ["/data"]
-
ADD
ADD
功能相比COPY
更加强大,将宿主机内的文件拷贝进镜像,如果源文件是.tar
、.tar.gz
等压缩格式的文件,ADD
会自动解压到目标路径。ADD
还可以从指定的URL下载文件并复制到容器内。ADD <宿主机源路径> <容器内目标路径>
-
COPY
仅仅执行文件的复制,不支持自动解压或下载
COPY <宿主机源路径> <容器内目标路径>
-
CMD
指定容器启动后要做的事情,支持
shell
和exec
两种格式,还支持参数列表格式,如果指定了ENTRYPOINT
指令,CMD
就会被用来指定具体的运行参数注意事项
1.
RUN
和CMD
的区别:RUN
是构建镜像时执行,CMD
是docker run
容器启动时执行2.Dockerfile中可以有多个
CMD
指令,但只有最后一个生效,CMD
会被docker run
之后的参数替换例如:tomcat的Dockerfile的最后一行是
CMD ["catalina.sh", "run"]
,那么使用docker run -it tomcat /bin/bash
命令启动这个镜像时,容器会启动,但是tomcat就不会被启动,因为被run
后的命令/bin/bash
替换掉了,故容器启动后会运行/bin/bash
-
ENTRYPOINT
类似于
CMD
命令,但是不会被docker run
后的命令覆盖,而且还会把docker run
后的命令当作命令行参数传递给ENTRYPOINT
指令指定的程序ENTRYPOINT ["可执行文件", "参数1", "参数2", ......]
ENTRYPOINT
可以和CMD
一起用,一般是变参才会使用到CMD
,这里的CMD
等同于是在给ENTRYPOINT
传参,当指定了ENTRYPOINT
后,CMD
的含义就发生了变化,不再是直接运行其命令而是将CMD
的内容作为参数传递给ENTRYPOINT
指令,它们两个组合后会变成<ENTRYPOINT> "<CMD>"
案例:
FROM nginx ENTRYPOINT ["nginx", "-c"] #相当于命令加定参 CMD ["/etc/nginx/nginx.conf"] #相当于可替换的变参
按照Dockerfile原样执行 传参运行 Docker命令 docker run nginx docker run nginx /etc/nginx/kms.conf 容器实际执行 nginx -c /etc/nginx/nginx.conf nginx -c /etc/nginx/kms.conf
如果写成docker run nginx -c /etc/nginx/kms.conf
也可以实现参数替换,-c
不会被重复的叠加成docker run nginx -c -c /etc/nginx/kms.conf
,因为ENTRYPOINT本身未包含-c
,而CMD提供了-c
的值
用Dockerfile构建镜像#
编写一个Dockerfile,用于构建一个自带Java17环境的RockyLinux9镜像,构建的镜像基于发行版rockylinux:8.9
,新镜像内新增vim
,net-tools
组件,并将下载好的jdk17拷贝进去,并设置jdk相关的环境变量,让这个镜像构建的容器自带原版镜像不默认安装的一些工具,并且自带jdk17
找到一个空文件夹,vim Dockerfile
编辑文件将构建命令写进去
FROM rockylinux:8.9
MAINTAINER lzj2023@foxmail.com
ENV MYPATH /opt
WORKDIR $MYPATH
RUN yum install -y vim net-tools
RUN mkdir /opt/jdk
# 此处使用相对路径,jdk-17.0.12_linux-x64_bin.tar.gz要和Dockerfile在同一目录
ADD jdk-17.0.12_linux-x64_bin.tar.gz /opt/jdk
ENV JAVA_HOME /opt/jdk/jdk-17.0.12
ENV PATH $JAVA_HOME/bin:$PATH
CMD ["/bin/bash"]
编写完成后,再将要打包进去的jdk-17.0.12_linux-x64_bin.tar.gz
放在同级目录,然后在这个目录内执行docker build
命令,会用当前目录(.
)下的Dockerfile构建镜像,镜像名称和标签是rockey8_jdk17:1.0.0
docker build -t rockey8_jdk17:1.0.0 .
执行输出
[root@localhost opt]# docker build -t rockey8_jdk17:1.0.0 .
Sending build context to Docker daemon 566.8MB
Step 1/11 : FROM rockylinux:8.9
8.9: Pulling from library/rockylinux
9088cdb84e39: Pull complete
Digest: sha256:9794037624aaa6212aeada1d28861ef5e0a935adaf93e4ef79837119f2a2d04c
Status: Downloaded newer image for rockylinux:8.9
---> c79048e50f5f
Step 2/11 : MAINTAINER lzj2023@foxmail.com
---> Running in 9c40b7e878e1
Removing intermediate container 9c40b7e878e1
---> e58d03a7ebae
Step 3/11 : ENV MYPATH /opt
---> Running in d8448a9b4329
Removing intermediate container d8448a9b4329
---> da5da26abbe3
Step 4/11 : WORKDIR $MYPATH
---> Running in ddf20f025c3f
Removing intermediate container ddf20f025c3f
---> 2fe907e79d95
Step 5/11 : RUN yum -y install vim
---> Running in f88378120cc1
Rocky Linux 8 - AppStream 3.4 MB/s | 15 MB 00:04
Rocky Linux 8 - BaseOS 2.5 MB/s | 9.4 MB 00:03
Rocky Linux 8 - Extras 5.1 kB/s | 14 kB 00:02
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
vim-enhanced x86_64 2:8.0.1763-19.el8_6.4 appstream 1.4 M
Installing dependencies:
gpm-libs x86_64 1.20.7-17.el8 appstream 38 k
vim-common x86_64 2:8.0.1763-19.el8_6.4 appstream 6.3 M
vim-filesystem noarch 2:8.0.1763-19.el8_6.4 appstream 49 k
which x86_64 2.21-20.el8 baseos 49 k
Transaction Summary
================================================================================
Install 5 Packages
Total download size: 7.8 M
Installed size: 30 M
Downloading Packages:
[MIRROR] gpm-libs-1.20.7-17.el8.x86_64.rpm: Curl error (52): Server returned nothing (no headers, no data) for http://au.mirrors.cicku.me/rocky/8.10/AppStream/x86_64/os/Packages/g/gpm-libs-1.20.7-17.el8.x86_64.rpm [Empty reply from server]
[MIRROR] vim-common-8.0.1763-19.el8_6.4.x86_64.rpm: Curl error (52): Server returned nothing (no headers, no data) for http://au.mirrors.cicku.me/rocky/8.10/AppStream/x86_64/os/Packages/v/vim-common-8.0.1763-19.el8_6.4.x86_64.rpm [Empty reply from server]
[MIRROR] vim-enhanced-8.0.1763-19.el8_6.4.x86_64.rpm: Curl error (52): Server returned nothing (no headers, no data) for http://au.mirrors.cicku.me/rocky/8.10/AppStream/x86_64/os/Packages/v/vim-enhanced-8.0.1763-19.el8_6.4.x86_64.rpm [Empty reply from server]
(1/5): gpm-libs-1.20.7-17.el8.x86_64.rpm 4.6 kB/s | 38 kB 00:08
(2/5): vim-filesystem-8.0.1763-19.el8_6.4.noarc 172 kB/s | 49 kB 00:00
(3/5): vim-common-8.0.1763-19.el8_6.4.x86_64.rp 725 kB/s | 6.3 MB 00:08
(4/5): vim-enhanced-8.0.1763-19.el8_6.4.x86_64. 144 kB/s | 1.4 MB 00:09
[MIRROR] which-2.21-20.el8.x86_64.rpm: Curl error (52): Server returned nothing (no headers, no data) for http://au.mirrors.cicku.me/rocky/8.10/BaseOS/x86_64/os/Packages/w/which-2.21-20.el8.x86_64.rpm [Empty reply from server]
(5/5): which-2.21-20.el8.x86_64.rpm 7.4 kB/s | 49 kB 00:06
--------------------------------------------------------------------------------
Total 449 kB/s | 7.8 MB 00:17
Rocky Linux 8 - AppStream 1.6 MB/s | 1.6 kB 00:00
Importing GPG key 0x6D745A60:
Userid : "Release Engineering <infrastructure@rockylinux.org>"
Fingerprint: 7051 C470 A929 F454 CEBE 37B7 15AF 5DAC 6D74 5A60
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-20.el8.x86_64 1/5
Installing : vim-filesystem-2:8.0.1763-19.el8_6.4.noarch 2/5
Installing : vim-common-2:8.0.1763-19.el8_6.4.x86_64 3/5
Installing : gpm-libs-1.20.7-17.el8.x86_64 4/5
Running scriptlet: gpm-libs-1.20.7-17.el8.x86_64 4/5
Installing : vim-enhanced-2:8.0.1763-19.el8_6.4.x86_64 5/5
Running scriptlet: vim-enhanced-2:8.0.1763-19.el8_6.4.x86_64 5/5
Running scriptlet: vim-common-2:8.0.1763-19.el8_6.4.x86_64 5/5
Verifying : gpm-libs-1.20.7-17.el8.x86_64 1/5
Verifying : vim-common-2:8.0.1763-19.el8_6.4.x86_64 2/5
Verifying : vim-enhanced-2:8.0.1763-19.el8_6.4.x86_64 3/5
Verifying : vim-filesystem-2:8.0.1763-19.el8_6.4.noarch 4/5
Verifying : which-2.21-20.el8.x86_64 5/5
Installed:
gpm-libs-1.20.7-17.el8.x86_64
vim-common-2:8.0.1763-19.el8_6.4.x86_64
vim-enhanced-2:8.0.1763-19.el8_6.4.x86_64
vim-filesystem-2:8.0.1763-19.el8_6.4.noarch
which-2.21-20.el8.x86_64
Complete!
Removing intermediate container f88378120cc1
---> cb9eb843b319
Step 6/11 : RUN yum install -y net-tools
---> Running in 15b13dec8321
Last metadata expiration check: 0:00:29 ago on Sun Dec 8 07:29:48 2024.
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Installing:
net-tools x86_64 2.0-0.52.20160912git.el8 baseos 321 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 321 k
Installed size: 942 k
Downloading Packages:
net-tools-2.0-0.52.20160912git.el8.x86_64.rpm 262 kB/s | 321 kB 00:01
--------------------------------------------------------------------------------
Total 101 kB/s | 321 kB 00:03
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Running scriptlet: net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Verifying : net-tools-2.0-0.52.20160912git.el8.x86_64 1/1
Installed:
net-tools-2.0-0.52.20160912git.el8.x86_64
Complete!
Removing intermediate container 15b13dec8321
---> 2e79057963a9
Step 7/11 : RUN mkdir /opt/jdk
---> Running in 69bf76127e8d
Removing intermediate container 69bf76127e8d
---> 25f8d658823f
Step 8/11 : ADD jdk-17.0.12_linux-x64_bin.tar.gz /opt/jdk
---> 83d8b92be129
Step 9/11 : ENV JAVA_HOME /opt/jdk/jdk-17.0.12
---> Running in 1f4043adc4cb
Removing intermediate container 1f4043adc4cb
---> 3c05d8189cad
Step 10/11 : ENV PATH $JAVA_HOME/bin:$PATH
---> Running in 15d649530173
Removing intermediate container 15d649530173
---> c9f46f990422
Step 11/11 : CMD ["/bin/bash"]
---> Running in 02d2ee2073ee
Removing intermediate container 02d2ee2073ee
---> fb5b6a2e5b81
Successfully built fb5b6a2e5b81
Successfully tagged rockey8_jdk17:1.0.0
提示构建成功,查看一下自己构建的镜像
[root@localhost opt]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rockey8_jdk17 1.0.0 fb5b6a2e5b81 49 seconds ago 642MB
rockylinux 8.9 c79048e50f5f 12 months ago 198MB
用交互模式用刚刚构建成的镜像运行一个容器,执行命令java -version
验证打包进去的jdk和环境变量,构建成功!
[root@localhost opt]# docker run -it rockey8_jdk17:1.0.0
[root@a4703ffe3841 opt]# java -version
java version "17.0.12" 2024-07-16 LTS
Java(TM) SE Runtime Environment (build 17.0.12+8-LTS-286)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.12+8-LTS-286, mixed mode, sharing)
虚悬镜像#
定义:REPOSITORY
和TAG
都是<none>
的镜像(dangling image),是由于构建和删除镜像时产生一些错误导致的,虚悬镜像会占用空间,因此需要清理掉它们
查出
docker image ls -f dangling=true
清理
docker image prune
作者:changelzj
出处:https://www.cnblogs.com/changelzj/p/18625051
版权:本作品采用「署名-非商业性使用-禁止演绎 4.0 国际」许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章