Dockerfile 是 Docker 的核心功能之一,通过它我们能够自动化地构建自定义镜像。在这一章,我们将深入探讨 Dockerfile 的基本语法和使用方法,并通过实际案例展示如何构建自定义镜像。
1. Dockerfile 基础
什么是 Dockerfile
Dockerfile 是一个文本文件,其中包含了一系列的指令,这些指令定义了一个 Docker 镜像的构建过程。每个指令对应一个镜像层,最终形成一个可以执行的 Docker 镜像。
Dockerfile 的基本语法
Dockerfile 的基本语法相对简单,但它具有很强的表达能力。下面是一些常用的指令:
FROM:指定基础镜像RUN:执行命令COPY或ADD:复制文件到镜像中CMD或ENTRYPOINT:指定容器启动时的命令EXPOSE:暴露端口ENV:设置环境变量WORKDIR:设置工作目录
编写第一个 Dockerfile
我们将编写一个简单的 Dockerfile 来构建一个包含 Node.js 环境的镜像。
# 使用官方的 Node.js 镜像作为基础镜像FROM node:14# 创建并设置工作目录WORKDIR /app# 复制 package.json 和 package-lock.jsonCOPY package*.json ./# 安装依赖RUN npm install# 复制应用代码COPY . .# 暴露应用端口EXPOSE 8080# 启动应用CMD ["node", "app.js"]
以上 Dockerfile 文件定义了一个以 Node.js 镜像为基础的自定义镜像,它将应用代码复制到镜像中并安装所需的依赖,最后设置启动命令。
2. 构建自定义镜像
使用 docker build 构建镜像
使用 docker build 命令可以根据 Dockerfile 构建镜像。以下是其基本用法:
docker build -t my-node-app .
参数解释:
-t my-node-app:为镜像指定标签my-node-app.:指定 Dockerfile 的路径(当前目录)
多阶段构建
多阶段构建是一种优化镜像大小的方法,通过在构建过程中使用多个 FROM 指令,可以有效减少最终镜像的体积。
# 第一阶段:构建阶段FROM node:14 AS builderWORKDIR /appCOPY package*.json ./RUN npm installCOPY . .RUN npm run build# 第二阶段:生产阶段FROM node:14WORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesEXPOSE 8080CMD ["node", "dist/app.js"]
上述 Dockerfile 分为两个阶段:
- 构建阶段:编译代码,生成构建产物
- 生产阶段:仅复制构建产物,大大减小了镜像体积
镜像优化与缓存机制
Docker 在构建镜像时使用分层缓存机制,可以加速构建过程。为了充分利用缓存机制,我们应尽量将不经常变化的指令放在 Dockerfile 的前面。
3. Dockerfile 实践
使用 Dockerfile 构建 Web 应用镜像
我们将构建一个简单的 Node.js Web 应用镜像。
- 创建项目目录并初始化 Node.js 项目:
mkdir my-web-appcd my-web-appnpm init -y
- 安装 Express:
npm install express
- 创建
app.js文件:
const express = require("express");const app = express();const port = 8080;app.get("/", (req, res) => {res.send("Hello, Docker!");});app.listen(port, () => {console.log(`App running at http://localhost:${port}`);});
- 编写 Dockerfile:
FROM node:14WORKDIR /appCOPY package*.json ./RUN npm installCOPY . .EXPOSE 8080CMD ["node", "app.js"]
- 构建镜像并运行容器:
docker build -t my-web-app .docker run -p 8080:8080 my-web-app
访问 http://localhost:8080,你将看到 “Hello, Docker!”。
使用 Dockerfile 构建数据库镜像
我们将使用官方的 MySQL 镜像并进行一些自定义配置。
- 创建 Dockerfile:
FROM mysql:5.7ENV MYSQL_ROOT_PASSWORD=my-secret-pwENV MYSQL_DATABASE=mydatabaseCOPY ./init.sql /docker-entrypoint-initdb.d/
- 创建
init.sql文件,以初始化数据库:
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL);
- 构建镜像并运行容器:
docker build -t my-mysql .docker run -d -p 3306:3306 --name my-mysql-container my-mysql
通过这些示例,你可以学会如何使用 Dockerfile 构建和自定义各种类型的应用镜像。
