
Dockerfile是什么?
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
将容器中的操作保存成镜像。
将容器内的操作写在文件中。

优点:
易于版本化管理,Dockerfile 本身是一个文本文件,方便存放在代码仓库做版本管理,可以很方便地找到各个版本之间的变更历史;
过程可追溯,Dockerfile 的每一行指令代表一个镜像层,根据 Dockerfile 的内容即可很明确地查看镜像的完整构建过程;
屏蔽构建环境异构,使用 Dockerfile 构建镜像无须考虑构建环境,基于相同 Dockerfile 无论在哪里运行,构建结果都一致。
书写原则✍️
(1)单一职责
由于容器的本质是进程,一个容器代表一个进程,因此不同功能的应用应该尽量拆分为不同的容器,每个容器只负责单一业务进程。
(2)提供注释信息
Dockerfile 也是一种代码,我们应该保持良好的代码编写习惯,晦涩难懂的代码尽量添加注释,让协作者可以一目了然地知道每一行代码的作用,并且方便扩展和使用。
(3)保持容器最小化
应该避免安装无用的软件包,比如在一个 nginx 镜像中,我并不需要安装 vim 、gcc 等开发编译工具。这样不仅可以加快容器构建速度,而且可以避免镜像体积过大。
(4)合理选择基础镜像
容器的核心是应用,因此只要基础镜像能够满足应用的运行环境即可。例如一个Java类型的应用运行时只需要JRE,并不需要JDK,因此我们的基础镜像只需要安装JRE环境即可。
(5)使用 .dockerignore 文件
在使用git时,我们可以使用.gitignore文件忽略一些不需要做版本管理的文件。同理,使用.dockerignore文件允许我们在构建时,忽略一些不需要参与构建的文件,从而提升构建效率。.dockerignore的定义类似于.gitignore。
分类

