DevOps

Docker 完全教程

容器化技术入门到实战,掌握现代应用部署

Docker 完全教程

Docker 是一个开源的容器化平台,让你可以将应用及其依赖打包到一个轻量级、可移植的容器中,在任何环境中一致运行。

为什么选择 Docker?

  • 一致性:开发、测试、生产环境完全一致
  • 轻量级:比虚拟机更快、更小
  • 可移植:一次构建,到处运行
  • 隔离性:应用之间互不干扰
  • 版本控制:镜像可以像代码一样管理

核心概念

镜像(Image)

镜像是一个只读的模板,包含运行应用所需的一切:代码、运行时、库、环境变量、配置文件。

容器(Container)

容器是镜像的运行实例,是一个独立的、可执行的软件包。

Dockerfile

Dockerfile 是一个文本文件,包含构建镜像的指令。

Docker Hub

Docker Hub 是官方的镜像仓库,类似于 GitHub。

安装 Docker

macOS

# 使用 Homebrew
brew install --cask docker

# 或下载 Docker Desktop
# https://www.docker.com/products/docker-desktop

Linux (Ubuntu)

# 更新包索引
sudo apt-get update

# 安装依赖
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 设置稳定版仓库
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 验证安装
sudo docker run hello-world

Windows

下载并安装 Docker Desktop for Windows: https://www.docker.com/products/docker-desktop

基础命令

镜像操作

# 搜索镜像
docker search nginx

# 拉取镜像
docker pull nginx
docker pull nginx:1.21  # 指定版本

# 列出本地镜像
docker images

# 删除镜像
docker rmi nginx
docker rmi $(docker images -q)  # 删除所有镜像

# 构建镜像
docker build -t myapp:1.0 .

# 标记镜像
docker tag myapp:1.0 username/myapp:1.0

# 推送镜像
docker push username/myapp:1.0

容器操作

# 运行容器
docker run nginx
docker run -d nginx  # 后台运行
docker run -d -p 8080:80 nginx  # 端口映射
docker run -d -p 8080:80 --name my-nginx nginx  # 指定名称

# 列出容器
docker ps  # 运行中的容器
docker ps -a  # 所有容器

# 停止容器
docker stop my-nginx
docker stop $(docker ps -q)  # 停止所有容器

# 启动容器
docker start my-nginx

# 重启容器
docker restart my-nginx

# 删除容器
docker rm my-nginx
docker rm $(docker ps -aq)  # 删除所有容器

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

# 进入容器
docker exec -it my-nginx bash

# 查看容器详情
docker inspect my-nginx

# 查看容器资源使用
docker stats

Dockerfile

基本结构

# 基础镜像
FROM node:18-alpine

# 设置工作目录
WORKDIR /app

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

# 安装依赖
RUN npm install

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

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

常用指令

# FROM:指定基础镜像
FROM ubuntu:22.04

# LABEL:添加元数据
LABEL maintainer="your@email.com"
LABEL version="1.0"

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

# WORKDIR:设置工作目录
WORKDIR /app

# COPY:复制文件
COPY src/ /app/src/
COPY package.json .

# ADD:复制文件(支持 URL 和自动解压)
ADD https://example.com/file.tar.gz /tmp/
ADD archive.tar.gz /app/

# RUN:执行命令(构建时)
RUN apt-get update && apt-get install -y curl
RUN npm install

# CMD:容器启动命令(可被覆盖)
CMD ["node", "server.js"]

# ENTRYPOINT:容器入口点(不可被覆盖)
ENTRYPOINT ["docker-entrypoint.sh"]

# EXPOSE:声明端口
EXPOSE 3000 8080

# VOLUME:创建挂载点
VOLUME ["/data"]

# USER:指定运行用户
USER node

# ARG:构建参数
ARG VERSION=1.0
RUN echo "Building version $VERSION"

多阶段构建

减小镜像大小,提高安全性。

# 构建阶段
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
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
EXPOSE 3000
CMD ["node", "dist/server.js"]

实战示例

Node.js 应用

Dockerfile

FROM node:18-alpine

WORKDIR /app

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

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

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 非 root 用户运行
USER node

# 启动应用
CMD ["node", "server.js"]

构建和运行

# 构建镜像
docker build -t my-node-app .

# 运行容器
docker run -d -p 3000:3000 --name node-app my-node-app

# 查看日志
docker logs -f node-app

Go 应用

# 构建阶段
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server .

# 运行阶段
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]

Python 应用

FROM python:3.11-slim

WORKDIR /app

