1. Dockerfile 是什么?
Dockerfile 是一个文本文件,里面包含了一系列指令,用来定义如何构建一个 Docker 镜像。你可以把它想象成一个“菜谱”,Docker 会根据这个“菜谱”一步步构建出你想要的镜像。
2. Dockerfile 的基本结构
一个典型的 Dockerfile 由多个指令组成,每个指令对应一个操作。以下是一个简单的 Dockerfile 示例:
Dockerfile复制代码
# 基础镜像
FROM ubuntu:20.04
# 设置工作目录
WORKDIR /app
# 复制文件到容器中
COPY . .
# 安装依赖
RUN apt-get update && apt-get install -y python3
# 暴露端口
EXPOSE 80
# 运行命令
CMD ["python3", "app.py"]
3. Dockerfile 常用指令详解
1. FROM
- 作用:指定基础镜像。
- 语法:
FROM <镜像名>:<标签>
- 示例:
FROM ubuntu:20.04
- 这里我们使用
ubuntu:20.04
作为基础镜像。
- 这里我们使用
2. WORKDIR
- 作用:设置工作目录。后续的命令(如
RUN
、COPY
等)都会在这个目录下执行。 - 语法:
WORKDIR <路径>
- 示例:
WORKDIR /app
- 这里我们将工作目录设置为
/app
。
- 这里我们将工作目录设置为
3. COPY
- 作用:将本地文件或目录复制到容器中。
- 语法:
COPY <源路径> <目标路径>
- 示例:
COPY . .
- 这里我们将当前目录下的所有文件复制到容器的
/app
目录下。
- 这里我们将当前目录下的所有文件复制到容器的
4. RUN
- 作用:在构建镜像时执行命令。通常用于安装软件包或配置环境。
- 语法:
RUN <命令>
- 示例:
RUN apt-get update && apt-get install -y python3
- 这里我们更新包管理器并安装
python3
。
- 这里我们更新包管理器并安装
5. EXPOSE
- 作用:声明容器运行时监听的端口。注意,这只是一个声明,并不会自动映射到主机端口。
- 语法:
EXPOSE <端口号>
- 示例:
EXPOSE 80
- 这里我们声明容器会监听 80 端口。
6. CMD
- 作用:指定容器启动时默认执行的命令。一个 Dockerfile 中只能有一个
CMD
指令。 - 语法:
CMD ["可执行文件", "参数1", "参数2"]
- 示例:
CMD ["python3", "app.py"]
- 这里我们指定容器启动时运行
python3 app.py
。
- 这里我们指定容器启动时运行
7. ENV
- 作用:设置环境变量。
- 语法:
ENV <变量名>=<值>
- 示例:
ENV PYTHON_VERSION=3.8
- 这里我们设置了一个环境变量
PYTHON_VERSION
。
- 这里我们设置了一个环境变量
8. ADD
- 作用:类似于
COPY
,但功能更强大。除了复制文件,还可以解压 tar 文件或从 URL 下载文件。 - 语法:
ADD <源路径> <目标路径>
- 示例:
ADD https://example.com/file.tar.gz /app
- 这里我们从 URL 下载文件并解压到
/app
目录。
- 这里我们从 URL 下载文件并解压到
9. ENTRYPOINT
- 作用:指定容器启动时执行的命令。与
CMD
类似,但ENTRYPOINT
的参数不会被覆盖。 - 语法:
ENTRYPOINT ["可执行文件", "参数1", "参数2"]
- 示例:
ENTRYPOINT ["python3"] CMD ["app.py"]
- 这里我们指定容器启动时运行
python3
,默认参数是app.py
。
- 这里我们指定容器启动时运行
10. VOLUME
- 作用:声明一个挂载点,用于持久化数据。
- 语法:
VOLUME <路径>
- 示例:
VOLUME /data
- 这里我们声明了一个挂载点
/data
。
- 这里我们声明了一个挂载点
4. Dockerfile 最佳实践
1. 减少镜像层数
- 每个
RUN
、COPY
、ADD
等指令都会创建一个新的镜像层。为了减少镜像大小,可以将多个命令合并到一个RUN
中。Dockerfile复制代码RUN apt-get update && apt-get install -y python3 && apt-get clean
2. 使用 .dockerignore
- 类似于
.gitignore
,.dockerignore
可以排除不需要的文件,避免它们被复制到镜像中。
3. 多阶段构建
- 如果你的构建过程比较复杂,可以使用多阶段构建来减少最终镜像的大小。Dockerfile复制代码
FROM node:14 AS build WORKDIR /app COPY . . RUN npm install && npm run build FROM nginx:alpine COPY --from=build /app/dist /usr/share/nginx/html
5. 实战:编写一个 Python 应用的 Dockerfile
假设你有一个 Python 应用,目录结构如下:
my-app/
├── app.py
├── requirements.txt
└── Dockerfile
Dockerfile 内容
# 使用官方的 Python 镜像作为基础镜像
FROM python:3.8-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 5000
# 运行应用
CMD ["python", "app.py"]
构建镜像
docker build -t my-python-app .
运行容器
docker run -p 5000:5000 my-python-app
基础镜像
1. 操作系统基础镜像
这些镜像提供了最基本的操作系统环境,适合需要完全自定义的场景。
1.1 Ubuntu
- 镜像名:
ubuntu
- 特点:功能全面,适合大多数 Linux 应用。
- 常用标签:
ubuntu:20.04
(LTS 版本)ubuntu:22.04
(最新 LTS 版本)ubuntu:latest
(最新稳定版)
1.2 Alpine
- 镜像名:
alpine
- 特点:非常轻量(只有 5MB 左右),适合对镜像大小敏感的场景。
- 常用标签:
alpine:3.14
alpine:latest
1.3 CentOS
- 镜像名:
centos
- 特点:稳定且广泛用于企业环境。
- 常用标签:
centos:7
centos:8
centos:latest
1.4 Debian
- 镜像名:
debian
- 特点:稳定且轻量,适合需要精简环境的场景。
- 常用标签:
debian:buster
debian:bullseye
debian:latest
2. 语言运行时基础镜像
这些镜像已经预装了特定语言的运行时环境,适合直接运行应用程序。
Python
- 官方镜像:
python:3.11-alpine
(轻量版)或python:3.11-slim
(Debian 精简版)。 - 特点:提供不同版本和变体,支持直接运行 Python 应用。
Node.js
- 官方镜像:
node:18-alpine
或node:18-bullseye-slim
。 - 特点:含 npm/yarn,适合前端或 Node 后端服务。
Golang
- 官方镜像:
golang:1.20-alpine
(编译环境),部署时通常使用多阶段构建复制二进制文件到scratch
或alpine
。
Java
- 官方镜像:
eclipse-temurin:17-jdk-jammy
(OpenJDK,基于 Ubuntu)或eclipse-temurin:17-jdk-alpine
(轻量版)。
PHP
- 官方镜像:
php:8.2-apache
(含 Apache)或php:8.2-fpm
(与 Nginx 配合)。
3. 数据库基础镜像
这些镜像预装了数据库服务,适合快速部署数据库。
3.1 MySQL
- 镜像名:
mysql
- 特点:预装了 MySQL 数据库。
- 常用标签:
mysql:5.7
mysql:8.0
mysql:latest
3.2 PostgreSQL
- 镜像名:
postgres
- 特点:预装了 PostgreSQL 数据库。
- 常用标签:
postgres:13
postgres:latest
3.3 Redis
- 镜像名:
redis
- 特点:预装了 Redis 缓存服务。
- 常用标签:
redis:6.2
redis:latest
4. Web 服务器基础镜像
这些镜像预装了 Web 服务器,适合快速部署 Web 应用。
4.1 Nginx
- 镜像名:
nginx
- 特点:预装了 Nginx Web 服务器。
- 常用标签:
nginx:1.21
nginx:latest
4.2 Apache HTTP Server
- 镜像名:
httpd
- 特点:预装了 Apache HTTP 服务器。
- 常用标签:
httpd:2.4
httpd:latest
5. 特殊用途基础镜像
这些镜像针对特定场景进行了优化。
5.1 Scratch
- 镜像名:
scratch
- 特点:空镜像,适合构建完全静态的二进制文件。
- 示例:
FROM scratch COPY my-app / CMD ["/my-app"]
5.2 BusyBox
- 镜像名:
busybox
- 特点:非常轻量,适合嵌入式或资源受限的环境。
- 常用标签:
busybox:latest
5.2 Distroless(Google 维护)
- 镜像名:
gcr.io/distroless/base
、gcr.io/distroless/nodejs18
。 - 特点:仅包含应用和运行时,无 Shell、包管理器,提升安全性。
- 适用场景:生产环境,减少攻击面。
6. 如何选择基础镜像?
- 镜像大小:如果对镜像大小敏感,可以选择
alpine
或slim
版本。 - 安全性:选择官方维护的镜像,并定期更新。
- 功能需求:如果需要特定语言或工具,选择对应的运行时镜像。
7. 示例:使用 Alpine 作为基础镜像
以下是一个使用 alpine
作为基础镜像的 Dockerfile 示例:
# 使用 Alpine 作为基础镜像
FROM alpine:3.14
# 安装 Python 和 pip
RUN apk add --no-cache python3 py3-pip
# 设置工作目录
WORKDIR /app
# 复制应用代码
COPY . .
# 安装依赖
RUN pip3 install -r requirements.txt
# 暴露端口
EXPOSE 5000
# 运行应用
CMD ["python3", "app.py"]
Comments | NOTHING