Skip to content

Docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 或 Windows 操作系统的机器上。本教程将帮助你掌握 Docker 的基本概念和使用方法。

Docker 简介

什么是 Docker?

Docker 是一个开源平台,它使用容器技术来简化应用的部署和管理。Docker 容器将软件及其依赖项打包成标准化单元,确保应用程序在任何环境中都能以相同的方式运行。

Docker 的主要组件

  • Docker 引擎:用于构建和运行容器的核心软件
  • Docker 镜像:容器的只读模板,包含运行应用所需的一切
  • Docker 容器:镜像的运行实例,可以启动、停止、移动或删除
  • Docker 注册表:存储和分发 Docker 镜像的仓库,如 Docker Hub
  • Dockerfile:用于自动构建 Docker 镜像的脚本文件

Docker 与虚拟机的区别

特性Docker 容器虚拟机
启动时间秒级分钟级
占用磁盘空间MB 级GB 级
性能接近原生有一定损耗
隔离级别进程级隔离完全隔离
操作系统共享主机内核独立操作系统

安装 Docker

Windows 安装

  1. 下载并安装 Docker Desktop for Windows
  2. 启动 Docker Desktop
  3. 验证安装:打开命令提示符或 PowerShell,运行 docker --version

macOS 安装

  1. 下载并安装 Docker Desktop for Mac
  2. 启动 Docker Desktop
  3. 验证安装:打开终端,运行 docker --version

Linux 安装 (Ubuntu)

bash
# 更新包索引
sudo apt-get update

# 安装依赖
sudo apt-get install \
    apt-transport-https \
    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=amd64 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 引擎
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 验证安装
sudo docker run hello-world

Docker 基本概念

镜像 (Images)

Docker 镜像是一个只读模板,包含创建 Docker 容器的指令。镜像可以包含一个完整的操作系统、应用程序和所有依赖项。

bash
# 列出本地镜像
docker images

# 拉取镜像
docker pull ubuntu:20.04

# 搜索镜像
docker search nginx

# 删除镜像
docker rmi image_id

容器 (Containers)

容器是镜像的运行实例,可以被启动、停止、删除。每个容器都是相互隔离的。

bash
# 运行容器
docker run -it ubuntu:20.04 bash

# 列出运行中的容器
docker ps

# 列出所有容器(包括已停止的)
docker ps -a

# 启动/停止容器
docker start container_id
docker stop container_id

# 删除容器
docker rm container_id

数据卷 (Volumes)

数据卷是 Docker 容器中数据持久化的机制,它们独立于容器的生命周期。

bash
# 创建数据卷
docker volume create my_volume

# 列出数据卷
docker volume ls

# 在容器中使用数据卷
docker run -v my_volume:/app nginx

# 使用主机目录作为数据卷
docker run -v /host/path:/container/path nginx

网络 (Networks)

Docker 网络允许容器之间以及容器与外部世界通信。

bash
# 创建网络
docker network create my_network

# 列出网络
docker network ls

# 在指定网络中运行容器
docker run --network=my_network nginx

# 将容器连接到网络
docker network connect my_network container_id

Docker 基本操作

运行容器

bash
# 基本运行
docker run nginx

# 后台运行
docker run -d nginx

# 指定名称
docker run --name my_nginx nginx

# 映射端口
docker run -p 8080:80 nginx

# 交互式终端
docker run -it ubuntu bash

# 环境变量
docker run -e MYSQL_ROOT_PASSWORD=password mysql

管理容器

bash
# 查看容器日志
docker logs container_id

# 在运行中的容器中执行命令
docker exec -it container_id bash

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

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

# 复制文件到容器
docker cp file.txt container_id:/path

# 从容器复制文件
docker cp container_id:/path/file.txt .

构建镜像

使用 Dockerfile

Dockerfile 是一个文本文件,包含构建 Docker 镜像的所有命令。

dockerfile
# 基础镜像
FROM node:14

# 设置工作目录
WORKDIR /app

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

# 安装依赖
RUN npm install

# 复制源代码
COPY . .

# 暴露端口
EXPOSE 3000

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

构建镜像:

bash
docker build -t my-app:1.0 .

常用 Dockerfile 指令

  • FROM:指定基础镜像
  • WORKDIR:设置工作目录
  • COPY/ADD:复制文件到镜像
  • RUN:执行命令并创建新层
  • ENV:设置环境变量
  • EXPOSE:声明容器监听的端口
  • VOLUME:创建挂载点
  • CMD:容器启动命令
  • ENTRYPOINT:容器入口点

镜像管理