# 安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用
COPY . .

EXPOSE 8000

CMD ["python", "app.py"]

Docker Compose

Docker Compose 用于定义和运行多容器应用。

安装

# macOS/Windows:Docker Desktop 已包含
# Linux
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

docker-compose.yml

version: '3.8'

services:
  # Web 应用
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:password@db:5432/mydb
    depends_on:
      - db
      - redis
    volumes:
      - ./logs:/app/logs
    networks:
      - app-network

  # 数据库
  db:
    image: postgres:15
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=mydb
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - app-network

  # Redis
  redis:
    image: redis:7-alpine
    networks:
      - app-network

  # Nginx
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - web
    networks:
      - app-network

volumes:
  postgres-data:

networks:
  app-network:
    driver: bridge

Compose 命令

# 启动服务
docker-compose up
docker-compose up -d  # 后台运行

# 停止服务
docker-compose down
docker-compose down -v  # 同时删除 volumes

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs
docker-compose logs -f web  # 查看特定服务

# 执行命令
docker-compose exec web bash

# 重启服务
docker-compose restart

# 构建镜像
docker-compose build
docker-compose build --no-cache  # 不使用缓存

数据管理

Volume(卷)

# 创建 volume
docker volume create my-data

# 列出 volumes
docker volume ls

# 查看 volume 详情
docker volume inspect my-data

# 使用 volume
docker run -d -v my-data:/app/data nginx

# 删除 volume
docker volume rm my-data
docker volume prune  # 删除未使用的 volumes

Bind Mount(绑定挂载)

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

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

网络

网络类型

  • bridge:默认网络,容器间可通信
  • host:使用主机网络
  • none:无网络
  • overlay:跨主机通信(Swarm)

网络命令

# 创建网络
docker network create my-network

# 列出网络
docker network ls

# 查看网络详情
docker network inspect my-network

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

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

# 删除网络
docker network rm my-network

容器间通信

# 创建网络
docker network create app-net

# 运行容器
docker run -d --name db --network app-net postgres
docker run -d --name web --network app-net -p 3000:3000 my-app

# web 容器可以通过 'db' 访问数据库
# 例如:postgresql://postgres:password@db:5432/mydb

最佳实践

1. 使用 .dockerignore

node_modules
npm-debug.log
.git
.env
*.md
.DS_Store

2. 最小化层数

# 不好
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git

# 好
RUN apt-get update && \
    apt-get install -y curl git && \
    rm -rf /var/lib/apt/lists/*

3. 利用缓存

# 先复制依赖文件
COPY package*.json ./
RUN npm install

# 再复制代码(代码变化不会重新安装依赖)
COPY . .

4. 使用小镜像

# 不好
FROM node:18  # ~900MB

# 好
FROM node:18-alpine  # ~170MB

5. 非 root 用户

# 创建用户
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

# 切换用户
USER nodejs

6. 健康检查

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

7. 使用多阶段构建

FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm run build

FROM node:18-alpine
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/server.js"]

常见问题

清理资源

# 删除停止的容器
docker container prune

# 删除未使用的镜像
docker image prune

# 删除未使用的 volumes
docker volume prune

# 删除未使用的网络
docker network prune

# 清理所有未使用的资源
docker system prune -a

查看资源使用

# 查看磁盘使用
docker system df

# 查看容器资源使用
docker stats

调试容器

# 查看容器日志
docker logs -f container-name

# 进入容器
docker exec -it container-name sh

# 查看容器进程
docker top container-name

# 查看容器变化
docker diff container-name

生产环境部署

使用 Docker Swarm

# 初始化 Swarm
docker swarm init

# 部署服务
docker stack deploy -c docker-compose.yml myapp

# 查看服务
docker service ls

# 扩展服务
docker service scale myapp_web=3

使用 Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        ports:
        - containerPort: 3000

安全建议

  1. 使用官方镜像
  2. 定期更新镜像
  3. 扫描漏洞docker scan myapp:1.0
  4. 最小权限原则
  5. 不在镜像中存储敏感信息
  6. 使用 secrets 管理密码

常用工具

  • Portainer:Docker 可视化管理
  • Watchtower:自动更新容器
  • Traefik:反向代理和负载均衡
  • Docker Bench:安全检查工具

总结

Docker 是现代应用部署的标准工具。掌握 Docker 可以让你:

  • 简化开发环境配置
  • 确保环境一致性
  • 快速部署和扩展应用
  • 提高资源利用率

开始使用 Docker,让你的应用部署更加简单高效!

参考资源