前言:
docker仓库可以给我们提供很多镜像,但是我们经常需要使用自定义的镜像,这时可以使用Docker Dockerfile来构建私有镜像,本文将讲解使用Dockerfile构建镜像的指令与格式。
一、Dockerfile指令
FROM 指定基础镜像来源
RUN 执行命令,可以使用shell格式或exec格式
COPY 拷贝文件
ADD 拷贝文件并解压
CMD 容器启动命令
ENV 设置镜像环境变量
USER 指定使用的账号,需要在构建时使用useradd创建用户才能使用
ARG 构建参数,类似ENV,但只在Dockerfile构建镜像时参数生效,完成的镜像内部不存在此参数
EXPOSE 声明端口号
ENTRYPOINT 命令入口点
WORKDIR 指定工作目录
VOLUME 指定匿名数据卷,在未使用-v定义数据卷时自动挂载到匿名卷,避免相关数据因容器重启而丢失
HEALTHCHECK 健康检查,用于运行在容器内的进程状态检查
ONBUILD 用于延迟构建命令的执行
二、构建镜像
1、例子1
编写Dockerfile文档
[root /root/dk]# vim Dockerfile
FROM java:8-jdk-alpine
RUN apk add --no-cache tzdata
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone
RUN apk del tzdata
使用docker命令构建镜像
[root /root/dk]# docker build -t openjdk-alpine-8-shanghai:v1.0 .
例子1使用了java:8-jdk-alpine为基础镜像,构建了一个亚洲上海时区且名为openjdk-alpine-8-shanghai:v1.0的镜像。
主要步骤使用java:8-jdk-alpine基础镜像,安装tzdat软件,拷贝并覆盖文件,修改文件,最后删除tzdata软件。
但是以上构建犯了一个新手的错误,就是构建的镜像很臃肿,因为Docker中每一个指令就构建一层镜像,等于构建了5层的镜像(每一层都会把上一层的东西装进下一层)。
所以相同RUN命令可以使用&&串联起来,如下:
[root /root/dk]# vim Dockerfile
FROM java:8-jdk-alpine
RUN apk add --no-cache tzdata && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && \
apk del tzdata
这样只需要两层就可以构建一个新的镜像了。
2、例子2
封装java镜像
新建一个空文件夹
[root /root]# mkdir /root/dk
里面包含两个文件,如下
[root /root/dk]# tree
.
├── Dockerfile
└── test.jar
编写Dockerfile文档
[root /root/dk]# vim Dockerfile
FROM openjdk-alpine-8-shanghai:v1.0
COPY ./test.jar .
ENTRYPOINT ["java","-jar","test.jar"]
构建镜像
[root /root/dk]# docker build -t test:v1.0 .
Sending build context to Docker daemon 820.7kB
Step 1/3 : FROM openjdk-alpine-8-shanghai:v1.0
---> 1c51fd8dc293
Step 2/3 : COPY ./test.jar .
---> 799e38d71ed2
Step 3/3 : ENTRYPOINT ["java","-jar","test.jar"]
---> Running in 8f6cae544f2a
Removing intermediate container 8f6cae544f2a
---> a1690f111b73
Successfully built a1690f111b73
Successfully tagged test:v1.0
启动镜像
[root /root]# docker run -name test -p 80:80 -d test:v1.0 -server
例子2使用三个指令构建了新镜像,这里需要注意的几点有:
1)docker运行模式是C/S,所以docker build 命令构建时读取的目录不是本地路径,而是上下文路径(需理解)
2)Dockerfile使用ENTRYPOINT与使用CDM的区别(需理解)
尾声:
为华为打call