概述

Docker是一个开源的容器化平台,能够将应用程序及其依赖项打包到轻量级、可移植的容器中,确保应用在任何环境中都能一致运行。

Docker 核心概念

镜像(Image)

  • 只读的模板,用于创建容器
  • 包含运行应用所需的所有依赖
  • 可以从Docker Hub拉取或自己构建

容器(Container)

  • 镜像的运行实例
  • 轻量级、可移植、隔离的运行环境
  • 可以启动、停止、删除

仓库(Repository)

  • 存储镜像的地方
  • Docker Hub是最大的公共仓库
  • 可以创建私有仓库

Docker 基础命令

镜像管理

# 搜索镜像
docker search nginx

# 拉取镜像
docker pull nginx:latest
docker pull nginx:1.20

# 查看本地镜像
docker images
docker image ls

# 删除镜像
docker rmi nginx:latest
docker image rm nginx:latest

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

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

# 查看镜像历史
docker history nginx:latest

# 标记镜像
docker tag nginx:latest my-nginx:1.0

容器管理

# 运行容器
docker run -d --name mynginx -p 8080:80 nginx:latest

# 交互式运行容器
docker run -it --name myubuntu ubuntu:latest /bin/bash

# 查看运行中的容器
docker ps
docker container ls

# 查看所有容器(包括停止的)
docker ps -a
docker container ls -a

# 停止容器
docker stop mynginx
docker container stop mynginx

# 启动容器
docker start mynginx
docker container start mynginx

# 重启容器
docker restart mynginx
docker container restart mynginx

# 删除容器
docker rm mynginx
docker container rm mynginx

# 强制删除运行中的容器
docker rm -f mynginx

# 查看容器日志
docker logs mynginx
docker logs -f mynginx  # 实时查看
docker logs --tail 100 mynginx  # 查看最后100行

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

# 查看容器详细信息
docker inspect mynginx

# 查看容器资源使用情况
docker stats
docker stats mynginx

# 复制文件到容器
docker cp ./index.html mynginx:/usr/share/nginx/html/

# 从容器复制文件
docker cp mynginx:/etc/nginx/nginx.conf ./nginx.conf

常用运行参数

# 后台运行
docker run -d nginx

# 端口映射
docker run -p 8080:80 nginx  # 主机8080端口映射到容器80端口
docker run -p 8080:80 -p 8443:443 nginx  # 多端口映射

# 挂载卷
docker run -v /host/path:/container/path nginx
docker run -v $(pwd)/html:/usr/share/nginx/html nginx

# 环境变量
docker run -e NODE_ENV=production node:14
docker run -e DB_HOST=localhost -e DB_PORT=5432 myapp

# 工作目录
docker run -w /app node:14 npm install

# 用户
docker run -u 1000:1000 nginx

# 资源限制
docker run --memory="512m" --cpus="1.0" nginx

# 自动重启
docker run --restart=always nginx
docker run --restart=on-failure:3 nginx  # 最多重启3次

# 网络配置
docker run --network=mynetwork --network-alias=myapp nginx

Dockerfile

基本结构

# 基础镜像
FROM node:16-alpine

# 维护者信息
LABEL maintainer="your-email@example.com"

# 设置工作目录
WORKDIR /app

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

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

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

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

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

# 更改文件所有者
RUN chown -R nextjs:nodejs /app
USER nextjs

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

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

多阶段构建

# 构建阶段
FROM node:16-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
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
COPY --from=builder /app/package.json ./package.json

EXPOSE 3000
CMD ["node", "dist/index.js"]

优化技巧

# 使用.alpine镜像减小体积
FROM node:16-alpine

