Dockerfile详解

Dockerfile 核心指令说明

指令 作用 执行阶段 示例 注意事项
FROM 指定基础镜像 构建阶段 FROM ubuntu:22.04 必须为Dockerfile的第一个指令;支持多阶段构建中多次使用;scratch表示空镜像
RUN 执行命令并创建新的镜像层 构建阶段 RUN apt-get update && apt-get install -y nginx RUN ["apt-get", "install", "-y", "nginx"] 推荐使用exec格式(JSON数组)避免shell注入风险;合并多个命令减少镜像层数;清理缓存命令放同一层
COPY 复制本地文件/目录到镜像 构建阶段 COPY app.py /app/ COPY ["src/*.py", "/app/"] 仅复制文件,不支持URL和自动解压;目标路径不存在会自动创建;使用.dockerignore排除不需要的文件
ADD 复制文件/目录或远程URL文件到镜像 构建阶段 ADD https://example.com/file.tar.gz /tmp/ 支持自动解压tar.gz文件和URL下载;优先使用COPY(更明确);远程URL文件不会自动解压
CMD 指定容器启动命令 运行阶段 CMD ["nginx", "-g", "daemon off;"] 每个Dockerfile只能有一个CMD,多个则最后一个生效;可被docker run命令参数覆盖;通常用于设置默认参数
ENTRYPOINT 设置容器入口点 运行阶段 ENTRYPOINT ["nginx"] <br> ENTRYPOINT nginx 不可被docker run命令直接覆盖(需使用--entrypoint选项);常与CMD配合使用(CMD作为参数)
ENV 设置环境变量 构建+运行阶段 ENV APP_HOME=/app ENV PATH=$PATH:/usr/local/bin 环境变量在构建和运行时均可用;可通过docker run -e覆盖;使用ENV key=value格式,等号前后无空格
WORKDIR 设置工作目录 构建+运行阶段 WORKDIR /app WORKDIR /usr/local/nginx 后续指令的工作目录;若不存在会自动创建;推荐使用绝对路径;可多次使用切换目录
EXPOSE 声明容器运行时监听的端口 构建阶段(声明) EXPOSE 80/tcp EXPOSE 443/udp 仅为文档说明,不实际映射端口;需通过docker run -p实际映射;可指定协议(tcp/udp)
VOLUME 创建匿名卷 构建+运行阶段 VOLUME ["/data"] VOLUME /var/log 运行时会自动创建匿名卷,避免数据丢失;无法指定宿主机路径(运行时通过-v指定)
ARG 定义构建参数 构建阶段 ARG VERSION=1.0 ARG USER=builder 仅在构建时可用,运行时不可访问;可通过docker build --build-arg覆盖;默认值可选
LABEL 添加镜像元数据 构建阶段 LABEL maintainer="dev@example.com" version="1.0" 键值对格式,可包含多个标签;使用OCI标准标签提高兼容性;通过docker inspect查看
ONBUILD 设置子镜像构建触发器 构建阶段(子镜像) ONBUILD COPY . /app <br> ONBUILD RUN npm install 当当前镜像被用作其他镜像的基础镜像时触发;避免在基础镜像中过度使用
HEALTHCHECK 定义容器健康检查命令 运行阶段 `HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost/
SHELL 更改默认shell 构建阶段 SHELL ["/bin/sh", "-c"] <br> SHELL ["powershell", "-Command"] Windows容器常用;影响RUN/CMD/ENTRYPOINT的shell模式执行;默认Linux为["/bin/sh", "-c"]
USER 指定运行用户 构建+运行阶段 USER www-data USER 1000:1000 需确保用户已存在(可通过RUN创建);切换后后续指令均使用该用户;降低权限增强安全性
STOPSIGNAL 设置容器停止信号 运行阶段 STOPSIGNAL SIGTERM <br> STOPSIGNAL 15 默认为SIGTERM;指定容器接收的停止信号;与应用程序信号处理机制配合使用
AS 为多阶段构建中的阶段命名 构建阶段 FROM node:18 AS builder FROM alpine:latest AS runner 配合多阶段构建使用;通过--from=builder引用其他阶段文件;减少最终镜像大小
复制代码
docker build -t myalpine:v1.0 -f Dockerfile . --progress=plain --no-cache

--progress=plain 是一个控制构建输出日志显示格式的选项

--no-cache:强制重新执行所有步骤(不利用缓存)

RUN: 镜像构建阶段

CMD:镜像运行阶段

指令测试

RUN指令

1. 准备Dockerfile指令

复制代码
-c 非交互模式

2.build镜像

复制代码
docker build -t run-test:v1.0 -f Dockerfile . --progress=plain --no-cache
  1. 在build中,执行了RUN指令
  2. RUN [ "echo","docker构建阶段成功-execV1"," $APP_NAME" ] 存在bug,无法使用env变量
  3. CMD中的未打印出结果,表示CMD没有在构建阶段执行

3.启动镜像

复制代码
# docker run -it --name run-container run-mirror:v0.0.1

ARG指令

作用:定义变量,build构建时使用的变量

复制代码
docker build --build-arg #修改变量

使用默认值

build时自定义ARG参数值

使用场景

自定义基础镜像版本

复制代码
# 自定义镜像版本(默认最新版本)
ARG version=latest
FROM alpine:${version}

自定义用户名

自定义路径

ENV指令

一般容器运行时使用,可通过

复制代码
docker run -e 启动镜像时修改环境变量

查询所有的环境变量

复制代码
docker image inspect  容器名称

USER指令

使用root账号有风险,设置一个账号专门管理

多阶段构建示例

bash 复制代码
# 构建阶段 
FROM maven:3.8-openjdk-17 AS builder 
WORKDIR /app 
COPY pom.xml . COPY src ./src 
RUN mvn package -DskipTests  



# 运行阶段 
FROM openjdk:17-jdk-slim 
WORKDIR /app 
COPY --from=builder /app/target/*.jar app.jar 
EXPOSE 8080 
ENTRYPOINT ["java", "-jar", "app.jar"]

RUN

CMD

相关推荐
muyun28003 小时前
Docker 下部署 Elasticsearch 8 并集成 Kibana 和 IK 分词器
elasticsearch·docker·容器
東雪蓮☆3 小时前
深入理解 LVS-DR 模式与 Keepalived 高可用集群
linux·运维·服务器·lvs
qq_264220893 小时前
LVS负载均衡群集和LVS+Keepalived群集
运维·负载均衡·lvs
乌萨奇也要立志学C++4 小时前
【Linux】进程概念(二):进程查看与 fork 初探
linux·运维·服务器
雨落Liy4 小时前
Nginx 从入门到进阶:反向代理、负载均衡与高性能实战指南
运维·nginx·负载均衡
Nazi64 小时前
k8s的dashboard
云原生·容器·kubernetes
Yyyy4824 小时前
Nginx负载均衡集群实验步骤
运维·nginx·负载均衡
獭.獭.6 小时前
Linux -- 信号【上】
linux·运维·服务器
hashiqimiya6 小时前
centos配置环境变量jdk
linux·运维·centos
路由侠内网穿透7 小时前
本地部署 GPS 跟踪系统 Traccar 并实现外部访问
运维·服务器·网络·windows·tcp/ip