Vibe Tutorial
云服务器运维与项目部署

13.5 Docker容器详解

Tip

在他的电脑上能跑,在我的电脑上跑不起来 (依赖冲突/环境不同)。Docker 就是为了解决这个问题。它把代码和运行环境(OS、库、配置)打包在一起,像一个标转化的集装箱。


1. 为什么要学这个?

你用 Python 3.10 写了个应用,服务器上是 Python 2.7。 你想安装 Postgres 14,但服务器上已经跑了 Postgres 12,端口冲突。 Environment Hell (环境地狱) 让你痛不欲生。

Docker 让你可以对服务器说:“我不管你装了什么,我自带了环境。”


2. 核心概念:Container (容器)

2.1 隐喻:饭盒 vs 餐厅

  • 虚拟机 (VM):是一整间餐厅。有独立的厨房、桌椅、服务员。重,启动慢,费资源。
  • 容器 (Docker):是一个外卖饭盒。自带餐具和饭菜。你只需要一个桌子(Linux 内核)就能吃。轻,毫秒级启动。

2.2 核心术语

  • Image (镜像): 饭菜的配方 (只读)。比如 node:18
  • Container (容器): 照着配方做出来的实物 (可读写)。你可以启动 10 个 node:18 的容器。
  • Dockerfile: 菜谱。告诉 Docker 怎么把代码打包成镜像。

3. 解决方案 (HOW)

3.1 Dockerfile 写法

在项目根目录新建 Dockerfile:

# 1. 选底料 (基础镜像)
FROM node:18-alpine

# 2. 设定工作目录
WORKDIR /app

# 3. 复制依赖清单并安装 (利用缓存层)
COPY package.json .
RUN npm install

# 4. 复制源码
COPY . .

# 5. 对外暴露端口
EXPOSE 3000

# 6. 启动命令
CMD ["npm", "start"]

3.2 常用命令

# 构建镜像
docker build -t my-app .

# 运行容器 (映射端口 3000->3000)
docker run -d -p 3000:3000 --name app-instance my-app

# 查看日志
docker logs -f app-instance

# 杀掉容器
docker rm -f app-instance

3.3 容器化流程图

graph TD
    Code["源码 + Dockerfile"] -->|"Step 1: Build"| Image["Docker Image (镜像)"]
    
    Image --"Step 2: Push"--> Registry["Docker Hub (仓库)"]
    
    Registry --"Step 3: Pull"--> Server["生产服务器"]
    
    Server --"Step 4: Run"--> Container["Running Container (容器)"]
    
    style Image fill:#fff9c4,stroke:#fbc02d
    style Container fill:#c8e6c9,stroke:#2e7d32

4. 避坑指南

❌ 不要这样做 ✅ 应该这样做 为什么
使用 Latest 锁定版本 FROM node:latest 今天是 v20,明天可能就是 v21。生产环境必须锁定具体版本 node:18-alpine
拷贝 node_modules 在 Docker 里安装 也就是不要把本地的 node_modules 文件夹 COPY 进去。本地是 macOS 二进制,Docker 是 Linux,不兼容。应该让 Docker 自己 npm install
存数据在容器里 挂载 Volume 容器重启后文件就没了。数据库文件、用户上传的图片,必须挂载 Volume 到宿主机。

5. 真实案例

Story

2018年,消失的数据

很多新手在 Docker 里运行 MySQL 数据库。运行了一年,想升级一下 MySQL 版本。 于是执行 docker rm mysql 然后 docker run mysql:new。 启动后发现数据库是空的。所有用户数据都没了。 因为他忘记挂载数据卷 (-v /host/data:/var/lib/mysql),数据是存在容器内部的文件系统里的,随容器销毁而灰飞烟灭。

Vibe 心法:容器是易碎的“隔离间”,永远假设它下一秒就会重启。坚持无状态 (Stateless) 的设计原则,将持久化数据锚定在外部数据卷(Volume)中,才能确保应用在动态漂移的环境中获得永恒的生命力。


6. 本章小结

  1. 一致性:Build once, Run anywhere。
  2. Dockerfile:是项目的标准说明书,比 Readme 更管用。
  3. Volume:是数据的救生圈,千万别忘了挂载。