步骤
- 编写文件
- build 构建镜像
- run 运行镜像
- push 发布镜像(Dockhub, 阿里云)
构建镜像命令
docker build-t 镜像名称<:tags>-f Dockerfile目录. 代表当前目录
尝试
# 创建文件
touch dockerfile
# 编辑
vim dockerfile
# Code
FROM centos
CMD echo 'Hello' >> /home/main.txt
# 构建
[root@linis_server build]# docker build -f dockerfile -t taoya/t1 .
检查
[root@linis_server build]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
taoya/t1 latest e672f8dc7258 28 seconds ago 237MB
概念
Dockerfile:是镜像的构建文件,描述的镜像是一步步怎么来的。
镜像:是通过Dockerfile做出来的,包含操作系统基础文件和软件运行环境,它使用分层的存储方式。
容器:是运行起来的镜像,简单理解,Docker镜像相当于程序,容器相当于进程。
语法
- 保留字放在每一行的开头,建议大写
- 指令按照顺序,从上至下执行
#表示注解- 每条指令执行都会创建一个新的镜像,并且执行提交
执行流程
执行一个容器,执行一条指令对镜像进行修改。 执行docker commit
在基于刚才提交的镜像运行一个新的容器。
常用的命令
参数
FROM
基础镜像。
- 指定基础镜像,所有构建的镜像都必须有一个基础镜像,且 FROM 命令必须是 Dockerfile 的第一个命令
- FROM
[AS
] 指定从一个镜像构建起一个新的镜像名字 - FROM
[:
] [AS ] 指定镜像的版本 Tag 示例 FROM mysql:5.0 AS database
FROM 镜像 # 比如发布一个应用到Tomcat里。 FROM tomcat<:tags>
MAINTAINER
- 镜像维护人的信息
- MAINTAINER
- 示例:MAINTAINER Taoya Taoya@qq.com
MAINTAINER taoya<xxx@qq.com>LABEL
描述性信息。LABEL version = '1.0.0'运行指令
一共有三个:RUN&CMD&ENTRYPOINTRun
构建镜像时运行的Shell命令
RUN ['yum', 'install', 'httpd']
RUN yun install httpd
命令格式
RUN yum -y install vim
EXEC格式
RUN ['yum', '-y', 'install', 'vim']
CMD
- 启动容器后执行的命令,和 RUN 不一样,RUN 是在构建镜像是要运行的命令
- 当使用 docker run 运行容器的时候,这个可以在命令行被覆盖
启动容器时执行的Shell命令.而不是镜像构建执行
CMD [executable, param1, param2]
ENTRYPOINT
容器创建执行。而不是镜像构建执行
在容器启动的时候执行此命令,且Dockerfile中只有最后一个ENTRYPOINT会被执行,推荐用EXEC格式。
EXPORSE
声明容器运行的服务端口
EXPOSE 80 443
WORKDIR
# 类似Linux的cd命令。 如果没有则自动创建
WORKDIR /usr/local/test
建议使用绝对路径
ADD & COPY
COPY
功能和 ADD 一样,只是复制,不会解压或者下载文件
# 将1.txt拷贝到根目录下。它不仅仅能拷贝单个文件,还支持Go语言风格的通配符,比如如下:
COPY 1.txt /
# 拷贝所有 abc 开头的文件到testdir目录下
COPY abc* /testdir/
# ? 是单个字符的占位符,比如匹配文件 abc1.log
COPY abc?.log /testdir/
ADD
将本地的文件添加复制到容器中去,压缩包会解压,可以访问网络上的文件,会自动下载
ADD <src> <dest>
# 将1.txt拷贝到根目录的abc目录下。若/abc不存在,则会自动创建
ADD 1.txt /abc
# 将test.tar.gz解压缩然后将解压缩的内容拷贝到/home/work/test
ADD test.tar.gz /home/work/test
docker官方建议当要从远程复制文件时,尽量用curl/wget命令来代替ADD。因为用ADD的时候会创建更多的镜像层。镜像层的size也大。
- 二者都是只复制目录中的文件,而不包含目录本身。
- COPY能干的事ADD都能干,甚至还有附加功能。
- ADD可以支持拷贝的时候顺带解压缩文件,以及添加远程文件(不在本宿主机上的文件)。
- 只是文件拷贝的话可以用COPY,有额外操作可以用ADD代替。
ENV
# 设置环境常量,方便下文引用,比如:
ENV JAVA_HOME /usr/local/jdk1.8
# 引用上面的常量,下面的RUN指令可以先不管啥意思,目的是想说明下文可以通过${xxx}的方式引用
RUN ${JAVA_HOME}/bin/java -jar xxx.jar
cmd与entrypoint的区别?
- cmd
指定这个容器启动的时候要运行的命令。只有最后一个生效。可被替换
build成功后直接执行,
- entrypoint
指定这个容器启动的时候运行的命令。可以追加命令。
FROM centos
CMD ['ls', '-a']
# 对比
FROM centos
ENTRYPOINT ['ls', '-a']
docker run asda -l # 第一个报错
docker run asda -l # 第二个可以追加
❤️实践
构建自己的CentOS
FROM centos
MAINTAINER taoya<569781231@qq.com>
# 配置环境变量
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 安装一些软件
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo '--Success--'
CMD /bin/bash
[root@linis_server build]# docker build -f dockerfile -t tao/centos:0.1 .
测试
[root@c265da262e00 local]# pwd
/usr/local
拿到一个镜像可以研究一下文件
docker history image_name
[root@linis_server build]# docker history tao/centos:0.1
IMAGE CREATED CREATED BY SIZE COMMENT
de70635c159d 7 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
d3ec971aa90c 7 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
6b14d6f62413 7 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
02921581630b 7 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
a8fcdfd1fa0f 7 minutes ago /bin/sh -c yum -y install net-tools 24MB
2b3914a32051 7 minutes ago /bin/sh -c yum -y install vim 59.8MB
a698edce6122 8 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
60dfa32fdf81 8 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
582d429551c3 8 minutes ago /bin/sh -c #(nop) MAINTAINER taoya<56978123… 0B
470671670cac 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:aa54047c80ba30064… 237MB
实践Tomcat镜像
- 准备文件
- jdk1.8
- tomcat压缩包
安装Java
```dockerfile FROM centos MAINTAINER taoya569781231@qq.com
ADD jdk-8u251-linux-x64.tar.gz /usr/local
RUN yum -y install vim
ENV MYPATH /usr/local WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_251 ENV PATH $PATH:$JAVA_HOME/bin
```shell
docker build -t tao/java .

发布镜像到Dockerhub
- 注册账号
- 服务器提交镜像
docker tag firstimage YOUR_DOCKERHUB_NAME/firstimage[root@linis_server build]# docker login -u taoya7

记录: 如果Push失败
首先打标签注意格式
docker tag 镜像id dockerhub注册的名字/仓库名字
docker push dockerhub注册的名字/仓库名字

发布到阿里云
找到阿里云容器镜像服务
- 创建命名空间

- 创建容器镜像


接着上一个步骤
docker logout # 退出登录
应用场景
- Web应用的自动化打包和部署
- 轻量化,私有的Paas环境
- 自动化测试和持续集成,发布
- 部署和调整WebApps, 数据库或后台服务



