Docker --- Dockerfile 制作镜像
0. 官方文档
https://docs.docker.com/engine/reference/builder/
1. 概述
1.1 是什么?
DockerFile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本

1.2 注意事项
1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
2. 指令按照从上到下,顺序执行
3. `#`表示注释
4. 每条指令都会创建一个新的镜像层并对镜像进行提交
1.3 Docker 执行Docker File 的大致流程
1. Docker 从基础镜像运行一个容器
2. 执行一条指令并对容器做出修改
3. 执行类似 docker commit 的操作提交一个新的镜像层
4. docker 再基于刚提交的镜像运行一个新容器
5. 执行dockerfile中的下一条指令知道所有指令都执行完成
1.4 DockerFile、镜像、容器之间的关系
DockerFile面向开发,Docker镜像为交付标准,Docker容器则涉及部署和运维,三者缺一不可,合力充当Docker体系的基石
# 官方镜像仓库中的镜像都是由DockerFile构建的


2. 编写 Docker File文件
2.0 保留字指令概览
FROM                # 指定基础镜像
MAINTAINER          # 指定维护者的信息
LABLE               # 描述,标签
RUN                 # 执行命令
ADD                 # 给它点创业资金(会自动解压tar)  制作docker基础的系统镜像
WORKDIR             # cd(设置当前工作目录)
VOLUME              # 设置卷,挂载主机目录 
EXPOSE              # 指定对外的端口(-P 随机端口)
CMD                 # 结束的最后执行的命令
dockerfile其他指令: 
COPY                # 复制文件(不会解压)
ENV                 # 环境变量(更改SSH密码,mysql)
ENTRYPOINT          # 容器启动后执行的命令(无法被替换,启容器的时候指定的命令,会被当成参数)
2.1 保留字指令详解
1. FROM
都是在整个DockerFile的第一行,用来指定当前新镜像是基于那个镜像的,指定一个已经存在的镜像作为模版
FROM 镜像名/镜像ID
2. MAINTAINER
用来指定镜像维护者的信息,如姓名和邮箱地址等,这个不是必须的
MAINTAINER 维护者的信息
3. ENV
用来指定在构建镜像过程中设置环境变量,这个环境变量可以在后续的任何 RUN 指令中使用,这就如同在命令前面指定了环境变量前缀一样,也可以在其他指令中使用这些环境变量
格式
ENV 环境变量名 路径
示例
ENV CATALINA_HOME /usr/local/tomcat
4. WORKDIR
用来指定在创建容器后,终端默认登陆进来的工作目录,类似与Linux的 cd 命令
WORKDIR $CATALINA_HOME
5. USER
用来指定该镜像以什么样的用户取执行,如果没有指定,默认是root,一般不指定
6. RUN
用来指定容器构建时需要运行的命令,它由两种格式,一种是shell格式,一种是exec格式,RUN是在docker build时运行的
1. shell格式
格式
RUN 命令行命令
示例
RUN yum install -y openssh*  
RUN /etc/init.d/sshd start && /etc/init.d/sshd start && echo '123' |passwd root --stdin
2. exec格式
格式
RUN ["可执行文件","参数1","参数2"]
示例
RUN ["./test.php","dev","offline"]   # 等价于 RUN ./test.php dev offline
7. ADD
将宿主机指定目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包,相当于COPY指令+tar解压指令
8. COPY
类似ADD, 只拷贝文件和目录到镜像中,不会解压文件,
将从构建上下文目录中 <源路径>的文件/目录复制到新的一层的镜像内的 <容器内的指定路径>
格式
# 容器内的指定路径不存在的话会自动创建
COPY 源路径 容器内的指定路径
COPY ["源路径","容器内的指定路径"]
9. VOLUME
用来指定容器数据卷路径,用于数据的保存和持久化
10. EXPOSE
用来指定当前容器对外暴露的端口
11. CMD
用来指定容器 启动后 要干的事情,DockerFile 中可以有多个CMD指令,但是只有最后一个生效,CMD中的参数 会被 docker run 命令后面跟着的参数替换
格式
shell格式
CMD shell命令
  
exec格式
CMD ["可执行文件","参数1","参数2"]
参数列表格式
# 在指定了 ENTRYPOINT 执行后,用 CMD 指定具体的参数
CMD ["参数1","参数2"]
对于 CMD中的参数 会被 docker run 命令后面跟着的参数替换 的解释
docker run -p 8080:8080 tomcat
可以看到 tomcat 启动成功

但是当启动命令变成下面这个时
docker run -p 8080:8080 tomcat /bin/bash
# CMD中的参数之前为
CMD ["catalina.sh","run"]
# 但是上面的docker run 命令后面跟了参数,CMD命令会被替换
CMD ["/bin/bash","run"]
导致容器启动成功,但是 tomcat 并未启动,所以浏览器访问不到


