𝑻𝒆𝒏𝑪𝒍𝒂𝒘正在头脑风暴···
𝑻𝒆𝒏𝑲𝒊𝑺𝒆𝒀𝒂の𝑨𝒈𝒆𝒏𝒕助手
𝑻𝒆𝒏-𝒇𝒍𝒂𝒔𝒉

Docker 容器化入门指南

Docker 是一个开源的容器化平台,它让应用的打包、分发和运行变得简单高效。

什么是 Docker?

Docker 使用容器技术,将应用及其依赖打包到一个轻量、可移植的容器中,确保应用在任何环境中都能一致运行。

容器 vs 虚拟机

特性Docker 容器虚拟机
启动速度秒级分钟级
资源占用MB 级GB 级
性能接近原生有性能损耗
隔离性进程级系统级

Docker 基础概念

镜像 (Image)

镜像是容器的模板,包含了运行应用所需的所有文件和配置。

# 拉取镜像
docker pull ubuntu:20.04

# 查看本地镜像
docker images

# 删除镜像
docker rmi ubuntu:20.04

容器 (Container)

容器是镜像的运行实例。

# 运行容器
docker run -d --name my-ubuntu ubuntu:20.04

# 查看运行中的容器
docker ps

# 查看所有容器
docker ps -a

# 停止容器
docker stop my-ubuntu

# 启动容器
docker start my-ubuntu

# 删除容器
docker rm my-ubuntu

Dockerfile

Dockerfile 是用来构建镜像的文本文件。

# 基础镜像
FROM node:16-alpine

# 设置工作目录
WORKDIR /app

# 复制 package.json
COPY package*.json ./

# 安装依赖
RUN npm install

# 复制源代码
COPY . .

# 暴露端口
EXPOSE 3000

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

常用命令

镜像管理

# 搜索镜像
docker search nginx

# 拉取镜像
docker pull nginx:latest

# 查看镜像详情
docker inspect nginx:latest

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

# 标记镜像
docker tag my-app:v1.0 username/my-app:v1.0

# 推送镜像
docker push username/my-app:v1.0

容器操作

# 交互式运行
docker run -it --name my-container ubuntu /bin/bash

# 后台运行
docker run -d --name my-nginx -p 8080:80 nginx

# 挂载卷
docker run -d --name my-volume-container \
-v /host/path:/container/path \
nginx

# 端口映射
docker run -d -p 8080:80 -p 8443:443 nginx

# 环境变量
docker run -d --name my-app \
-e NODE_ENV=production \
-e PORT=3000 \
my-app

# 进入运行中的容器
docker exec -it my-container /bin/bash

# 查看容器日志
docker logs my-container
docker logs -f my-container # 实时日志

# 复制文件
docker cp local.txt my-container:/container/path/
docker cp my-container:/container/path/remote.txt .

实战示例

Node.js 应用容器化

# Dockerfile
FROM node:16-alpine

# 设置环境变量
ENV NODE_ENV=production
ENV PORT=3000

# 创建应用目录
WORKDIR /app

# 复制 package 文件
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production

# 复制应用代码
COPY . .

# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
USER nextjs

# 暴露端口
EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/ || exit 1

# 启动应用
CMD ["npm", "start"]
# 构建镜像
docker build -t my-node-app .

# 运行容器
docker run -d \
--name my-node-container \
-p 3000:3000 \
-e NODE_ENV=production \
my-node-app

多容器应用 (Docker Compose)

# docker-compose.yml
version: '3.8'

services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=db
depends_on:
- db
volumes:
- ./logs:/app/logs

db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"

redis:
image: redis:6-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data

volumes:
postgres_data:
redis_data:
# 启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs web

# 停止服务
docker-compose down

# 重新构建并启动
docker-compose up --build

网络配置

默认网络

# 查看网络
docker network ls

# 查看网络详情
docker network inspect bridge

# 创建自定义网络
docker network create my-network

# 连接容器到网络
docker network connect my-network my-container

# 断开网络连接
docker network disconnect my-network my-container

网络模式

# bridge 模式(默认)
docker run --network=bridge nginx

# host 模式
docker run --network=host nginx

# none 模式
docker run --network=none nginx

# 容器模式
docker run --network=container:other-container nginx

数据管理

数据卷

# 创建数据卷
docker volume create my-volume

# 查看数据卷
docker volume ls

# 使用数据卷
docker run -d -v my-volume:/data nginx

# 删除数据卷
docker volume rm my-volume

绑定挂载

# 挂载主机目录
docker run -d \
-v /host/path:/container/path \
nginx

# 只读挂载
docker run -d \
-v /host/path:/container/path:ro \
nginx

优化实践

镜像优化

# 使用更小的基础镜像
FROM node:16-alpine # 而不是 node:16

# 合并 RUN 指令
RUN apk add --no-cache curl \
&& npm install -g http-server

# 清理缓存
RUN apt-get update \
&& apt-get install -y package \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# 使用 .dockerignore
# .dockerignore 文件
node_modules
npm-debug.log
.git
.gitignore
README.md

多阶段构建

# 构建阶段
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 生产阶段
FROM node:16-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]

安全配置

用户权限

# 避免使用 root 用户
FROM node:16-alpine

# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001

USER nodejs

# 或者使用特定用户 ID
RUN adduser -D -u 1000 appuser
USER 1000

安全扫描

# 安装 Docker 安全扫描工具
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy:latest image my-app

# 检查镜像漏洞
docker scan my-app

监控和日志

健康检查

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1

日志管理

# 配置日志驱动
docker run -d \
--log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx

# 查看日志配置
docker inspect my-container | grep LogConfig

最佳实践

  1. 使用官方镜像作为基础镜像
  2. 保持镜像简单,每个容器运行一个应用
  3. 使用 .dockerignore 减少构建上下文
  4. 定期更新基础镜像获取安全补丁
  5. 监控容器资源使用
  6. 使用多阶段构建减少镜像大小

[!tip]

  • 使用 Alpine Linux 基础镜像可以显著减小镜像大小
  • 合理使用数据卷和绑定挂载管理数据持久化
  • 定期清理未使用的镜像和容器释放磁盘空间

参考资料