Dockerfile

Dockerfile

指令集

按官方 v1.4 语法,全部大写,大小写不敏感,但行业习惯全大写;

1. 定义基础 & 元数据

指令 作用 示例
FROM 指定基础镜像 FROM python:3.11-alpine
LABEL 为镜像打键值对标签 LABEL maintainer="ops@corp.com"
ARG 声明构建期变量 ARG VERSION=latest

2. 文件系统操作

指令 作用 示例
COPY 复制本地文件/目录 COPY app.py /opt/app/
ADD 类似 COPY,但可解压 tar/远程 URL(不推荐用 URL) ADD app.tar.gz /opt/app/
WORKDIR 设置后续指令的工作目录 WORKDIR /opt/app
VOLUME 声明挂载点(匿名卷) VOLUME ["/data"]

3. 软件安装 & 配置

指令 作用 示例
RUN 构建阶段执行命令,结果提交为新层 RUN apt-get update && apt-get install -y curl
ENV 设置环境变量(运行期也生效) ENV PATH=/usr/local/bin:$PATH

4. 运行阶段

指令 作用 示例
CMD 容器启动默认命令(可被 docker run 覆盖) CMD ["python","app.py"]
ENTRYPOINT 容器入口(通常配 CMD 做默认参数) ENTRYPOINT ["java","-jar","/app.jar"]
EXPOSE 声明监听端口(文档/随机映射用) EXPOSE 8080/tcp

5. 构建阶段控制

