Dockerfile
1465字约5分钟
2025-05-28
Dockerfile
# 基于centos
FROM centos
# 设置环境目录
ENV MYPATH /usr/local
# 设置工作目录,就是进入终端之后默认进入的目录
WORKDIR $MYPATH
# 下载软件
RUN yum -y install vim
# 映射端口
EXPOSE 8080:80
[root@hadoop01 dockerDemo]# docker build -f Dockerfile文件名 -t 自定义镜像名:自定义版本号 .
[root@hadoop01 dockerDemo]# docker build -f Dockerfile -t nginx66:0.1 .
1. FROM
作用:指定基础镜像,是 Dockerfile 的必需首行指令。 语法:
FROM <image>[:<tag>] [AS <name>]
FROM python:3.9-slim-buster # 使用Python官方轻量级镜像
- 最佳实践
- 使用官方镜像或经过验证的第三方镜像。
- 始终指定标签(如
python:3.9
),避免使用latest
导致版本不稳定。 - 使用
AS
为阶段命名,支持多阶段构建(如AS builder
)。
2. LABEL
作者信息,名字+邮箱
语法:
LABEL maintainer="John Doe <john@example.com>"
扩展标签
可添加更多镜像信息。
LABEL version="1.0" description="My application"
3. RUN
作用:在构建镜像时执行命令,常用于安装软件或配置环境。 两种形式:
shell 形式
直接执行命令(默认使用
/bin/sh -c
)RUN apt-get update && apt-get install -y python3-pip
exec 形式
以数组形式执行命令,避免 shell 解析。
RUN ["pip", "install", "flask"]
最佳实践
合并多条命令以减少镜像层数(如
&&
连接)。清理临时文件以减小镜像体积:
RUN apt-get update && apt-get install -y python3-pip \ && rm -rf /var/lib/apt/lists/* # 清除APT缓存
4. ADD
作用:复制文件或目录到镜像中,支持 URL 和自动解压。 语法:
ADD <src>... <dest>
ADD app.tar.gz /app/ # 自动解压tar文件
ADD https://example.com/file.txt /tmp/ # 下载远程文件
- 最佳实践
- 优先使用
COPY
,因为ADD
的解压和远程下载功能可能导致意外行为。 - 避免从 URL 下载大文件,改用
RUN wget
或curl
以便清理临时文件。
- 优先使用
5. COPY
作用:复制文件或目录到镜像中,更透明且推荐使用。 语法:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY requirements.txt /app/ # 复制本地文件
COPY --chown=appuser:appuser src/ /app/ # 指定文件所有者
最佳实践
使用
.dockerignore
文件排除不需要的文件(如.git
、node_modules
)。遵循 “依赖优先复制” 原则,减少缓存失效:
COPY requirements.txt /app/ # 先复制依赖文件 RUN pip install -r requirements.txt # 缓存此层 COPY . /app/ # 最后复制应用代码
6. ENV
作用:设置环境变量,可在后续指令中使用。 语法:
ENV <key>=<value> ...
ENV PYTHONUNBUFFERED=1 # 禁用Python输出缓冲
ENV APP_PORT=8080 DB_HOST=localhost
- 最佳实践
- 用于设置不变的环境变量(如配置参数)。
- 敏感信息(如密码)建议通过
docker run --env
传递,而非硬编码在 Dockerfile 中。
7. WORKDIR
作用:设置工作目录,后续指令的相对路径以此为基准。 语法:
WORKDIR /path/to/dir
WORKDIR /app
RUN pip install -r requirements.txt # 在/app目录执行
CMD ["python", "app.py"] # 运行/app/app.py
- 最佳实践
- 使用绝对路径,避免路径歧义。
- 若目录不存在,
WORKDIR
会自动创建。
8. VOLUME
作用:创建挂载点,用于数据持久化或容器间共享。 语法:
VOLUME ["/data"]
VOLUME /var/log/app # 挂载日志目录
- 注意事项
- 挂载点在运行时由 Docker 管理,镜像构建时无法操作其中的内容。
- 建议在
docker run
时通过-v
或--mount
参数显式挂载,而非依赖 Dockerfile 中的VOLUME
。
9. EXPOSE
作用:声明容器运行时监听的端口,仅作文档用途,不实际映射端口。 语法:
EXPOSE <port> [<port>/<protocol>]
EXPOSE 8080/tcp # 声明HTTP服务端口
EXPOSE 5432/udp # 声明UDP端口
- 最佳实践
- 配合
docker run -p
或docker-compose.yml
中的端口映射使用。 - 支持多个端口声明(如
EXPOSE 80 443
)。
- 配合
10. CMD
作用:设置容器启动时的默认命令,若有多个CMD
,仅最后一个生效。 三种形式:
exec 形式(推荐)
CMD ["python", "app.py"] # 直接执行命令
当运行容器的时候会在容器里面执行
pyhton app.py
shell 形式
CMD python app.py # 通过shell执行,可能导致信号处理问题
当运行容器的时候会在容器里面执行
pyhton app.py
作为
ENTRYPOINT
的默认参数ENTRYPOINT ["python", "app.py"] CMD ["--host=0.0.0.0"] # 此参数会传递给ENTRYPOINT
最佳实践
使用 exec 形式避免 shell 包装,确保进程接收 Docker 的信号(如
SIGTERM
)。若需运行多个命令,可封装为脚本并执行:
CMD ["/scripts/start.sh"]
11. ENTRYPOINT
作用:配置容器启动时的执行命令,与CMD
配合可实现参数化。 两种形式:
exec 形式(推荐)
ENTRYPOINT ["python", "app.py"] CMD ["--port=8080"] # 默认参数,可被docker run覆盖
shell 形式
ENTRYPOINT python app.py # 会忽略CMD和docker run的参数
示例
ENTRYPOINT ["python", "app.py"] # 固定命令 # 运行时可覆盖参数:docker run myimage --port=8000
最佳实践
- 使用 exec 形式,允许通过
docker run --entrypoint
覆盖。 - 常用于封装可执行程序(如数据库客户端、CLI 工具)。
- 使用 exec 形式,允许通过
12. ONBUILD
作用:设置触发器,当该镜像被其他镜像用作基础镜像时执行。
ONBUILD
指令的作用是为基础镜像添加触发器,当其他镜像通过FROM
指令继承该基础镜像时,这些触发器会被自动执行。
语法:
ONBUILD <INSTRUCTION>
ONBUILD COPY . /app
ONBUILD RUN pip install -r requirements.txt
- 最佳实践
- 用于创建可复用的基础镜像(如应用框架镜像)。
- 避免在
ONBUILD
中使用ADD
、COPY
等依赖上下文的指令,可能导致构建失败。
完整示例
以下是一个 Python Flask 应用的 Dockerfile 示例:
# 基础镜像
FROM python:3.9-slim-buster
# 设置工作目录
WORKDIR /app
# 安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 设置环境变量
ENV FLASK_APP=app.py
ENV FLASK_ENV=production
# 暴露端口
EXPOSE 5000
# 定义启动命令
CMD ["flask", "run", "--host=0.0.0.0"]