本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2022-07-06
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。
1、编写Dockerfile文件
2、docker build 命令构建镜像
3、docker run 根据镜像运行容器实例
Dockerfile内容基础知识:
大致流程:
1、docker从基础镜像运行一个容器
2、执行一条指令并对容器作出修改
3、执行类似docker commit的操作提交一个新的镜像层
4、docker再基于刚提交的镜像运行一个新容器
5、执行Dockerfile中的下一条指令直到所有指令都执行完成
FROM: 基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from,FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
中的AS <name>
表示为构建阶段命名,在后续FROM和COPY --from=<name>
说明中可以使用这个名词,引用此阶段构建的映像
MAINTAINER: 镜像维护者的姓名和邮箱地址
RUN: 容器构建时需要运行的命令,是在docker build的时候运行,两种格式,shell、exec。
RUN yum -y install vim
: shell格式,安装vimRUN ["./test.php", "dev", "offline"]
:exec格式,等价于执行 ./test.php dev offline
,后两个是参数。EXPOSE: 当前容器对外暴露的端口
WORKDIR: 指定在创建容器后,终端默认登陆的工作目录,会自动cd到容器实例中的那个目录下。
USER: 指定该镜像以什么样的用户去执行,如果不指定,默认是root。
ENV: 用来在构建镜像过程中设置环境变量,ENV MY_PATH /usr/mytest
,这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样。比如在WORKDIR中使用:WORKDIR $MY_PATH
就会登录后直接cd到/usr/mytest
目录下。
VOLUME: 容器数据卷,用于数据保存和持久化工作。
ADD: 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包,类似于COPY+解压。
COPY: 拷贝文件和目录到镜像中,将从构建上下文目录(执行docker build的目录)的文件/目录 复制到新的一层的镜像内的目标路径。
CMD: 指定容器启动后要干的事情,也执行 shell和exec两种格式。当使用了ENTRYPOINT之后,CMD的作用就变成了传参数。可以有多个CMD指令,但只有最后一个生效,CMD会被docker run 之后的参数替换,docker run -it my_mysql /bin/bash
,/bin/bash
就会取代掉默认 my_mysql这个镜像生成文件Dockerfile中CMD指定的指令。CMD在docker run时运行,RUN是在docker build时运行。即RUN是前期构建增强镜像做的命令,CMD是根据镜像生成容器后需要执行的命令。
ENTRYPOINT: 也是用来指定一个容器启动时要运行的命令,类似于CMD,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当初参数送给ENTRYPOINT指定的程序。
ENTRYPOINT ["nginx" "-c"]
CMD ["/etc/nginx/nginx.conf"]
# 等同于容器启动后执行 nginx -c /etc/nginx/nginx.conf
# 如果我们docker run my_nginx -c /etc/nginx/new.conf
# 在run的时候指定了参数,那么CMD会被覆盖掉,等同于启动后执行的是 nginx -c /etc/nginx/new.conf
在centos镜像上安装vim、ifconfig、java8,这样一个镜像文件应该怎么做。
1、编写文件
# Dockerfile
FROM centos
MAINTAINER abc@qq.com
ENV MY_PATH /usr/local
WORKDIR $MY_PATH
RUN yum -y install vim
RUN yum -y install net-tools
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
# jdk-8u171-linux-x64.tar.gz 这个包要在当前执行docker build的目录下
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
# 配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
# 使用:分割,后面再接一个$PATH指的是保持原来PATH里的内容,理解的话可以看做是 i = i + 1
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80
CMD echo $MY_PATH
CMD echo "success"
CMD /bin/bash
2、构建
# 在Dockerfile所在的目录下执行 应该在别目录下执行docker build 然后使用 -f 参数指定Dockerfile所在的目录 -f /usr/local/Dockerfile
# 注意最后有个点
docker build -t 新镜像名称:TAG .
使用各种 docker 命令,其实就是在使用客户端工具与 Docker 引擎 进行交互。用 docker build 命令来构建镜像时,这个构建过程其实是在 Docker引擎 中完成的,而不是在本机环境。
那么如果在 Dockerfile 中使用了一些 COPY 等指令来操作文件,如何让 Docker引擎 获取到这些文件呢?
这里就有了一个 镜像构建上下文 的概念,即上面最后添加的那个 .
代表以当前目录作为镜像构建上下文,当构建的时候会将这个路径下所有的文件都打包上传给 Docker 引擎,引擎内将这些内容展开后,就能获取到所有指定上下文中的文件了。
比如说 Dockerfile 中的 COPY ./package.json /project,其实拷贝的并不是本机目录下的 package.json 文件,而是 docker引擎 中展开的构建上下文中的文件,所以如果拷贝的文件超出了构建上下文的范围,Docker引擎 是找不到那些文件的。
理解了上面的这些概念,就更方便的去理解 .dockerignore 文件的作用了。即这个上下文目录中可能并不是所有的文件我们都会在 Dockerfile 中使用到,那么这个时候就可以在 .dockerignore 文件中指定在传递给 docker引擎 时需要忽略掉的文件或文件夹。
另外如果使用 docker build .
直接去根据Dockerfile构建镜像,不指定镜像名称和TAG,就会造成虚悬镜像。查看当前所有虚悬镜像的命令是docker image ls -f dangling=true
,删除虚悬镜像的命令是docker image prune
。
# Dockerfile
FROM java:8
MAINTAINER abc@qq.com
# 在主机 /var/lib/docker目录下创建一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为 my_java_server.jar
ADD docker_test.jar my_java_server.jar
# 运行jar包
RUN bash -c 'touch my_java_server.jar'
ENTRYPOINT ["java", "- jar", "/my_java_server.jar"]
EXPOSE 6001
根据Dockerfile构建镜像 docker build -t my_java_docker:1.0 .
根据镜像运行容器docker run -d -p 6001:6001 my_java_docker
,如果有防火墙可以关闭防火墙后重启docker,systemctl stop firewalld
关闭防火墙,systemctl restart docker
重启docker。
使用curl
进行my_java_server的服务是否可以正常访问。