bash
# 为镜像添加标签
docker tag image_id username/repository:tag

# 推送镜像到 Docker Hub
docker push username/repository:tag

# 保存镜像到文件
docker save -o image.tar image_name

# 从文件加载镜像
docker load -i image.tar

# 查看镜像历史
docker history image_name

Docker Compose

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。

安装 Docker Compose

bash
# Linux
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Windows 和 macOS
# Docker Desktop 已包含 Docker Compose

docker-compose.yml 文件

yaml
version: '3'

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - db
  
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: app
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

基本命令

bash
# 启动服务
docker-compose up

# 后台启动
docker-compose up -d

# 停止服务
docker-compose down

# 查看服务状态
docker-compose ps

# 查看服务日志
docker-compose logs

# 执行命令
docker-compose exec web bash

Docker 实战示例

部署 Web 应用

Node.js 应用

dockerfile
FROM node:14

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["node", "app.js"]
bash
docker build -t my-node-app .
docker run -p 3000:3000 my-node-app

使用 Docker Compose 部署 MEAN 栈

yaml
version: '3'

services:
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend
  
  backend:
    build: ./backend
    ports:
      - "3000:3000"
    environment:
      - MONGODB_URI=mongodb://db:27017/myapp
    depends_on:
      - db
  
  db:
    image: mongo:4.4
    volumes:
      - mongo_data:/data/db

volumes:
  mongo_data:

数据库容器

MySQL

bash
docker run -d \
  --name mysql \
  -e MYSQL_ROOT_PASSWORD=my-secret-pw \
  -e MYSQL_DATABASE=mydb \
  -v mysql_data:/var/lib/mysql \
  -p 3306:3306 \
  mysql:5.7

PostgreSQL

bash
docker run -d \
  --name postgres \
  -e POSTGRES_PASSWORD=my-secret-pw \
  -e POSTGRES_DB=mydb \
  -v postgres_data:/var/lib/postgresql/data \
  -p 5432:5432 \
  postgres:13

MongoDB

bash
docker run -d \
  --name mongodb \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=password \
  -v mongo_data:/data/db \
  -p 27017:27017 \
  mongo:4.4

Docker 最佳实践

镜像优化

  1. 使用官方镜像:优先使用官方维护的镜像
  2. 使用特定标签:避免使用 latest 标签
  3. 多阶段构建:减小最终镜像大小
dockerfile
# 构建阶段
FROM node:14 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 生产阶段
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
  1. 最小化层数:合并 RUN 命令减少层数
  2. 清理不必要的文件:删除缓存和临时文件

安全最佳实践

  1. 使用非 root 用户
dockerfile
FROM node:14
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
USER appuser
CMD ["node", "app.js"]
  1. 扫描镜像漏洞:使用 Docker Scout、Trivy 等工具
  2. 使用内容信任:签名和验证镜像
  3. 限制容器资源:设置内存和 CPU 限制
  4. 使用只读文件系统docker run --read-only ...

容器编排

对于生产环境,考虑使用容器编排平台:

  • Kubernetes:大规模容器编排平台
  • Docker Swarm:Docker 原生集群管理工具
  • Amazon ECS:AWS 的容器编排服务
  • Azure Container Instances:Azure 的容器服务

监控和日志

  1. 集中式日志管理:使用 ELK 栈或 Prometheus + Grafana
  2. 健康检查:实现容器健康检查
  3. 资源监控:监控容器 CPU、内存使用情况

Docker 常见问题解答

容器无法访问网络

检查以下几点:

  • DNS 配置是否正确
  • 网络模式是否适合您的用例
  • 防火墙规则是否阻止了连接

容器启动后立即退出

容器需要在前台运行一个进程,如果主进程退出,容器也会退出。解决方法:

  • 确保 CMD 或 ENTRYPOINT 指令正确
  • 检查应用程序是否正确运行
  • 使用 docker logs 查看错误信息

数据持久化问题

使用数据卷或绑定挂载来持久化数据:

  • 数据卷:docker run -v my_volume:/app/data ...
  • 绑定挂载:docker run -v /host/path:/container/path ...

容器间通信

容器可以通过以下方式通信:

  • 使用用户定义的网络:docker network create my_network
  • 使用 Docker Compose 定义服务
  • 使用容器名称作为主机名

Docker 占用磁盘空间过大

清理未使用的资源:

bash
# 删除所有停止的容器
docker container prune

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

# 删除未使用的数据卷
docker volume prune

# 删除所有未使用的对象
docker system prune

相关资源


本文档将持续更新,如有问题请通过 GitHub Issues 反馈。

vitepress开发指南