Docker File编写实战指南
DockerFile 基础概念
DockerFile 是用于构建 Docker 镜像的脚本文件,它包含一系列指令和参数,系统会按照这些指令自动生成镜像。
使用流程如下:
- 编写 DockerFile 脚本
- 执行
docker build生成镜像 - 通过
docker run启动容器 - 使用
docker push上传镜像到仓库
DockerFile 编写规范
核心规则
- 所有保留指令必须大写
- 指令按顺序从上到下执行
- 每条指令都会创建一个新镜像层并提交
#表示注释行
常用指令详解
- FROM:设定基础镜像,类似于面向对象中的父类继承
- MAINTAINER:标注作者信息,通常为姓名+邮箱格式
- RUN:在构建镜像时执行的命令
- ADD:添加压缩文件,构建时自动解压
- WORKDIR:设定容器启动后的默认工作目录
- VOLUME:配置数据卷挂载点
- EXPOSE:声明容器运行时暴露的端口
- CMD:定义容器启动时执行的命令,仅最后一条生效,可被
docker run后附加命令覆盖 - ENTRYPOINT:定义容器启动时执行的命令,仅最后一条生效,但
docker run后附加命令会拼接到其后 - ONBUILD:触发器,当当前镜像被其他 DockerFile 继承时,在构建子镜像前执行此指令
- COPY:将文件复制到镜像中
- ENV:设置环境变量
实战示例:定制 CentOS 镜像
官方 CentOS 镜像缺少一些常用工具,我们可以扩展它。
编写 DockerFile
FROM centos
MAINTAINER dev_team<dev@example.com>
RUN yum -y install vim
RUN yum -y install net-tools
ENV WORK_DIR /usr/local
WORKDIR $WORK_DIR
VOLUME /data
EXPOSE 80
CMD echo "Build completed"
CMD echo "Working dir: $WORK_DIR"
CMD /bin/bash
构建镜像
# 标准构建命令,-f 指定文件路径,-t 指定镜像名称:标签
docker build -f ./centos-custom -t mycentos:1.0 .
# 查看镜像构建历史
docker history mycentos:1.0
启动容器验证
docker run -it mycentos:1.0
进入容器后,默认路径为 /usr/local,且 ifconfig 和 vim 均可用。
CMD 与 ENTRYPOINT 深度对比
相同点
- 两者都定义容器启动时的执行命令
- 优先级相同,同一类型中仅最后一条生效
- 若同时存在,最后出现的那个指令生效
不同点
- CMD:
docker run后附加命令会完全替换 CMD 定义 - ENTRYPOINT:
docker run后附加命令会拼接到 ENTRYPOINT 定义的命令之后
测试场景
CMD 被替换
# DockerFile
FROM centos
CMD ["ls", "-a"]
# 运行并附加命令
docker run test-cmd echo "hello"
# 输出: hello(CMD的ls命令未执行)
ENTRYPOINT 拼接
# DockerFile
FROM centos
ENTRYPOINT ["ls", "-a"]
# 运行并附加参数
docker run test-entrypoint -l
# 实际执行: ls -a -l,输出详细目录列表
生产案例:构建 Tomcat 镜像
准备资源
- apache-tomcat-9.0.37.tar.gz
- jdk-8u261-linux-x64.tar.gz
编写 DockerFile
FROM centos
MAINTAINER team<team@example.com>
COPY readme.txt /usr/local/readme.txt
ADD apache-tomcat-9.0.37.tar.gz /usr/local
ADD jdk-8u261-linux-x64.tar.gz /usr/local
RUN yum -y install vim
RUN yum -y install net-tools
ENV APP_DIR /usr/local
WORKDIR $APP_DIR
ENV JAVA_HOME /usr/local/jdk1.8.0_261
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.37
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD $CATALINA_HOME/bin/startup.sh && tail -F $CATALINA_HOME/logs/catalina.out
启动容器并挂载卷
docker run -d -p 8000:8080 \
--name tomcat-app \
-v /host/webapps/test:/usr/local/apache-tomcat-9.0.37/webapps/test \
-v /host/logs:/usr/local/apache-tomcat-9.0.37/logs \
my-tomcat-image
部署测试应用
创建 WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
</web-app>
创建 index.jsp
<html>
<head><title>Test App</title></head>
<body>
Hello from Docker!<br/>
<%
System.out.println("=== Access log entry ===");
%>
</body>
</html>
访问 http://server-ip:8000/test/ 即可看到页面。通过访问挂载的日志目录 logs/catalina.out 可以查看输出信息。
注意事项
挂载数据卷时,若直接挂载到 webapps 目录层级,会覆盖容器内原有内容,导致默认应用不可用。建议挂载到具体子目录。