12. ENTRYPOINT
也是用来指定一个容器启动时要运行的命令,类似于 CMD 指令,但是 ENTRYPOINT 不会被 docker run 后面跟的参数覆盖,而且这些参数会被当做参数 传给 ENTRYPOINT 指令指定的程序
ENTRYPOINT 可以和 CMD 一起用,一般是需要参数发生改变(变参)时使用CMD,如果是在一起使用的,这样CMD就相当于是在给 ENTRYPOINT 传参
在指定了CMD的同时也指定了 ENTRYPOINT 后,CMD指令的含义就发生了改变,不再是直接运行其命令,而是将CMD的内容作为参数传递给 ENTRYPOINT 指令,如 <ENTRYPOINT> "<CMD>"
格式
ENTRYPOINT ["执行的命令","参数1","参数2"]
示例:如构建的是 nginx:test 镜像
FROM nginx
ENTRYPOINT ["nginx","-c"]    # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
当没有传参运行 nginx 时
docker run nginx:test
# 底层执行的命令
nginx -c /etc/nginx/nginx.conf
当传参时,CMD的参数会被 docker run 后面的参数覆盖
docker run nginx:test -c /etc/nginx/new.conf
# 底层执行的命令
nginx -c /etc/nginx/new.conf
13. CMD 和 RUN 的区别
CMD 是在 docker run 时运行
RUN 是在 docker build 时运行
14. CMD 和 ENTRYPOINT 的区别
CMD 中的参数会被 docker run 后面的参数覆盖
ENTRYPOINT 中的参数不会被 docker run 后面的参数覆盖,且会将参数传递给 指定的程序
3. 构建镜像
# 注意最后的点(.),表示在当前目录下构建新镜像
docker build -t 新镜像名字:标签 .
4. 运行容器
docker run 镜像名/镜像ID
5. 虚悬镜像出现的现象
1. 虚悬镜像是怎么出现的
构建或删除镜像的时候,出现一些错误导致仓库和标签都是none,这种虚悬镜像已经失去了存在的意义,白白占用空间
2. 构建虚悬镜像
FROM ubutu
CMD echo "success......"
docker build .

3. 查出所有的虚悬镜像
docker image ls -f dangling=true
4. 删除所有的虚悬镜像
docker image prune
6. 案例
6.1 重制 centos
原始的centos7 并没有vim,ifconfig,jdk8的功能,使用 Dockerfile 自定义镜像 mycentosjava8
1. JDK8 官网下载地址
https://www.oracle.com/java/technologies/downloads/#java8

2. 上传到Linux的 /myfile 目录
3. 编写Dockerfile
vim Dockerfile
Dockerfile
FROM centos   # 指定基础镜像为centos
MAINTAINER xxx<xxxx@xxx.com>  # 指定镜像维护者的信息
ENV MYPATH /usr/local  # 制定环境变量
WORKDIR $MYPATH    # 进入工作目录
# 安装 vim 编辑器
RUN yum -y install vim
# 安装 ifconfig 命令
RUN yum -y install net-tools
# 安装 java8 及 lib 库
RUN yum -y install glbc.i686
RUN mkdir /usr/local/java
# ADD 是相对路径,把 jdk....-x64.tar.gz 添加到容器中,安装包必须要和Dockerfile文件在同一位置,会自动解压
ADD jdk...-x64.tar.gz /usr/local/java
# 配置 java 环境变量
ENV JAVA_HOME /usr/local/java/jdk1.9.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOM/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80  # 对外暴露 80 端口
CMD echo "success......"  # 随便输出一段话表示安装成功
CMD /bin/bash   # 返回一个伪终端
6.2 使用 Docker 发布Spring Boot微服务
1. 创建文件夹
cd /
mkdir myapp
**2. 将 jar 包上传到 Linux 中的 /myapp **
3. 创建 Dockerfile 文件
vim Dockerfile
4. 编写Dockerfile
# 基础镜像使用java
FROM java:8
# VOLUME 指定临时文件目录为 /tmp, 在主机 /var/lib/docker目录下创建了一个临时文件并链接到容器中的 /tmp
VOLUME /tmp
# 将 jar 包添加并解压到容器中,并更名为zzyy_docker.jar
ADD docker_boot-0.0.1-SNAPSHOT.jar zzyy_docker.jar
# 运行jar 包
RUN bash -c 'touch /zzyy_docker.jar'
ENTRYPOINT ["java","-jar","/zzyy_docker.jar"]
# 暴露6001端口为微服务
EXPOSE 6001
5. 制作镜像
# 记得 最后的点(.),指在当前目录下构建镜像
docker build -t zzyy_docker:1.6 .
6. 运行容器
docker run -d -p 6001:6001 zzyy_docker:1.6

                
            
        
浙公网安备 33010602011771号