Dockerfile深度剖析
Dockerfile主要是用来定制镜像
Dockerfile指令集
FROM
###指定基础镜像第一条指令。scratch是虚拟的镜像,表示一个空白的镜像。
FROM centos:7.5
MAINTAINER
###维护人的信息(不推荐使用)
MAINTAINER jockming.com
###推荐使用LABEL来指定镜像作者
LABEL maintainer="jockming.com"
ARG
###在构建镜像时,指定一些参数
FROM centos:7.5
###ARG user=root
ARG user
USER $user
###在执行docker build时就可以带上自定义参数user了
docker build --build-arg user=root Dockerfile .
USER
###为RUN、CMD和ENTRYPOINT执行Shell命令指定运行用户
USER <user>[:<usergroup>]
USER <UID>[:<UID>]
USER root
WORKDIR
###为RUN、CMD、ENTRYPOINT以及COPY和AND设置工作目录
WORKDIR /data
RUN
###执行命令
###shell 格式: RUN <命令> ,RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
###exec 格式: RUN ["可执行文件", "参数1", "参数2"] 。run可以写多个,每一个指令都会建立一层,所以正确写法应该是↓
RUN buildDeps='gcc libc6-dev make' \
&& apt-get update \
&& apt-get install -y $buildDeps \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
&& mkdir -p /usr/src/redis \
&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
&& make -C /usr/src/redis \
&& make -C /usr/src/redis install \
&& rm -rf /var/lib/apt/lists/* \
&& rm redis.tar.gz \
&& rm -r /usr/src/redis \
&& apt-get purge -y --auto-remove $buildDeps
COPY
###复制文本COPY <源路径>... <目标路径>
###COPY ["<源路径1>",... "<目标路径>"]
###<源路径> 可以是多个、以及使用通配符,通配符规则满足Go的filepath.Match 规则,如:COPY hom* /mydir/ COPY hom?.txt /mydir/
###<目标路径>使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。
###拷贝文件或目录到镜像中,用法同ADD,只是不支持自动下载和解压
COPY ./start.sh /start.sh
ADD
###高级复制文件,文件会自动解压,容器内不保留原文件
###ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /<源路径> 可以是一个 URL ,下载后的文件权限自动设置为 600 。
ADD <src>...<dest>
ADD html.tar.gz /var/www/html
ADD https://xxx.com/html.tar.gz /var/www/html
ENV
###设置容器内环境变量
ENV MYSQL_ROOT_PASSWORD 123456
ENV JAVA_HOME /usr/java/jdk1.8.0_241
VOLUME
###指定容器挂载点到宿主机自动生成的目录或其他容器
###目的是为了数据持久化,以及数据共享等
###通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的
VOLUME ["/var/lib/mysql","..."]
EXPOSE
###暴露端口
EXPOSE 80 443 8080
HEALTHCHECK
###告诉Docker如何测试容器以检查它是否仍在工作,即健康检查
HEALTHCHECK --interval=5m --timeout=3s --retries=3 \
CMD curl -f http:/localhost/ || exit 1
###选项
--interval = DURATION (default: 30s):每隔多长时间探测一次,默认30秒
-- timeout = DURATION (default: 30s):服务响应超时时长,默认30秒
--start-period = DURATION (default: 0s):服务启动多久后开始探测,默认0秒
--retries = N (default: 3):认为检测失败几次为宕机,默认3次
###返回值
0:容器成功是健康的,随时可以使用
1:不健康的容器无法正常工作
2:保留不使用此退出代码
ENTRYPOINT
###启动容器时执行的Shell命令,同CMD类似,只是由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定指定的程序,例如:
ENTRYPOINT ["/bin/bash", "-C", "/start.sh"]
ENTRYPOINT /bin/bash -C '/start.sh'
PS:Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效。
CMD
shell 格式: CMD <命令>
exec 格式: CMD ["可执行文件", "参数1", "参数2"...]
CMD ["nginx", "-g", "daemon off;"]ENTRYPOINT:入口点
同CMD,指定容器启动程序及参数。
通过--entrypoint 参数在运行时替换。
用例一:使用CMD要在运行时重新写命令才能追加运行参数,ENTRYPOINT则可以运行时接受新参数。
CMD ["-C", "/start.sh"]
CMD ["/usr/sbin/sshd", "-D"]
CMD /usr/sbin/sshd -D
案例
在/home/software/目录下执行
创建文件
touch Dockerfile
赋权
chmod +x Dockerfile
Dockerfile文件内容如下:
# This dockerfile uses the centos7 image
# VERSION 1 - EDITION 1
# Author: jockming
#指定基础镜像
FROM centos:7
#指定维护者信息
LABEL maintainer="jockming.com"
#设置工作目录
#WORKDIR /usr/local/tomcat8/tomcat8080
#创建目录
RUN mkdir -p /usr/local/java/ \
&& mkdir -p /usr/local/tomcat8/
#复制jdk到镜像中
ADD jdk-8u241-linux-x64.tar.gz /usr/local/java/
#设置环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_241
ENV PATH $JAVA_HOME/bin:$PATH
#复制tomcat到镜像中,ADD命令会自动解压
ADD apache-tomcat-8.5.32.tar.gz /usr/local/tomcat8/
#删除安装包,改名
RUN cd /usr/local/tomcat8/ \
&& mv apache-tomcat-8.5.32 tomcat8080
#复制tomcat配置到镜像中
COPY server.xml /usr/local/tomcat8/tomcat8080/conf
#设置工作目录
WORKDIR /usr/local/tomcat8/tomcat8080/
#暴露端口
EXPOSE 8080
#启动容器是执行的命令,"./bin"是相对于工作目录的
ENTRYPOINT ./bin/startup.sh && tail -F ./logs/catalina.out
准备jdk安装包和tomcat安装包,放到这个目录下/home/software/
准备tomcat配置文件server.xml,放到这个目录下/home/software/
构建镜像
###进入到dockerfile文件所在的目录执行以下命令
###docker build -f DockerFile路径 -t 名称 .
docker build -f ./Dockerfile -t tomcat8:v1 .
查看镜像
docker images
运行镜像
docker run -itd --name=tomcat8 -p 8080:8080 \
-v /app/webapps/:/usr/local/tomcat8/tomcat8080/webapps/ \
tomcat8:v1 /bin/bash
ps:在宿主机的目录下解压tomcat压缩包,把webapps目录下的所有文件复制到这个目录下"/app/webapps/"。
由于在指定数据卷时"-v /app/webapps/:/usr/local/tomcat8/tomcat8080/webapps/",宿主机目录"/app/webapps/"下没有文件,因此容器内的"/usr/local/tomcat8/tomcat8080/webapps/"这个目录下也就没有文件,到时候通过浏览器访问不到,会报错:404。
容器启动后,就可以通过浏览器直接访问tomcat的默认目录。
浏览器输入:http://IP:8080
查看容器
docker ps -a
查看启动日志
docker logs -f 容器ID