指令 作用 示例
ONBUILD 触发器:被别人 FROM 时自动执行 ONBUILD COPY . /app/src
STOPSIGNAL 指定停止容器时发送的信号 STOPSIGNAL SIGTERM
HEALTHCHECK 声明健康检查 `HEALTHCHECK --interval=30s CMD curl -f http://localhost/
SHELL Windows 镜像里替换默认 shell SHELL ["powershell","-Command"]

6. 多阶段构建(Docker 17.05+)

指令 作用 示例
FROM … AS 定义多阶段构建 FROM golang:1.21 AS builder

7. 语法版本声明(放在第一行)

指令 作用 示例
# syntax=docker/dockerfile:1 指定解析器版本 # syntax=docker/dockerfile:1

速记口诀

  • FROM → RUN/COPY → ENV → EXPOSE → CMD/ENTRYPOINT → HEALTHCHECK

掌握以上指令即可覆盖 99% 的构建场景。

样例

# 使用更小的基础镜像
FROM python:3.9-alpine3.16

# 安装依赖
RUN apk add --no-cache \
    tzdata \
    shadow \
    && rm -rf /var/cache/apk/*

# 设置工作目录
WORKDIR /opt/autumn/ssh_monitor

# 复制脚本文件
COPY ssh_monitor.py /opt/autumn/ssh_monitor/ssh_monitor.py

# 安装 Python 依赖
RUN pip install --no-cache-dir dingtalkchatbot==1.5.0

# 创建日志目录
RUN mkdir -p /opt/autumn/ssh_monitor && touch /opt/autumn/ssh_monitor/ssh_monitor.log && chmod 644 /opt/autumn/ssh_monitor/ssh_monitor.log

# 添加健康检查
HEALTHCHECK --interval=5m --timeout=3s \
  CMD pgrep -f 'python /opt/autumn/ssh_monitor/ssh_monitor.py' || exit 1

# 设置容器启动命令
CMD ["python", "/opt/autumn/ssh_monitor/ssh_monitor.py"]

# 暴露必要的文件系统
VOLUME ["/var/log"]

1. 基础镜像

FROM python:3.9-alpine3.16
  • 使用 python:3.9-alpine3.16 作为基础镜像。
  • Alpine 镜像体积极小(≈5 MB),再叠加 Python 运行时,整体镜像可以控制在 50 MB 左右。
  • 注意:Alpine 采用 musl libc,如果依赖的 Python 包需要编译 C 扩展,有可能因为缺少 musl-devgcc 等工具而失败。

2. 安装系统依赖

RUN apk add --no-cache \
    tzdata \
    shadow \
    && rm -rf /var/cache/apk/*
  • tzdata:设置时区用;脚本里如果要按北京时间写日志就需要它。
  • shadow:提供 useradd/groupadd 等管理用户/组的工具;如果你后面想切非 root 用户会用到。
  • --no-cacherm -rf /var/cache/apk/* 作用相同:避免把 apk 缓存留在镜像层里,减小体积。
  • 这两包加起来不到 3 MB,对体积影响很小。

3. 创建工作目录

WORKDIR /opt/autumn/ssh_monitor
  • 设置容器内工作目录,如果目录不存在 Docker 会自动创建。
  • 后续所有相对路径命令都会以该目录为基准。

4. 复制脚本

COPY ssh_monitor.py /opt/autumn/ssh_monitor/ssh_monitor.py
  • 把本地同目录下的 ssh_monitor.py 拷贝到镜像的指定位置。
  • 建议:如果脚本需要配置文件、模板等,可以改成 COPY . . 一次性复制整个目录,再写 .dockerignore 排除不需要的文件。

5. 安装 Python 依赖

RUN pip install --no-cache-dir dingtalkchatbot==1.5.0
  • 安装钉钉机器人 SDK。
  • --no-cache-dir 同样是为了避免 pip 缓存留在镜像层里。
  • 如果后面依赖增多,建议把 requirements.txt 先 COPY 进来,再 pip install -r requirements.txt,这样依赖变化时可以利用 Docker 缓存,减少构建时间。

6. 创建日志文件并赋权

RUN mkdir -p /opt/autumn/ssh_monitor && \
    touch /opt/autumn/ssh_monitor/ssh_monitor.log && \
    chmod 644 /opt/autumn/ssh_monitor/ssh_monitor.log
  • 这三步其实可以合并成一句:
    RUN touch ssh_monitor.log && chmod 644 ssh_monitor.log
    因为上一步 WORKDIR 已经把目录创建好了。
  • 文件权限 644:所有者可读写,组/其他只读;如果容器里用非 root 用户运行,记得改成该用户可写。

7. 健康检查

HEALTHCHECK --interval=5m --timeout=3s \
  CMD pgrep -f 'python /opt/autumn/ssh_monitor/ssh_monitor.py' || exit 1
  • 每 5 分钟执行一次健康检查,超时 3 秒。

  • 检查逻辑:用 pgrep 查找包含指定命令行的进程;找不到说明进程挂了,就返回非 0,Docker 会把容器标成 unhealthy

  • 注意:

    • Alpine 里 pgrep 属于 procps 包,需要提前 apk add procps,否则健康检查命令会失败。
    • 如果脚本本身会 fork 子进程或改名,则 pgrep 可能误判。

8. 容器启动命令

CMD ["python", "/opt/autumn/ssh_monitor/ssh_monitor.py"]
  • 容器启动后执行的唯一进程就是这句 Python 脚本。

  • 如果脚本里有死循环或守护逻辑,这里没问题;否则容器会立刻退出。

  • 建议:

    • exec 形式(数组)而非 shell 形式,确保 PID 1 是 Python 进程,可以正确接收 SIGTERM。
    • 如果脚本需要前台持续运行,确保里面有 while True 或阻塞式监听。

9. 声明卷

VOLUME ["/var/log"]
  • 只是“声明”了一个挂载点 /var/log,告诉使用者“你可以在这里挂卷”。
  • 实际上镜像里并没有往 /var/log 写东西,这个声明对镜像构建没影响,也不会自动挂载宿主机目录。
  • 如果脚本把日志写到 /opt/autumn/ssh_monitor/ssh_monitor.log,而你想持久化,应该
    VOLUME ["/opt/autumn/ssh_monitor"] 或启动容器时 -v /host/path:/opt/autumn/ssh_monitor

posted @ 2025-09-02 11:44  修淳  阅读(17)  评论(0)    收藏  举报