Dockerfile是docker构建镜像的基础,也是docker区别于其他容器的重要特征,正是有了Dockerfile,docker的自动化和可移植性才成为可能。不论是开发还是运维,学会编写Dockerfile几乎是必备的。
1.Dockerfile语法
Dockerfile中每行都以一个关键字为行首,如果一行内容过长,使用“\”换行。
2.关键字
2.1 FROM - Dockerfile的第一行,指定从哪个基础镜像开始构建。
FROM scratch
FROM centos
FROM openjdk:11-jre
FROM python:3.6.5
如果当前要构建的镜像本身就是一个基础镜像
FROM scratch
2.2 LABEL - 描述镜像信息
镜像生成后,可以使用docker inspect查看镜像信息
LABEL key="value"
LABEL maintainer="author <xxx@yyy.com>"
LABEL version="1.2"
2.3 ENV - 设置环境变量。
ENV TEST 1
2.4 RUN - 构建镜像时执行shell命令
多条命令之间使用用&&连接,还可以使用\换行。
RUN apt-get -y update
RUN apt-get -y install nginx
2.5 ADD - 将外部文件拷贝到镜像里
同时,如果文件是压缩文件,ADD可以实现解压缩。
此外,虽然ADD能够添加远程文件(URL),但还是建议使用curl或wget将远程文件下载到容器内部指定目录。
ADD http://nicescale.com/ /data/nicescale.tgz
2.6 COPY - 将编译机本地文件拷贝到镜像文件系统中
与ADD类似,不能使用URL,也不能解压缩文件。
COPY /tmp/nicescale.tgz /data/nicescale.tgz
2.7 WORKDIR - 设置工作目录
相当于在shell中使用cd命令切换当前路径
WORKDIR /var/www
2.8 USER - 设置用户
USER nginx
2.9 VOLUME - 设置容器与宿主机数据共享及数据持久化
也可以在创建容器时使用-v选项 docker run -v <host_dir>:<container_dir> IMAGE (指定宿主机映射目录) 或docker run -v <host_dir>:<container_dir> IMAGE (使用默认的映射目录/var/lib/docker/volumes/<container_id>)达到同样效果
VOLUME ['/data']
2.10 EXPOSE - 指定监听的端口。
EXPOSE 80 443
2.11 ENTRYPOINT - 指定容器启动时执行的命令
Dockerfile中仅最后一条ENTRYPOINT有效。
# exec方式
ENTRYPOINT ['/bin/bash', 'echo','hello world']
# shell方式
ENTRYPOINT echo "hello world"
docker run命令后如果跟了内容,会作为ENTRYPOINT指定的命令的参数,如:
ENTRYPOINT ["/bin/ls"]
如果用以下命令创建并启动容器
docker run <image> -l
那么ENTRYPOINT中指定的命令最终会与-l参数一起运行
/bin/ls -l
另外,ENTRYPOINT还支持shell脚本,来完成更复杂的操作
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
2.12 CMD - 指定容器启动时执行的命令
Dockerfile中仅最后一条CMD有效,并且docker run指定的命令会替代CMD指定的命令。
CMD ["/bin/bash","echo","service started..."]
CMD echo "service started..."
当CMD与ENTRYPOINT同时使用时,CMD后的内容会作为ENTRYPOINT后命令的默认参数,如果docker run后又附带了内容,则附带内容会替换CMD后的内容,作为ENTRYPOINT命令的参数。这样CMD与ENTRYPOINT同时使用,能够构建一个既有默认参数又支持参数传入的镜像。
3.创建镜像
通过当前目录下的Dockerfile文件构建镜像
docker build -t IMAGE:VERSION .
通过指定目录下的Dockerfile文件构建镜像
docker build -t IMAGE:VERSION /app/
4.镜像维护
使用Dockerfile文件维护镜像相对比较容易,只需要修改Dockerfile的部分内容,通过docker build重新构建即可。另外还可以通过“-t”选项指定一个新版本,在新旧两个版本间快速切换。
5.Dockerfile实例
5.1 官方镜像hello-world
# 从零开始构建基础镜像
FROM scratch
# 复制可执行文件到docker虚拟机根目录
COPY hello /
# 启动后运行可执行文件
CMD ["/hello"]
5.2 以centos为基础镜像,创建一个新的镜像,用echo输出字符串
Dockerfile文件内容如下
FROM centos
CMD echo "hello docker $(date)"
创建镜像
$ docker build -t test .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM centos
---> e934aafc2206
Step 2/2 : CMD echo "hello docker $(date)"
---> Running in 9ad050c6be7b
Removing intermediate container 9ad050c6be7b
---> 4b412e803011
Successfully built 4b412e803011
Successfully tagged test:latest
通过镜像创建容器并启动(不指定启动时运行的命令)
$ docker run test --name test1
hello docker Thu May 17 05:09:22 UTC 2018
通过镜像创建容器并启动(指定启动时运行的命令),此时CMD中指定的命令不会执行
# 指定启动时以交互模式在终端运行bash
$ docker run --name test2 -it test /bin/bash
[root@9d4414207eeb /]#
# 指定启动时pwd命令
$ docker run test2 pwd
/
5.3 打包SpringBoot镜像
Dockerfile
FROM openjdk:8-jre
ADD crs-core-0.0.1-SNAPSHOT.jar /opt/jar/crs-core.jar
EXPOSE 8080
CMD ["java","-jar","/opt/jar/crs-core.jar"]
打包镜像过程如下
$ sudo docker build -t crs-core:0.0.1 .
Sending build context to Docker daemon 41.98MB
Step 1/4 : FROM openjdk:8-jre
---> dd20fb277e3c
Step 2/4 : ADD crs-core-0.0.1-SNAPSHOT.jar /opt/jar/crs-core.jar
---> Using cache
---> 021003891a14
Step 3/4 : EXPOSE 8080
---> Using cache
---> b6f8e3d010dd
Step 4/4 : CMD ["java","-jar","/opt/jar/crs-core.jar"]
---> Running in 5b6fb9d78093
Removing intermediate container 5b6fb9d78093
---> 6d9938a0f6be
Successfully built 6d9938a0f6be
Successfully tagged crs-core:0.0.1
查看镜像
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
crs-core 0.0.1 6d9938a0f6be 47 seconds ago 485MB
openjdk 8-jre dd20fb277e3c 2 weeks ago 443MB
启动容器
$ sudo docker run --name crs-core -p 9090:8080 -d crs-core:0.0.1
52dc83fe7542f1958e509bdd905a91f0ac967fe6dd094486c6c13028bc782c4a
[clinflash@localhost crs-docker]$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
52dc83fe7542 crs-core:0.0.1 "java -jar /opt/jar/…" 6 seconds ago Up 5 seconds 0.0.0.0:9090->8080/tcp crs-core