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
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 应用容器化
FROM node:16-alpine
ENV NODE_ENV=production ENV PORT=3000
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
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)
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
|
网络模式
docker run --network=bridge nginx
docker run --network=host nginx
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
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/*
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"]
|
安全配置
用户权限
FROM node:16-alpine
RUN addgroup -g 1001 -S nodejs RUN adduser -S nodejs -u 1001
USER nodejs
RUN adduser -D -u 1000 appuser USER 1000
|
安全扫描
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
|
最佳实践
- 使用官方镜像作为基础镜像
- 保持镜像简单,每个容器运行一个应用
- 使用 .dockerignore 减少构建上下文
- 定期更新基础镜像获取安全补丁
- 监控容器资源使用
- 使用多阶段构建减少镜像大小
[!tip]
- 使用 Alpine Linux 基础镜像可以显著减小镜像大小
- 合理使用数据卷和绑定挂载管理数据持久化
- 定期清理未使用的镜像和容器释放磁盘空间
参考资料