Docker基础Part5——DockerFlie

[TOC]

DockerFile介绍

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

Dockerfile 是面向开发的,Docker镜像逐渐成为企业交付、发布项目的标准。

构建步骤:

  1. 编写 dockerfile 文件
  2. docker build 构建镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub 、阿里云仓库)

每一个指令都会创建一个新的镜像层并提交。

DockerFile指令

1
2
3
4
5
6
7
8
9
10
11
12
FROM				# 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 开放端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行ONBUILD的指令,触发指令。
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量

实战测试

  • DockerHub中大部分镜像都是从FROM scratch开始。
  • 关键字不一定要大写,但是一般都是大写来和变量区分。

官方的centos镜像没有vim、ifconfig命令,这里制作自己的centos镜像。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 1.编写Dockerfile文件
[root@VM-1-14-centos dockerfile]# vim mydockerfile_centos
[root@VM-1-14-centos dockerfile]# cat mydockerfile_centos
FROM centos
MAINTAINER NephrenCake<834957063@qq.com>

ENV MYPATH /usr/local
WOKDIR $MYPATH

run yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "-----end-----"
CMD /bin/bash

# 2.构建镜像
# 命令 docker build -f 文件路径 -t 镜像名:[tag] 目标路径
docker build -f mydockerfile_centos -t mycentos:0.1 . # <-注意这里的一个“.”表示镜像文件生成在当前目录
......
Successfully built 0fb03cb15b56
Successfully tagged mycentos:0.1

# 3.测试运行
[root@VM-1-14-centos dockerfile]# docker run -it mycentos:0.1 /bin/bash
[root@6db4033677cd local]# pwd
/usr/local # 进入设置的工作目录
[root@6db4033677cd local]# ifconfig
...... # ifconfig 可以正常使用
[root@6db4033677cd local]# vim --version
...... # vim 可以正常使用

# 4.查看构建过程
[root@VM-1-14-centos dockerfile]# docker history mycentos:0.1
IMAGE CREATED CREATED BY SIZE COMMENT
0fb03cb15b56 25 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
857a02979c6b 25 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
9b1d90e765f1 25 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
383a1fdc4420 25 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
315a1c8eafe2 25 minutes ago /bin/sh -c yum -y install net-tools 23.3MB
1bd3533bf951 25 minutes ago /bin/sh -c yum -y install vim 58MB
e7468e6156a1 26 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
02c89bb6f0d5 26 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
1e2c46d0633d 26 minutes ago /bin/sh -c #(nop) MAINTAINER NephrenCake<83… 0B
300e315adb2f 4 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 4 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 4 months ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
  • 建议在dockerfile所在目录构建镜像。
  • 对所有拿到的镜像都可以docker history来分析其构建过程。

CMD 和 ENTRYPOINT区别

1
2
CMD					# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令

test CMD:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 1.编写dockerfile文件
[root@VM-1-14-centos dockerfile]# vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]

# 2.构建镜像
[root@VM-1-14-centos dockerfile]# docker build -f dockerfile-test-cmd -t cmd-test:0.1 .

# 3.运行镜像
$ docker run cmd-test:0.1
.
..
.dockerenv
bin
dev
...... # 成功执行设置的cmd指令

# 4.意图追加命令 -l 成为ls -al
[root@VM-1-14-centos dockerfile]# docker run cmd-test:0.1 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\":
executable file not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled
# cmd的情况下 `-l` 替换了 `CMD["ls","-a"]` ,而 `-l` 不是命令所以报错

# 5.修正:
[root@VM-1-14-centos dockerfile]# docker run cmd-test:0.1 ls -l
total 48
lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin
drwxr-xr-x 5 root root 340 Apr 25 03:10 dev
drwxr-xr-x 1 root root 4096 Apr 25 03:09 etc
drwxr-xr-x 2 root root 4096 Nov 3 15:22 home
......

# 6.没有停留在容器的原因是执行完cmd指令自动退出了
[root@VM-1-14-centos dockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9ce9877f6610 cmd-test:0.1 "ls -l" 11 seconds ago Exited (0) 10 seconds ago interesting_knuth

test ENTRYPOINT:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1.编写dockerfile文件
[root@VM-1-14-centos dockerfile]# vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]

# 2.构建镜像
[root@VM-1-14-centos dockerfile]# docker build -f dockerfile-test-entrypoint -t entrypoint-test:0.1

# 3.运行镜像
[root@VM-1-14-centos dockerfile]# docker run entrypoint-test:0.1
.
..
.dockerenv
bin
dev
......

# 4.追加命令
[root@VM-1-14-centos dockerfile]# docker run entrypoint-test:0.1 -l
total 56
drwxr-xr-x 1 root root 4096 May 16 06:32 .
drwxr-xr-x 1 root root 4096 May 16 06:32 ..
-rwxr-xr-x 1 root root 0 May 16 06:32 .dockerenv
......

Tomcat实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1.准备镜像文件
Tomcat jdk dockerfile readme

# 2.编写dockerfile
FROM centos #
MAINTAINER cheng<1204598429@qq.com>
COPY README /usr/local/README #复制文件
ADD jdk-8u231-linux-x64.tar.gz /usr/local/ #复制解压
ADD apache-tomcat-9.0.35.tar.gz /usr/local/ #复制解压
RUN yum -y install vim
ENV MYPATH /usr/local #设置环境变量
WORKDIR $MYPATH #设置工作目录
ENV JAVA_HOME /usr/local/jdk1.8.0_231 #设置环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 #设置环境变量
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib #设置环境变量 分隔符是:
EXPOSE 8080 #设置暴露的端口
CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/logs/catalina.out # 设置默认命令

# 3.构建image 因为dockerfile命名使用默认命名 因此不用使用-f 指定文件
$ docker build -t mytomcat:0.1 .

# 4.运行image
$ docker run -d -p 8080:8080 --name tomcat01 -v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs mytomcat:0.1

发布镜像

登录

注册DockerHub

1
2
3
4
5
6
docker login [OPTIONS] [SERVER]

Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Username

提交

1
2
3
4
5
6
7
docker push xxx/image:[镜像版本号]

# 没有前缀默认push到官方的library
# 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了
$ docker build -t nephrencake/mytomcat:1.0 .
# 第二种 使用docker tag 然后再次push
$ docker tag 容器id nephrencake/mytomcat:1.0

修改版本

1
2
3
4
5
$ docker tag [ImageId] registry.cn-xxx.aliyuncs.com/xxxx/image:[镜像版本号]
# 修改id 和 版本
$ sudo docker tag a5ef1f32aaae registry.cn-xxx.aliyuncs.com/xxxx/image:1.0
# 修改仓库镜像版本
$ docker push registry.cn-xxx.aliyuncs.com/xxxx/image:[镜像版本号]

打包镜像

1
2
3
4
docker save [OPTIONS] IMAGE [IMAGE...]

Options:
-o, --output string Write to a file, instead of STDOUT

小结

image-20210427110036461