《Docker快速入门(基础篇)》运行的容器,其镜像都来自于Docker Hub官方仓库。然而,在实际项目中,我们编写的程序,如果部署到Docker中,则需要构建自定义镜像,用到Dockerfile文件。
一、Dockerfile简介
1、什么是Dockerfile
Dockerfile,一个文本文件,其内包含了一条条指令,用于构建自定义镜像。每一条指令构建一层镜像,因此每一条指令的内容,就是描述该层镜像应当如何构建。
2、Dockerfile的作用
主要作用有两个:将编写的程序打包成镜像,或者对官方镜像做扩展以满足工作需要。
3、自定义镜像
首先,新建一个Dockerfile文件,并编写自定义镜像构建脚本,具体语法规则参考官方文档或下文常用指令。
然后,打开命令提示符(或终端),执行以下其中一条命令即可。
# 构建镜像
docker build .
# 构建镜像,并指定Dockerfile文件
docker build -f /path/to/a/Dockerfile .
# 构建镜像,指定镜像名称
docker build -t lewis2951/myapp .
docker build -t lewis2951/myapp:1.0.0 .
此时,镜像就构建好了,执行以下命令,可以创建并运行容器:
# 命令格式
docker run 镜像名称[:tag]
# 举例
docker run lewis2951/myapp:1.0.0
4、官方文档
官方指南Dockerfile reference | Docker Documentation。
二、Dockerfile常用指令
这里列举几个常用的指令,包括FROM、ADD、COPY、RUN、CMD、ENV、ARG、EXPOSE、VOLUME等。
1、FROM
指定基础镜像,必须为第一个指令。
# 格式
FROM 镜像名称[:tag]
# 举例
FROM centos
FROM openjdk:17
2、ADD
将宿主机文件添加到容器中,tar文件会自动解压,可以访问网络资源。
# 命令格式
ADD 源路径 目标路径
# 举例
ADD target/demo-1.0-SHAPSHOT.jar demo.jar
3、COPY
功能类似ADD,语法同ADD。
区别:
- ADD:自动解压文件,可访问网络资源
- COPY:不解压文件,不可访问网络资源
4、RUN
构建镜像时执行的命令,每一次RUN都会构建一层。
# 格式
RUN ["可执行文件", "参数1", "参数2"]
# 举例
RUN ["java", "-jar", "demo.jar"]
5、CMD
构建镜像后容器启动时执行的命令,应该仅出现一次,如果存在多个CMD指令,仅最后一个CMD指令有效。
区别:
- RUN:在docker build镜像构建时执行
- CMD:在容器启动时执行
# 格式
CMD ["可执行文件", "参数1", "参数2"]
6、ENTRYPOINT
类似于CMD指令,容器进入时执行的命令,但不会被docker run的命令行参数指定的指令所覆盖。
# 格式
ENTRYPOINT ["可执行文件", "参数1", "参数2"]
7、LABEL
添加元数据。
# 格式
LABEL key=value ...
# 举例
LABEL name="Lewis Lu"
docker image inspect lewis2951/myapp
8、ENV
设置变量,后续指令中可以使用。
# 格式
ENV key=value ...
# 举例
ENV name="Lewis Lu"
9、ARG
设置构建时的变量,与ENV作用一致。
# 格式
ARG name[=defaultValue]
# 举例
# Dockerfile
ARG user
ARG buildNo=1.0.0
docker build --build-arg user=lewis2951 .
10、EXPOSE
申明容器的服务端口。
# 格式
EXPOSE port[/protocal] ...
# 举例
EXPOSE 80/tcp 80/udp
docker run -p 80:80/tcp -p 80:80/udp ...
11、VOLUME
定义数据卷,如果没有定义,则使用默认。
# 格式
VOLUME ["路径1", "路径2", "路径3", ...]
在docker run的时候,使用-v设置数据卷。
12、MAINTAINER(已废弃)
构建维护者信息:姓名、邮箱。
# 命令格式
MAINTAINER 维护者
# 举例
MAINTAINER lewis2951
MAINTAINER lewis2951@xxx.com
MAINTAINER lewis2951 lewis2951@xxx.com