Dockerfile 是一个文本文件,包含了一系列用于构建 Docker 镜像的指令。它允许开发者通过简单的指令定义镜像的构建过程,实现自动化、可重复的镜像构建。
主要作用:
一个典型的 Dockerfile 包含以下部分:
# 注释
指令 参数
构建过程:
FROM ubuntu:20.04
# 使用官方Ubuntu 20.04镜像作为基础
FROM python:3.9-slim
# 使用Python官方提供的精简版3.9镜像
说明:
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# 更新包索引,安装curl和git,然后清理缓存
RUN pip install --no-cache-dir flask gunicorn
# 安装Python依赖但不缓存下载的包
最佳实践:
--no-cache
选项避免缓存COPY . /app
# 将当前目录所有文件复制到容器的/app目录
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
# 只复制requirements文件先安装依赖
ADD 与 COPY 区别:
WORKDIR /app
# 后续指令都在/app目录下执行
特点:
EXPOSE 80
# 声明容器将监听80端口
EXPOSE 3000/tcp
EXPOSE 3000/udp
# 可以指定协议类型
注意:
ENV NODE_ENV=production
ENV APP_HOME=/app
ENV PATH=/app/node_modules/.bin:$PATH
# 可以修改PATH等系统环境变量
用途:
CMD ["python", "app.py"]
# 容器启动时默认运行python app.py
ENTRYPOINT ["/bin/bash", "-c"]
CMD ["echo $HOME"]
# ENTRYPOINT作为主命令,CMD作为参数
区别:
ARG VERSION=latest
FROM ubuntu:$VERSION
# 构建时可以传递--build-arg VERSION=20.04来改变基础镜像版本
特点:
VOLUME /var/lib/mysql
# 将MySQL数据目录声明为卷
用途:
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
# 每30秒检查一次服务是否健康
参数:
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser
# 创建非root用户并切换
安全实践:
ONBUILD COPY . /app
ONBUILD RUN make build
# 这些指令会在基于此镜像构建其他镜像时执行
用途:
# 构建阶段
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .
# 运行阶段
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]
优点:
# 变化频率低的指令放前面
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y package
# 变化频率高的指令放后面
COPY . /app
原理:
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*
# 合并多个RUN命令
技巧:
&&
连接命令\
换行提高可读性.git
node_modules
*.log
.DS_Store
作用:
FROM alpine:latest
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# 使用非root用户
建议:
# 多阶段构建示例 - Python应用
# 构建阶段
FROM python:3.9 as builder
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt
# 运行阶段
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /app/wheels /wheels
COPY --from=builder /app/requirements.txt .
RUN pip install --no-cache /wheels/* \
&& rm -rf /wheels \
&& rm -f requirements.txt
COPY . .
RUN useradd -m myuser && chown -R myuser:myuser /app
USER myuser
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8000/health || exit 1
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
解释:
构建 Docker 镜像是使用 Dockerfile 的最终目的,本节将详细介绍如何使用 docker build
命令从 Dockerfile 创建镜像,并探讨各种构建选项和技巧。
docker build -t my-image:1.0 .
参数解释:
-t my-image:1.0
:为镜像指定名称和标签.
:指定构建上下文路径(Dockerfile 所在目录)构建过程输出示例:
Sending build context to Docker daemon 2.048kB
Step 1/8 : FROM python:3.9-slim
---> 2d0f2f3d3a3a
Step 2/8 : WORKDIR /app
---> Running in a1b2c3d4e5f6
Removing intermediate container a1b2c3d4e5f6
---> 123456789abc
...
Successfully built 789abc123def
Successfully tagged my-image:1.0
当 Dockerfile 不在当前目录或使用不同名称时:
docker build -t my-image -f /path/to/Dockerfile .
示例:
docker build -t backend-app -f docker/backend.Dockerfile .
使用 --build-arg
传递构建参数:
# Dockerfile
ARG VERSION=latest
FROM ubuntu:$VERSION
docker build -t my-ubuntu --build-arg VERSION=20.04 .
典型用途:
跳过缓存:
docker build --no-cache -t fresh-image .
指定缓存来源:
docker build --cache-from=my-image:1.0 -t my-image:1.1 .
对于多阶段构建,可以只构建特定阶段:
# Dockerfile
FROM node:14 as builder
...
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
# 只构建builder阶段
docker build --target builder -t my-app-builder .
查看发送到Docker守护进程的文件:
docker build --no-cache --progress=plain .
优化.dockerignore:
确保.dockerignore文件排除不必要的文件:
.git
node_modules
*.log
*.md
docker buildx build --platform linux/amd64,linux/arm64 -t my-image .
DOCKER_BUILDKIT=1 docker build -t my-image .
# 先安装依赖
COPY package.json .
RUN npm install
# 再复制源代码
COPY . .
查看构建历史:
docker history my-image:1.0
保存镜像到文件:
docker save -o my-image.tar my-image:1.0
从文件加载镜像:
docker load -i my-image.tar
假设有以下项目结构:
/my-app
├── Dockerfile
├── app.py
├── requirements.txt
└── .dockerignore
构建过程:
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
cd /my-app
docker build -t my-python-app .
docker images | grep my-python-app
docker run -d -p 5000:5000 --name test-app my-python-app
curl localhost:5000
通过本文我们全面了解了:
docker build
命令构建镜像关键构建要点:
掌握这些 Dockerfile 编写和镜像构建技能,您将能够为任何应用程序创建高效、可靠的容器镜像,实现开发和生产环境的一致性。