文章目录
- 7. Dockerfile
- 7.1 Dockerfile介绍
- 7.2 指令规则
- 7.3 指令说明
- 7.3.1 RUN命令的两种格式
- 7.3.1 CMD命令覆盖问题
- 7.3.2 ENTRYPOINT命令使用
- 7.3.3 ENV的使用
- 7.4 构建tomcat Dockerfile案例
- 7.4.1 准备原始文件
- 7.4.2 编写Dockerfile
- 7.4.3 构建镜像
- 7.4.4 验证镜像
- 7.5 构建jdk基础镜像(alpine-java8)
- 7.5.1 准备glibc包
- 7.5.2 编写Dockerfile
- 7.5.3 构建镜像
- 7.5.4 验证镜像
- 7.5.5 上传镜像到docker-hub
- 7.5.5.1 注册创建存储库
- 7.5.5.2 打标签
- 7.5.5.3 上传镜像
- 7.6 基于自定义的镜像构建微服务(SpringBoot)案例
- 7.6.1 准备微服务包
- 7.6.2 编写Dockerfile
- 7.6.3 构建镜像
- 7.6.4 运行镜像
7. Dockerfile
7.1 Dockerfile介绍
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需要的指令和参数构成的脚本。
官方语法文档:https://docs.docker.com/engine/reference/builder/
上面打不开的,可以https://9w94o-jhdoy-qp3y6-s66fo.glados.space
通过这个地址申请打开。
7.2 指令规则
- 指令大写,后面跟随至少一个参数
- 指令按照从上到下顺序执行
- #表示注释
- 每条指令会创建一个新的镜像层,并对镜像进行提交
7.3 指令说明
指令 | 说明 |
---|---|
FROM | 基础镜像,当前新镜像是基于哪个镜像的,指定一个存在的镜像作为模板,第一条必须是FROM |
MAINTAINER | 镜像作者的姓名和邮箱 |
RUN | 容器构建时需要执行的命令 两种格式:shell格式和exec格式 RUN命令是在docker构建时运行 |
EXPOSE | 当前容器对外暴露的端口 |
WORKDIR | 指定在创建容器后,终端默认登录进来的工作目录 |
USER | 指定该镜像以什么样的用户去执行,如果不指定,默认是root |
ENV | 用来在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包 |
COPY | 将容器内路径和主机路径关联。 |
VOLUME | 容器卷,用于数据保存和持久化工作 VOLUME指定的路径宿主机和容器内部的路径必须是相同的,如果要不同,只能通过docker run -v的形式指定 |
CMD | 指定容器启动后,需要执行的某个命令 Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换。 |
ENTRYPOINT | 类似于CMD命令,但是ENTRYPOINT不会被docker run后面的命令覆盖, 而且这些命令行参数会被当做参数送给ENTRYPOINT指令指定的程序。 |
7.3.1 RUN命令的两种格式
shell格式:RUN yum -y install vim
exec格式:RUN [“./test.php”,“dev”,“offline”]
7.3.1 CMD命令覆盖问题
注意事项:当带参数执行docker run命令时,参数会覆盖已有的CMD命令。
# 第一种,不带参数的,这种情况可以正常运行
docker run -it -p 8080:8080 billygoo/tomcat8-jdk8
# 第二种,带参数/bin/bash,这种情况不能正常运行
docker run -it -p 8080:8080 billygoo/tomcat8-jdk8 /bin/bash
这时候就没看到tomcat启动起来,通过docker ps -a
可以看到COMMAND列被替换为了/bin/bash
,所以就根本没执行catalina.sh run
CMD是在docker run时运行,而RUN是在docker build时运行。
7.3.2 ENTRYPOINT命令使用
当ENTRYPOINT和CMD一起使用时,即在ENTRYPOINT的后面一行添加了CMD命令,那么CMD不再是直接运行的命令,而是将其内容作为参数传递给ENTRYPOINT指令。
ENTRYPONIT ["nginx" "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
比如上面的2行,CMD后面的不再是可以直接运行的命令,而是当做参数传递给了ENTRYPOINT,那么在实际执行时会执行下面shell命令
nginx -c /etc/nginx/nginx/conf
第一点需要注意的地方:
这里的CMD包含的内容,就是给nginx指定了在启动时,默认的配置文件是/etc/nginx/nginx/conf。
第二点需要注意的地方:
假设在执行docker run的命令时,如果又指定了外部的参数,如下:
docker run nginx:test -c /etc/nginx/new.conf
这里对照docker run的语法对比了下:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
-c如果作为COMMAND,那么/etc/nginx/new.conf就作为ARG, 即如下:
docker run nginx:test /etc/nginx/new.conf
这时/etc/nginx/new.conf作为参数可以替换掉原有的CMD中的参数。
7.3.3 ENV的使用
ENV可以用来定义变量:
# 指定进入到容器内部时的默认路径
ENV BASE_PATH /opt/local/
WORKDIR $BASE_PATH
7.4 构建tomcat Dockerfile案例
7.4.1 准备原始文件
glic文件,从下面连接获取。
https://gitee.com/pang123/alpine-tomcat/
tomcat文件,从官网下载,这里下载tomcat8 core包10m。
https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.93/bin/apache-tomcat-8.5.93.tar.gz
基础镜像包,这里选用alpine linux,非常小,只有5.61MB,不需要手工下载。
7.4.2 编写Dockerfile
FROM alpine:3.18.3COPY glibc/ .
ADD apache-tomcat-8.5.93.tar.gz /usr/local
ENV TOMCAT_HOME=/usr/local/apache-tomcat-8.5.93
RUN \mv sgerrand.rsa.pub /etc/apk/keys/sgerrand.rsa.pub; \apk add *.apk; \rm -rf *.apk; \#install jdk and useful utilsecho "http://mirrors.aliyun.com/alpine/v3.18/main/" > /etc/apk/repositories; \echo "http://mirrors.aliyun.com/alpine/v3.18/community/" >> /etc/apk/repositories; \apk upgrade; \apk add --no-cache ca-certificates unzip curl bash bash-completion wget vim net-tools tzdata openjdk8; \rm -rf /tmp/* /var/cache/apk/*; \ln -s $TOMCAT_HOME /usr/local/tomcat;ENV CATALINA_HOME=/usr/local/tomcat \LANG=C.UTF-8 \TZ=Asia/Shanghai
ENV PATH=$CATALINA_HOME/bin:$PATH
WORKDIR /usr/local/tomcat
EXPOSE 8080CMD ["catalina.sh", "run"]
7.4.3 构建镜像
# 构建命令语法(最后有一个点号)
docker build -t 新镜像名字:TAG .# tomcat案例
docker build -t tomcat:8.5.93 .
构建时间比较长,大约5分钟,构建成功后,在dokcer images中可以查看到镜像只有190M左右。
7.4.4 验证镜像
docker run -d -p 8080:8080 tomcat:8.5.93
7.5 构建jdk基础镜像(alpine-java8)
由于每次基于alpine构建镜像时间非常长,所以我们先基于alpine构建jdk8环境的基础镜像。
以后安装java应用时,可以直接使用此镜像扩展,也不需要再准备glibc包,这里jdk环境是基于openjdk8。
7.5.1 准备glibc包
将https://gitee.com/pang123/alpine-tomcat/
下面的glibc文件夹整个拷贝到和Dockerfilie相同目录。
7.5.2 编写Dockerfile
FROM alpine:3.18.3
MAINTAINER 硅谷工具人COPY glibc/ .
RUN \mv sgerrand.rsa.pub /etc/apk/keys/sgerrand.rsa.pub; \apk add *.apk; \rm -rf *.apk; \#install jdk and useful utilsecho "http://mirrors.aliyun.com/alpine/v3.18/main/" > /etc/apk/repositories; \echo "http://mirrors.aliyun.com/alpine/v3.18/community/" >> /etc/apk/repositories; \apk upgrade; \apk add --no-cache ca-certificates unzip curl bash bash-completion wget vim net-tools tzdata openjdk8; \rm -rf /tmp/* /var/cache/apk/*;CMD /bin/bash
7.5.3 构建镜像
docker build -t alpine_java8:1.0.0 .
7.5.4 验证镜像
docker run -it alpine_java8:1.0.0
7.5.5 上传镜像到docker-hub
7.5.5.1 注册创建存储库
先注册,https://hub.docker.com
然后创建docker-hub的存储库。
7.5.5.2 打标签
docker tag alpine_java8:1.0.0 wz220321/alpine_java8:1.0.0
tag后面第一个alpine_java8:1.0.0是本地的镜像的名称和版本
tag后面第二个wz220321/alpine_java8:1.0.0 是docker-hub服务器存储库的名称和指定的版本号。
7.5.5.3 上传镜像
注意:先登录,然后才能上传,不然没权限,账号和密码就是注册时填写的。
先登录成功后,将本地打过标签的镜像上次到Docker Hub的仓库中。
docker login -u wz220321 -p 你的密码
docker push wz220321/alpine_java8:1.0.0
然后去docker_hub上查看就可以看到,这个包含jdk8的压缩包仅仅100m左右。
我们也可以直接通过search看到这个镜像。
7.6 基于自定义的镜像构建微服务(SpringBoot)案例
7.6.1 准备微服务包
准备好SpringBoot程序,启动端口是9001。
本地测试:
程序打包jar
7.6.2 编写Dockerfile
这里基于7.5中自己制作的jdk8的镜像wz220321/alpine_java8镜像编写。
FROM wz220321/alpine_java8:1.0.0
MAINTAINER 硅谷工具人# 映射本地宿主机目录/tmp链接到容器的/tmp目录
VOLUME /tmp
# 将jar包添加到容器中,并重命名
ADD springboot-demo-1.0-SNAPSHOT.jar springboot.jar
# 运行jar包
#RUN bash -c 'touch /springboot.jar'
ENTRYPOINT ["java", "-jar", "/springboot.jar"]
EXPOSE 9001
7.6.3 构建镜像
docker build -t springboot:1.0 .
7.6.4 运行镜像
docker run -d -p 9001:9001 springboot:1.0
web测试:
通过上面的案例可以看到这个容器运行springboot程序,整个镜像只需要195M就可以了。
alipine是个非常轻量级linux,推荐大家使用,如果是部署java程序则可以直接引用我制作的jdk镜像(wz220321/alpine_java8:1.0.0)。