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
posted @ 2024-02-21 14:08  河图s  阅读(79)  评论(0)    收藏  举报