作为一个后端老兵,以前每次接手新项目,最头疼的就是“环境不一致”问题。“在我的电脑上明明跑得好好的啊!”这句话简直是开发和运维之间永恒的导火索。直到我全面拥抱了 Docker。

今天,我将通过一个典型的 Node.js 项目,分享我在 Docker 容器化部署中总结的最佳实践。不仅能大幅减小镜像体积,还能提升安全性。

1. 告别臃肿,拥抱多阶段构建 (Multi-stage Builds)

很多新手写 Dockerfile,喜欢把源码、编译工具、测试依赖一股脑全塞进去。结果一个简单的 Web 服务,镜像体积高达 1GB 以上。这在生产环境是不可接受的。

正确的做法是使用多阶段构建。看下面这段我常用的基础配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 阶段一:构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 阶段二:生产阶段
FROM node:18-alpine
WORKDIR /app
# 仅拷贝编译后的产物和生产依赖
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/main.js"]

[在这里插入一张 Docker 鲸鱼 Logo 或多阶段构建架构图]

2. 为什么推荐 Alpine 版本?

在上面的代码中,你会发现我使用了 node:18-alpine 而不是普通的 node:18。Alpine Linux 是一个极其轻量级的发行版,基础镜像只有不到 5MB!这不仅意味着拉取速度更快,更重要的是大大减少了潜在的安全漏洞攻击面。

3. 配置 .dockerignore

.gitignore 一样,千万不要忘记写 .dockerignore。把你本地的 node_modules.git、日志文件等统统排除在外。这能极大加快 Docker daemon 的构建上下文传输速度。

总结

Docker 化不是写个 FROMRUN 就完事了。精简镜像、关注安全、分离构建环境和运行环境,才是运维老手该有的素质。下次我们再聊聊配合 docker-compose 的进阶玩法。