Skip to content
AskSoul

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/bash

Dockerfile 最佳实践

基本结构

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 mynetwork

Docker 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 --build

Node.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:

镜像优化

减小镜像体积

  1. 使用 alpine 基础镜像
  2. 减少层数
  3. 多阶段构建
  4. 清理缓存和临时文件

优化示例

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流程