一、Docker 基础概念
- 镜像(Image):应用及其依赖环境的打包(如 mysql:latest),可 push/pull 到 Docker Hub。
- 容器(Container):镜像的运行实例,相互隔离(独立文件系统、网络、端口)。
- 数据卷(Volume):将宿主机目录挂载到容器内,用于持久化数据(如 MySQL 的 /var/lib/mysql)。
常用命令:
powershell
docker run -d \
--name mysql-container2 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=admin \
-v /Users/wuying/mysql:/var/lib/mysql \
mysql:latest
二、Dockerfile 与镜像构建
- 基础 Dockerfile
powershell
# 指定基础镜像
FROM node:24.15-alpine
# 设置容器内工作目录
WORKDIR /app
# 复制 package.json 利用缓存加速
COPY package*.json ./
# 安装依赖
RUN npm install
# 复制项目所有代码到容器内
COPY . .
# 构建项目
RUN npm run build
# 暴露端口
EXPOSE 3000
# 容器启动时执行的命令
CMD ["node", "dist/main.js"]
- 多阶段构建(减小体积)
优点:最终镜像体积小,不包含源码、开发依赖等。
powershell
# 构建阶段(含 devDependencies)
FROM node:24.15-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 运行阶段(仅生产依赖 + 编译结果)
FROM node:24.15-alpine
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/main.js"]
三、Docker Compose:编排多个容器
开发环境(docker-compose.dev.yml)
- 同时启动 MySQL、Milvus 及其依赖(etcd、minio)。
- 通过 volume 挂载持久化数据。
- 环境变量灵活控制目录(如 ${DOCKER_VOLUME_DIRECTORY:-.})。
powershell
version: '3.8'
services:
# MySQL
mysql:
image: mysql:latest
container_name: mysql-dev
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: book
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci # 设置默认字符集
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/mysql:/var/lib/mysql
restart: always
# Milvus
etcd:
container_name: milvus-etcd-dev
image: quay.io/coreos/etcd:v3.5.25
environment:
- ETCD_AUTO_COMPACTION_MODE=revision # 压缩模式:基于修订版本
- ETCD_AUTO_COMPACTION_RETENTION=1000 # 保留最近1000个修订版本
- ETCD_QUOTA_BACKEND_BYTES=4294967296 # 数据库大小限制4GB
- ETCD_SNAPSHOT_COUNT=50000 # 每5万次修改创建快照
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd # 持久化目录
command: etcd -advertise-client-urls=http://etcd:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd # 启动命令
test: ["CMD", "etcdtrl", "endpoint", "health"]
interval: 30s # 每30秒检查一次
timeout: 20s # 单次检查超时20秒
retries: 3 # 连续失败3次判定为不健康
minio:
container_name: milvus-minio-dev
image: minio/minio:RELEASE.2024-12-18T13-15-44Z
environment:
MINIO_ACCESS_KEY: minioadmin # 控制台用户名
MINIO_SECRET_KEY: minioadmin # 控制台密码
ports:
- "9001:9001" # 控制台UI端口
- "9000:9000" # API端口(Milvus连接用)
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data # 持久化数据
command: minio server /minio_data --console-address ":9001" # 启动命令
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
standalone:
container_name: milvus-standalone-dev
image: milvusdb/milvus:v2.6.11
command: ["milvus", "run", "standalone"] # 单机模式
security_opt:
- seccomp:unconfined # 允许所有系统调用(性能优先)
environment:
MINIO_REGION: us-east-1 # MinIO 存储区域(S3兼容)
ETCD_ENDPOINTS: etcd:2379 #「元数据」存储地址
MINIO_ADDRESS: minio:9000 #「对象」存储地址
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus # 持久化数据
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
interval: 30s
start_period: 90s # 启动等待90秒后再检查
timeout: 20s
retries: 3
ports:
- "19530:19530" # gRPC客户端端口
- "9091:9091" # 健康检查端口
depends_on:
- "etcd"
- "minio"
networks:
default:
name: common-network
生产环境(docker-compose.prod.yml)
powershell
services:
mysql-prod:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: book
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/mysql-prod:/var/lib/mysql
restart: always
nest-app:
build:
context: .
dockerfile: Dockerfile # 使用当前目录的 Dockerfile
ports:
- "3000:3000"
depends_on:
- mysql-prod
restart: always
- 业务服务通过容器名互相访问(如 mysql-prod)。
- 使用 depends_on 控制启动顺序。
- --build 确保每次启动前重新构建镜像。
四、开发与部署流程
- 本地开发:npm run docker:up → 一键启动 MySQL + Milvus,代码直连 localhost。
生产部署:npm run docker:prod:up -- --build → 构建并启动 Nest 镜像 + MySQL
容器,互联使用容器名。
核心思想:开发时用 Docker Compose 跑基础设施,生产时也将应用容器化,统一编排,环境一致性高。
yaml
"docker:up": "DOCKER_VOLUME_DIRECTORY=/Users/wuying/ docker compose -f docker-compose.dev.yml up -d",
"docker:down": "docker compose -f docker-compose.dev.yml down",
"docker:prod:up": "docker compose -f docker-compose.prod.yml up -d --build",