1.创建一个Dockerfile
注意:一定要创建一个新的目录 因为在构建镜像的时候,会默认把dockerfile所在的目录中的所有目录发送给docker引擎,举个例子 如果你把dockerfile放在/目录下 那么这个过程会变得非常的缓慢
[root@server3 mnt]# mkdir /mnt/docker
[root@server3 mnt]# cd docker/
[root@server3 docker]# ls
[root@server3 docker]# vim dockerfile
FROM busybox #以哪个基础镜像为模板
RUN echo testfile > file1 #在新镜像中你要执行的哪些动作
RUN echo testfile > file2
创建镜像
[root@server3 docker]# docker build -t test:v2 #镜像名称 . 代表当前目录
Sending build context to Docker daemon 2.048 kB #把dockerfile所在的目录中的所有目录发送给docker引擎
Step 1/3 : FROM busybox
---> db8ee88ad75f
Step 2/3 : RUN echo testfile > file1
---> Running in 4c00ef6f0753
---> e8a1fbac8837
Removing intermediate container 4c00ef6f0753 #临时镜像层删掉
Step 3/3 : RUN echo testfile > file2
---> Running in cd7a46bb3269
---> 5fc404485b27
Removing intermediate container cd7a46bb3269
Successfully built 5fc404485b27
[root@server3 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test v2 5fc404485b27 About a minute ago 1.22 MB
test v1 c1a9c80bccb0 19 minutes ago 1.22 MB
ubuntu latest 3556258649b2 2 weeks ago 64.2 MB
busybox latest db8ee88ad75f 3 weeks ago 1.22 MB
game2048 latest 19299002fdbe 2 years ago 55.5 MB
[root@server3 docker]# docker history test:v2
IMAGE CREATED CREATED BY SIZE COMMENT
5fc404485b27 About a minute ago /bin/sh -c echo testfile > file2 9 B
e8a1fbac8837 About a minute ago /bin/sh -c echo testfile > file1 9 B
db8ee88ad75f 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
3 weeks ago /bin/sh -c #(nop) ADD file:9ceca008111a4dd... 1.22 MB
[root@server3 docker]# docker history busybox:latest
IMAGE CREATED CREATED BY SIZE COMMENT
db8ee88ad75f 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
3 weeks ago /bin/sh -c #(nop) ADD file:9ceca008111a4dd... 1.22 MB
再次更改dockerfile 注意:不要随便加空格(要使用缓存 之前内容不能随便更改)
[root@server3 docker]# cat dockerfile
FROM busybox
RUN echo testfile > file1
RUN echo testfile > file2
RUN echo testfile > file3
Using cache
,已经缓存过的不会再缓存了[root@server3 docker]# docker build -t test:v3 .
Sending build context to Docker daemon 2.048 kB
Step 1/4 : FROM busybox
---> db8ee88ad75f
Step 2/4 : RUN echo testfile > file1
---> Using cache #已经运行过的不再运行
---> e8a1fbac8837
Step 3/4 : RUN echo testfile > file2
---> Using cache
---> 5fc404485b27
Step 4/4 : RUN echo testfile > file3
---> Running in e2e4d6f4c565 #运行新的指令
---> edd40df71d11
Removing intermediate container e2e4d6f4c565
Successfully built edd40df71d11
说明
--no-cache
参数[root@server3 docker]# docker history test:v3
IMAGE CREATED CREATED BY SIZE COMMENT
edd40df71d11 52 seconds ago /bin/sh -c echo testfile > file3 9 B
5fc404485b27 6 minutes ago /bin/sh -c echo testfile > file2 9 B
e8a1fbac8837 6 minutes ago /bin/sh -c echo testfile > file1 9 B
db8ee88ad75f 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
3 weeks ago /bin/sh -c #(nop) ADD file:9ceca008111a4dd... 1.22 MB
[root@server3 docker]# docker history test:v2
IMAGE CREATED CREATED BY SIZE COMMENT
5fc404485b27 6 minutes ago /bin/sh -c echo testfile > file2 9 B
e8a1fbac8837 6 minutes ago /bin/sh -c echo testfile > file1 9 B
db8ee88ad75f 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
3 weeks ago /bin/sh -c #(nop) ADD file:9ceca008111a4dd... 1.22 MB
本质:dockerfile中的每一层其实就是执行了一个docker commit
以下详细介绍dockerfile的一些常用指令 ,便于我们书写更成熟的dockerfile文件
FROM
:指定base镜像,如果本地不存在会从远程仓库下载(虚拟机要配置上网)MAINTAINER
:设置镜像的作者,比如用户邮箱等 (不是必须的)COPY
:把文件从build context复制到镜像[root@server3 docker]# vim dockerfile
FROM busybox
COPY testfile /tmp
[root@server3 docker]# vim testfile
hello~
[root@server3 docker]# docker build -t test:v4 .
Sending build context to Docker daemon 3.072 kB
Step 1/2 : FROM busybox
---> db8ee88ad75f
Step 2/2 : COPY testfile /tmp
---> ff437a8d3732
Removing intermediate container e79887133199
Successfully built ff437a8d3732
[root@server3 docker]# docker history test:v4
IMAGE CREATED CREATED BY SIZE COMMENT
ff437a8d3732 9 seconds ago /bin/sh -c #(nop) COPY file:d93a5a916d7ae8... 7 B
db8ee88ad75f 3 weeks ago /bin/sh -c #(nop) CMD ["sh"] 0 B
3 weeks ago /bin/sh -c #(nop) ADD file:9ceca008111a4dd... 1.22
COPY
成功[root@server3 docker]# docker run -it --name vm1 test:v4
/ # ls
bin dev etc home proc root sys tmp usr var
/ # cd /tmp/
/tmp # ls
testfile
/tmp # cat testfile
hello~
建议:不用的容器和镜像,要即使删除
ADD
:用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以下载URL并拷贝到镜像eg:ADD html.tar /var/www
ADD http://ip/html.tar /var/www
scp [email protected]:/mnt/nginx/nginx-1.17.4.tar.gz .
[root@server3 docker]# vim dockerfile
FROM busybox
COPY testfile /tmp
ADD nginx-1.15.9.tar.gz /tmp
[root@server3 docker]# docker build -t test:v5 .
Sending build context to Docker daemon 1.036 MB
Step 1/3 : FROM busybox
---> db8ee88ad75f
Step 2/3 : COPY testfile /tmp
---> Using cache
---> ff437a8d3732
Step 3/3 : ADD nginx-1.15.9.tar.gz /tmp
---> 9db2ad29e44f
Removing intermediate container f84d556d43dc
Successfully built 9db2ad29e44f
ADD
成功[root@server3 docker]# docker run -it --name vm2 test:v5
/ # cd /tmp/
/tmp # ls
nginx-1.15.9 testfile
/tmp # cd nginx-1.15.9/
/tmp/nginx-1.15.9 # ls
CHANGES README configure man
CHANGES.ru auto contrib src
LICENSE conf htm
ENV
:设置环境变量,变量可以被后续的指令使用(不是必须的)EXPOSE
:如果容器运行应用服务,可以把服务的端口暴露出去[root@server3 docker]# docker history game2048
IMAGE CREATED CREATED BY SIZE COMMENT
19299002fdbe 2 years ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "se... 0 B
2 years ago /bin/sh -c #(nop) EXPOSE 80/ tcp 0 B # 服务的端口暴露出去 方便我们去做端口映射和用户在容器启动后去访问的
2 years ago /bin/sh -c #(nop) COPY dir:cb74e9c037a3d50... 600 kB
2 years ago /bin/sh -c #(nop) MAINTAINER Golfen Guo <... 0 B
2 years ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daem... 0 B
2 years ago /bin/sh -c #(nop) EXPOSE 443/tcp 80/tcp 0 B
2 years ago /bin/sh -c #(nop) COPY file:d15ceb73c6ea77... 1.1 kB
2 years ago /bin/sh -c #(nop) COPY file:af94db45bb7e4b... 643 B
2 years ago /bin/sh -c GPG_KEYS=B0F4253373F8F6F510D421... 50.1 MB
2 years ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.11.7 0 B
2 years ago /bin/sh -c #(nop) MAINTAINER NGINX Docker... 0 B
2 years ago /bin/sh -c #(nop) ADD file:7afbc23fda8b0b3... 4.8 MB
VOLUME:
申明数据卷,通常指定的是应用的数据挂载点
目的:容器数据持久化的
在dockerfile中加VOLUME ["/data"]
[root@server3 docker]# vim dockerfile
FROM busybox
COPY testfile /tmp
ADD nginx-1.15.9.tar.gz /tmp
VOLUME ["/data"] #在启动容器的时候会帮我们自动的新建
[root@server3 docker]# docker build -t test:v6 .
Sending build context to Docker daemon 1.036 MB
Step 1/4 : FROM busybox
---> db8ee88ad75f
Step 2/4 : COPY testfile /tmp
---> Using cache
---> ff437a8d3732
Step 3/4 : ADD nginx-1.15.9.tar.gz /tmp
---> Using cache
---> 9db2ad29e44f
Step 4/4 : VOLUME /data
---> Running in 5f03d4efc260
---> 680a9d07e8e9
Removing intermediate container 5f03d4efc260
Successfully built 680a9d07e8e9
[root@server3 docker]# docker run -it --name vm2 test:v6
/ # ls
bin dev home root tmp var
data etc proc sys usr
/ # cd data/
docker inspect 6a8af9225428
(镜像ID)这个命令看到docker inspect 6a8af9225428
"Mounts": [
{
"Type": "volume",
"Name": "54322e71d6257057e0b785efdfa5853a53422a287048780753fba37df3a2470b",
"Source": "/var/lib/docker/volume/54322e71d6257057e0b785efdfa5853a53422a287048780753fba37df3a2470b/_data",
cd var/lib/docker/volume/54322e71d6257057e0b785efdfa5853a53422a287048780753fba37df3a2470b/_data
[root@server3 /]# cd /var/lib/docker/volumes/54322e71d6257057e0b785efdfa5853a53422a287048780753fba37df3a2470b/_data
[root@server3 _data]# ls
[root@server3 _data]# touch file1
[root@server3 _data]# touch file2
[root@server3 _data]# docker attach vm2
/ # cd /data/
/data # ls
file1 file2
/data # rm -rf file1
/data # exit
[root@server3 _data]# ls
file2
WOEKDIR
:为RUN
CMD
ENTRYPOINT
ADD
COPY
指令设置镜像中的当前工作目录(类似于cd ),如果目录不存在会自动创建RUN
:在容器中运行命令并创建新的镜像层,常用于安装包RUN yum install -y vim
CMD
与ENTRYPOINT
:这两个指令都是用于设置容器启动后执行的命令CMD
会被docker run后面的命令覆盖,而ENTRYPOINT
不会被忽略,一定会被执行ENTRYPOINT
指令当作参数 dockerfile中只能指定一个ENTRYPOINT
,如果指定了很多,只有最后一个有效[root@server3 docker]# cat dockerfile
FROM busybox
ENV name world #ENV:定义变量
ENTRYPOINT echo "hello,$name"
[root@server3 docker]# docker build -t test:v8 .
Sending build context to Docker daemon 1.036 MB
Step 1/3 : FROM busybox
---> db8ee88ad75f
Step 2/3 : ENV name world
---> Using cache
---> 9771be0e3225
Step 3/3 : ENTRYPOINT /bin/echo hello,$name
---> Running in 6bc8e3d7e2d8
---> 77cecb1b6c1c
Removing intermediate container 6bc8e3d7e2d8
Successfully built 77cecb1b6c1c
[root@server3 docker]# docker run --rm test:v8
hello,$name
[root@server3 docker]# cat dockerfile #
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo","hello,$name"]
shell格式底层会掉用/bin/sh -c 来执行命令,可以解析变量,而exec格式不会
[root@server3 docker]# docker build -t test:v9 .
Sending build context to Docker daemon 1.036 MB
Step 1/3 : FROM busybox
---> db8ee88ad75f
Step 2/3 : ENV name world
---> Using cache
---> 9771be0e3225
Step 3/3 : ENTRYPOINT /bin/sh -c echo hello,$name
---> Running in 5ab8da5fc8ca
---> 6f26d3c56e7e
Removing intermediate container 5ab8da5fc8ca
Successfully built 6f26d3c56e7e
exec格式时,ENTRYPOINT可以通过CMD提供的额外参数,CMD的额外参数可以在容器启动时动态替换,在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数
[root@server3 docker]# docker run --rm test:v10
hello world
CMD
和ENTRYPOINT
[root@server3 docker]# cat dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
验证
[root@server3 docker]# docker run --rm test:v10 westos
hello westos
# westos 覆盖了dockerfile CMD后面的值