Docker 介绍与使用
什么是 Docker
Docker 是一个开源的容器化平台,让你可以打包应用及其依赖到一个可移植的容器中,然后在任何支持 Docker 的环境中运行。
核心概念
| 概念 | 说明 |
|---|---|
| 镜像(Image) | 应用程序的只读模板,包含运行应用所需的所有内容 |
| 容器(Container) | 镜像的运行实例,类似轻量级虚拟机 |
| 仓库(Registry) | 存储和分发镜像的地方,最常用的是 Docker Hub |
| Dockerfile | 定义镜像构建步骤的配置文件 |
容器 vs 虚拟机
| 特性 | Docker 容器 | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | 很小(MB 级) | 较大(GB 级) |
| 性能 | 接近原生 | 有一定损耗 |
| 隔离性 | 进程级隔离 | 完全隔离 |
| 操作系统 | 共享宿主机内核 | 独立操作系统 |
安装 Docker
Ubuntu/Debian
# 1. 卸载旧版本(如有)
sudo apt remove docker docker-engine docker.io containerd runc
# 2. 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
# 3. 添加 Docker GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 4. 添加 Docker 仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 5. 安装 Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 6. 验证安装
sudo docker run hello-world
启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
非 Root 用户免 sudo
sudo usermod -aG docker $USER
# 重新登录生效,或执行
newgrp docker
macOS / Windows
下载 Docker Desktop 安装包进行安装。
基础命令
镜像操作
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
# 列出本地镜像
docker images
docker images -a # 包含中间层
# 删除镜像
docker rmi nginx:latest
# 构建镜像(根据 Dockerfile)
docker build -t myapp:1.0 .
# 导出/导入镜像
docker save -o myapp.tar myapp:1.0
docker load -i myapp.tar
# 查看镜像详情
docker inspect nginx:latest
容器操作
# 运行容器(最常用)
docker run nginx # 后台运行
docker run -it nginx /bin/bash # 交互式运行
docker run -d nginx # 后台守护式运行
docker run --name mynginx nginx # 指定容器名称
# 常见选项
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 常用选项:
# -d 后台运行
# -it 交互式终端
# --name 容器名称
# -p 8080:80 端口映射(宿主机:容器)
# -v /host:/container 卷挂载
# -e KEY=VALUE 设置环境变量
# --network 指定网络
# --rm 容器停止后自动删除
# --restart 重启策略(no/on-failure/always/unless-stopped)
# 列出运行中的容器
docker ps
# 列出所有容器(包括已停止)
docker ps -a
# 启动/停止/重启容器
docker start mynginx
docker stop mynginx
docker restart mynginx
# 删除容器
docker rm mynginx
docker rm -f mynginx # 强制删除(运行中也可删)
# 进入运行中的容器
docker exec -it mynginx /bin/bash
docker exec -it mynginx sh # 很多容器没有 bash
# 查看容器日志
docker logs mynginx
docker logs -f mynginx # 实时跟踪
# 查看容器进程
docker top mynginx
# 查看容器详细信息
docker inspect mynginx
进入容器的替代方法
# 如果容器已经在运行
docker attach mynginx
# 推荐方式(exec)
docker exec -it mynginx /bin/sh
进阶命令
Docker Compose
Docker Compose 用于定义和运行多容器应用。
安装(新版 Docker 已内置):
docker compose version
示例 docker-compose.yml:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- redis
networks:
- mynet
redis:
image: redis:alpine
networks:
- mynet
networks:
mynet:
常用命令:
docker compose up -d # 后台启动所有服务
docker compose up --build # 构建并启动
docker compose down # 停止并删除容器
docker compose down -v # 删除容器和卷
docker compose ps # 查看状态
docker compose logs -f # 查看日志
docker compose restart # 重启
docker compose exec web sh # 在服务中执行命令
docker compose build # 构建镜像
docker compose pull # 拉取依赖镜像
清理资源
# 删除已停止的容器
docker container prune
# 删除未使用的镜像
docker image prune
docker image prune -a # 删除所有未使用镜像
# 删除未使用的卷
docker volume prune
# 删除未使用的网络
docker network prune
# 一键清理所有未使用资源
docker system prune
docker system prune -a # 清理更多(包括未使用的镜像)
查看资源使用
docker stats # 实时显示资源使用
docker stats --no-stream # 单次显示
实战示例
1. 运行一个 Web 服务
docker run -d \
--name mynginx \
-p 8080:80 \
nginx:latest
# 访问 http://localhost:8080
2. 运行 MySQL 数据库
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=mysecretpassword \
-e MYSQL_DATABASE=myapp \
-v mysql_data:/var/lib/mysql \
mysql:8.0
# 连接:mysql -h localhost -P 3306 -u root -p
3. 运行 Redis
docker run -d \
--name redis \
-p 6379:6379 \
redis:alpine
# 使用 redis-cli 连接
docker exec -it redis redis-cli
4. 使用 Docker Compose 运行 LNMP
# docker-compose.yml
version: '3'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html
depends_on:
- php
networks:
- app-net
php:
image: php:8.2-fpm
volumes:
- ./html:/var/www/html
networks:
- app-net
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: myapp
volumes:
- mysql_data:/var/lib/mysql
networks:
- app-net
volumes:
mysql_data:
networks:
app-net:
driver: bridge
启动:
docker compose up -d
5. 构建自定义镜像
创建 Dockerfile:
# 基于官方镜像
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 复制文件
COPY package*.json ./
# 安装依赖
RUN npm install --production
# 复制源代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["node", "server.js"]
构建并运行:
docker build -t myapp:1.0 .
docker run -d --name myapp -p 3000:3000 myapp:1.0
Dockerfile 常用指令
| 指令 | 说明 |
|---|---|
FROM | 指定基础镜像 |
RUN | 执行命令 |
COPY | 复制文件 |
ADD | 复制文件(支持 URL 和解压) |
WORKDIR | 设置工作目录 |
ENV | 设置环境变量 |
EXPOSE | 声明端口 |
CMD | 容器启动命令 |
ENTRYPOINT | 入口点 |
VOLUME | 定义卷 |
ARG | 构建参数 |
CMD vs ENTRYPOINT
# CMD:默认命令,可被 docker run 参数覆盖
CMD ["echo", "hello"]
# ENTRYPOINT:固定入口,参数附加在其后
ENTRYPOINT ["echo", "hello"]
# docker run image world → 输出 "hello world"
数据管理
挂载宿主目录
docker run -v /host/path:/container/path nginx
使用 Docker 卷
# 创建卷
docker volume create mydata
# 使用卷
docker run -v mydata:/data nginx
# 查看卷
docker volume ls
docker volume inspect mydata
# 删除未使用卷
docker volume prune
数据备份
# 备份
docker run --rm -v mydata:/data -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz /data
# 恢复
docker run --rm -v mydata:/data -v $(pwd):/backup alpine tar xzf /backup/backup.tar.gz -C /
网络配置
网络模式
| 模式 | 说明 |
|---|---|
bridge | 默认模式,容器连接到 bridge 网络 |
host | 容器共享宿主机的网络命名空间 |
none | 禁用网络 |
overlay | 跨 Docker 守护进程通信 |
macvlan | 为容器分配 MAC 地址 |
创建自定义网络
docker network create mynet
docker network ls
# 容器加入网络
docker run --network=mynet nginx
# 连接已运行的容器到网络
docker network connect mynet mynginx
容器间通信
# docker-compose.yml 中自动创建网络
services:
web:
networks:
- mynet
db:
networks:
- mynet
networks:
mynet:
Docker 镜像加速
中国镜像加速器
创建或编辑 /etc/docker/daemon.json:
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
应用配置:
sudo systemctl daemon-reload
sudo systemctl restart docker
验证:
docker info | grep -A 10 "Registry Mirrors"
常用场景
1. 开发环境隔离
# 每个项目独立的开发环境
docker run -d --name project1-db -e MYSQL_ROOT_PASSWORD=secret mysql:8.0
2. 一键部署应用
docker compose up -d --build
3. 定时任务容器化
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "task.py"]
4. 临时测试环境
# 用完即删
docker run --rm -it python:3.11 python
常见问题
容器内中文乱码
docker run -e LANG=C.UTF-8 nginx
容器时间不同步
docker run -v /etc/localtime:/etc/localtime:ro nginx
查看容器 IP
docker inspect -f '{{.NetworkSettings.IPAddress}}' mynginx
容器无法访问外网
# 重启 Docker
sudo systemctl restart docker
# 检查 iptables
sudo iptables -L -n
Docker 太占空间
docker system prune -a # 清理
docker volume prune # 清理卷