# 合并RUN指令减少层数
RUN apk add --no-cache curl \
    && npm install -g pm2 \
    && rm -rf /var/cache/apk/*

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

# 多阶段构建
FROM golang:1.19 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

FROM scratch
COPY --from=builder /app/main /
CMD ["/main"]

Docker Compose

基本概念

Docker Compose是用于定义和运行多容器Docker应用程序的工具。通过YAML文件配置应用的服务,然后使用一个命令创建和启动所有服务。

docker-compose.yml 基本结构

version: '3.8'

services:
  # Web服务
  web:
    image: nginx:latest
    container_name: my-web
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
      - ./nginx.conf:/etc/nginx/nginx.conf
    environment:
      - NGINX_HOST=localhost
      - NGINX_PORT=80
    networks:
      - mynetwork
    depends_on:
      - app
    restart: unless-stopped

  # 应用服务
  app:
    build: .
    container_name: my-app
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=database
      - DB_PORT=5432
      - DB_NAME=myapp
      - DB_USER=admin
      - DB_PASSWORD=password
    volumes:
      - ./logs:/app/logs
    networks:
      - mynetwork
    depends_on:
      - database
      - redis
    restart: unless-stopped

  # 数据库服务
  database:
    image: postgres:13
    container_name: my-db
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - mynetwork
    restart: unless-stopped

  # Redis服务
  redis:
    image: redis:6-alpine
    container_name: my-redis
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - mynetwork
    restart: unless-stopped

# 网络定义
networks:
  mynetwork:
    driver: bridge

# 数据卷定义
volumes:
  postgres_data:
  redis_data:

Docker Compose 常用命令

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

# 启动指定服务
docker-compose up web app

# 停止所有服务
docker-compose stop

# 停止并删除容器
docker-compose down
docker-compose down -v  # 同时删除数据卷

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

# 查看服务状态
docker-compose ps

# 查看服务日志
docker-compose logs
docker-compose logs web
docker-compose logs -f web  # 实时查看

# 进入服务容器
docker-compose exec web sh
docker-compose exec app bash

# 重新启动服务
docker-compose restart web
docker-compose restart

# 拉取最新镜像
docker-compose pull

# 扩展服务实例
docker-compose up -d --scale web=3

# 查看资源使用情况
docker-compose top

# 暂停/恢复服务
docker-compose pause
docker-compose unpause

# 删除未使用的资源
docker-compose down --remove-orphans

环境变量配置

# docker-compose.yml
version: '3.8'

services:
  app:
    image: myapp:${APP_VERSION:-latest}
    environment:
      - NODE_ENV=${NODE_ENV:-development}
      - PORT=${PORT:-3000}
      - DB_HOST=${DB_HOST:-database}
      - DB_PORT=${DB_PORT:-5432}
    env_file:
      - .env
      - .env.production
# .env文件
APP_VERSION=1.0.0
NODE_ENV=production
PORT=3000
DB_HOST=database
DB_PORT=5432
DB_NAME=myapp
DB_USER=admin
DB_PASSWORD=secretpassword

生产环境配置

# docker-compose.prod.yml
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/ssl:/etc/nginx/ssl
      - static_files:/var/www/html
    depends_on:
      - app
    restart: always

  app:
    image: myapp:production
    environment:
      - NODE_ENV=production
    volumes:
      - ./logs:/app/logs
    depends_on:
      - database
      - redis
    restart: always
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

  database:
    image: postgres:13
    environment:
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./backups:/backups
    restart: always

volumes:
  postgres_data:
  static_files:

网络管理

创建网络

# 创建桥接网络
docker network create mynetwork

# 创建自定义网络
docker network create --driver bridge --subnet=192.168.0.0/16 mynetwork

# 查看网络
docker network ls
docker network inspect mynetwork

# 连接容器到网络
docker network connect mynetwork mycontainer

# 断开容器连接
docker network disconnect mynetwork mycontainer

# 删除网络
docker network rm mynetwork

数据卷管理

创建和管理数据卷

# 创建数据卷
docker volume create myvolume

# 查看数据卷
docker volume ls
docker volume inspect myvolume

# 删除数据卷
docker volume rm myvolume

# 清理未使用的数据卷
docker volume prune

实用技巧

性能优化

# 使用多阶段构建减小镜像大小
# 使用.alpine基础镜像
# 合并RUN指令减少层数
# 使用.dockerignore排除不需要的文件
# 定期清理无用资源
docker system prune -a

安全最佳实践

# 使用非root用户运行
# 不要在镜像中硬编码密码
# 使用官方基础镜像
# 定期更新基础镜像
# 扫描镜像漏洞
docker scan myimage

调试技巧

# 查看容器详细信息
docker inspect container_name

# 查看容器内进程
docker exec container_name ps aux

# 实时查看日志
docker logs -f container_name

# 进入容器调试
docker exec -it container_name /bin/bash

# 查看资源使用
docker stats container_name

常见问题解决

容器无法启动

# 查看详细错误信息
docker logs container_name

# 检查端口冲突
netstat -tulpn | grep :8080

# 检查资源限制
docker stats

网络连接问题

# 检查网络配置
docker network ls
docker network inspect network_name

# 测试容器间连接
docker exec container1 ping container2

数据持久化问题

# 检查数据卷
docker volume ls
docker volume inspect volume_name

# 备份数据卷
docker run --rm -v volume_name:/data -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz /data

总结

Docker和Docker Compose为现代应用部署提供了强大的容器化解决方案。掌握这些工具可以显著简化开发、测试和部署流程,提高应用的可移植性和可扩展性。在实际使用中,建议根据具体需求选择合适的配置和优化策略。