Docker 容器化入门指南
概述
Docker 是一个开源的容器化平台,让开发者可以将应用及其依赖打包成轻量级的容器。本文从镜像构建到容器编排,全面介绍 Docker 技术,为微服务部署奠定基础。
核心概念
容器与虚拟机
| 特性 | 容器 | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | 轻量(MB) | 重量(GB) |
| 隔离性 | 进程级 | 系统级 |
| 性能 | 接近原生 | 有损耗 |
Docker 架构
┌─────────────────┐
│ Client │ Docker CLI
└────────┬────────┘
│
▼
┌─────────────────┐
│ Registry │ Docker Hub
└─────────────────┘
▲
│
┌────────▼────────┐
│ Daemon │ Docker Server
└────────┬────────┘
│
▼
┌─────────────────┐
│ Containers │ 运行时
└─────────────────┘核心组件
镜像 (Image)
- 只读模板
- 包含应用和依赖
- 用于创建容器
容器 (Container)
- 镜像的运行实例
- 可读写层
- 相互隔离
仓库 (Registry)
- 存储和分发镜像
- Docker Hub 是公共仓库
- 可搭建私有仓库
基础命令
镜像操作
bash
# 搜索镜像
docker search ubuntu
# 拉取镜像
docker pull ubuntu:20.04
# 查看本地镜像
docker images
# 删除镜像
docker rmi ubuntu:20.04
# 构建镜像
docker build -t myapp:1.0 .容器操作
bash
# 创建并启动容器
docker run -it ubuntu /bin/bash
# 后台运行容器
docker run -d --name myapp nginx
# 列出运行中的容器
docker ps
# 列出所有容器
docker ps -a
# 停止容器
docker stop myapp
# 启动已停止的容器
docker start myapp
# 删除容器
docker rm myapp
# 进入容器
docker exec -it myapp /bin/bashDockerfile 最佳实践
基本结构
dockerfile
# 基础镜像
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["node", "server.js"]多阶段构建
dockerfile
# 构建阶段
FROM node:18 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 --from=builder /app/package*.json ./
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/server.js"].dockerignore
gitignore
node_modules
npm-debug.log
.git
.gitignore
.env*
*.md
dist数据管理
数据卷 (Volumes)
bash
# 创建数据卷
docker volume create mydata
# 挂载数据卷
docker run -d -v mydata:/data nginx
# 查看数据卷
docker volume ls
docker volume inspect mydata绑定挂载
bash
# 挂载本地目录
docker run -v /host/path:/container/path nginx
# 挂载单个文件
docker run -v /host/file:/container/file nginx网络配置
端口映射
bash
# 映射端口
docker run -p 8080:80 nginx
# 映射多个端口
docker run -p 8080:80 -p 443:443 nginx自定义网络
bash
# 创建网络
docker network create mynetwork
# 容器连接到网络
docker run --network mynetwork nginx
# 查看网络
docker network ls
docker network inspect mynetworkDocker Compose
基本配置
yaml
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- db
- redis
db:
image: postgres:14
volumes:
- dbdata:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=secret
redis:
image: redis:alpine
volumes:
dbdata:常用命令
bash
# 启动服务
docker-compose up
# 后台运行
docker-compose up -d
# 停止服务
docker-compose down
# 查看日志
docker-compose logs -f web
# 重新构建
docker-compose up --buildNode.js 应用部署
完整示例
dockerfile
# Dockerfile
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 --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]yaml
# docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/myapp
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- app
db:
image: postgres:14
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=myapp
volumes:
- pgdata:/var/lib/postgresql/data
restart: unless-stopped
redis:
image: redis:alpine
restart: unless-stopped
volumes:
pgdata:镜像优化
减小镜像体积
- 使用 alpine 基础镜像
- 减少层数
- 多阶段构建
- 清理缓存和临时文件
优化示例
dockerfile
# 优化前
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
RUN rm -rf node_modules/.cache
# 优化后
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 --from=builder /app/node_modules ./node_modules
RUN rm -rf /var/cache/apk/*安全最佳实践
dockerfile
# 使用非 root 用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# 只复制必要文件
COPY --from=builder /app/dist ./dist
# 不使用 latest 标签
FROM node:18.17.0
# 扫描漏洞
docker scan myapp:1.0常见问题
容器无法启动
bash
# 查看日志
docker logs <container>
docker logs -f <container>
# 检查配置
docker inspect <container>权限问题
bash
# 修改文件权限
chmod -R 755 ./data
# 在容器中使用相同用户
docker run -u $(id -u):$(id -g) myapp清理资源
bash
# 删除未使用的容器
docker container prune
# 删除未使用的镜像
docker image prune -a
# 删除未使用的卷
docker volume prune
# 清理所有未使用资源
docker system prune总结
Docker 为现代应用部署带来了革命性的变化:
- 一致的运行环境
- 快速部署和扩展
- 资源高效利用
- 简化的CI/CD流程
