Docker 完全指南:从入门到日常使用

Docker 完全指南:从入门到日常使用

本文涵盖 Docker 的核心概念、安装配置、常用命令以及实际工作中的使用场景,适合开发者日常参考。


目录


什么是 Docker

Docker 是一个开源的容器化平台,让你可以将应用及其所有依赖打包进一个轻量级、可移植的容器中,实现”一次构建,到处运行”。

与虚拟机的区别:

对比项 Docker 容器 虚拟机
启动速度 秒级 分钟级
资源占用 极低(共享宿主内核) 较高(独立操作系统)
隔离性 进程级隔离 完全隔离
镜像大小 MB 级别 GB 级别
可移植性 极强 一般

核心概念

镜像(Image)

镜像是容器的只读模板,类似于系统安装盘。镜像是分层构建的,每一层都基于上一层叠加。

容器(Container)

容器是镜像的运行实例,类似于虚拟机实例。容器是独立的、隔离的运行环境,可以启动、停止、删除。

仓库(Registry)

仓库用于存储和分发镜像。Docker Hub 是最大的公共仓库,也可以搭建私有仓库。

Docker Compose

用于定义和运行多容器应用的工具,通过 docker-compose.yml 文件统一管理。

数据卷(Volume)

用于容器数据持久化的机制,容器删除后数据依然保留。


安装 Docker

macOS

1
2
3
4
5
# 推荐:下载 Docker Desktop
# https://www.docker.com/products/docker-desktop/

# 或使用 Homebrew
brew install --cask docker

Ubuntu / Debian

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc

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

# 添加 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

# 添加仓库
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

# 安装
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 当前用户加入 docker 组(免 sudo)
sudo usermod -aG docker $USER
newgrp docker

CentOS / RHEL

1
2
3
4
5
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl start docker
sudo systemctl enable docker

验证安装

1
2
3
4
5
docker --version
# Docker version 25.x.x, build xxxxxxx

docker run hello-world
# 看到 "Hello from Docker!" 说明安装成功

镜像操作

搜索镜像

1
2
docker search nginx
docker search --filter=stars=1000 python # 筛选 star 数 > 1000

拉取镜像

1
2
3
docker pull nginx              # 拉取最新版
docker pull nginx:1.25 # 拉取指定版本
docker pull ubuntu:22.04

查看本地镜像

1
2
3
docker images
docker images -a # 包含中间层镜像
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

删除镜像

1
2
3
4
docker rmi nginx               # 删除镜像
docker rmi nginx:1.25 # 删除指定版本
docker image prune # 删除所有未使用镜像
docker image prune -a # 删除所有没有容器使用的镜像

导出 / 导入镜像

1
2
3
4
5
# 导出
docker save -o myapp.tar myapp:latest

# 导入
docker load -i myapp.tar

给镜像打标签

1
docker tag myapp:latest myregistry.com/myapp:v1.0

容器操作

运行容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 基本运行
docker run nginx

# 常用参数组合
docker run -d \ # 后台运行
--name my-nginx \ # 指定容器名
-p 8080:80 \ # 端口映射 宿主机:容器
-v /data/html:/usr/share/nginx/html \ # 挂载目录
-e NGINX_PORT=80 \ # 设置环境变量
--restart unless-stopped \ # 自动重启策略
nginx:latest

# 交互式运行(进入容器 shell)
docker run -it ubuntu:22.04 bash

# 运行后自动删除容器(适合临时任务)
docker run --rm ubuntu:22.04 echo "hello"

查看容器

1
2
3
docker ps                        # 查看运行中的容器
docker ps -a # 查看所有容器(含已停止)
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

启动 / 停止 / 重启

1
2
3
4
docker start my-nginx
docker stop my-nginx # 优雅停止(发 SIGTERM)
docker kill my-nginx # 强制停止(发 SIGKILL)
docker restart my-nginx

进入运行中的容器

1
2
3
docker exec -it my-nginx bash
docker exec -it my-nginx sh # 没有 bash 时用 sh
docker exec my-nginx ls /etc/nginx # 执行单条命令

查看容器日志

1
2
3
4
docker logs my-nginx
docker logs -f my-nginx # 实时跟踪日志
docker logs --tail 100 my-nginx # 最后 100 行
docker logs --since 1h my-nginx # 最近 1 小时

查看容器详情

1
2
3
docker inspect my-nginx          # 详细配置信息(JSON)
docker stats # 实时资源使用情况
docker top my-nginx # 容器内进程

文件拷贝

1
2
3
4
5
# 宿主机 → 容器
docker cp ./config.conf my-nginx:/etc/nginx/conf.d/

# 容器 → 宿主机
docker cp my-nginx:/var/log/nginx/access.log ./

删除容器

1
2
3
docker rm my-nginx               # 删除已停止的容器
docker rm -f my-nginx # 强制删除(含运行中)
docker container prune # 删除所有已停止的容器

数据持久化

数据卷(Volume)— 推荐方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建数据卷
docker volume create mydata

# 使用数据卷
docker run -d \
--name mysql \
-v mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0

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

# 删除数据卷
docker volume rm mydata
docker volume prune # 删除所有未使用的卷

绑定挂载(Bind Mount)

1
2
3
4
# 将宿主机目录直接挂载到容器
docker run -d \
-v /home/user/html:/usr/share/nginx/html:ro \ # ro = 只读
nginx

两种方式对比

对比项 Volume Bind Mount
管理方式 Docker 管理 用户管理
可移植性 依赖宿主机路径
适用场景 数据库、应用数据 开发时代码热更新

网络管理

网络类型

类型 说明
bridge 默认,容器间可通信,与宿主机隔离
host 共享宿主机网络,性能最好
none 完全隔离,无网络
自定义 bridge 推荐,容器间可通过名称互相访问

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看网络
docker network ls

# 创建自定义网络
docker network create mynet

# 将容器加入网络
docker run -d --name app --network mynet myapp
docker run -d --name db --network mynet mysql:8.0

# 此时 app 容器可以用 "db" 作为主机名访问数据库

# 查看网络详情
docker network inspect mynet

# 删除网络
docker network rm mynet
docker network prune

Dockerfile 编写

Dockerfile 是构建镜像的脚本文件。

常用指令

指令 说明
FROM 基础镜像
WORKDIR 设置工作目录
COPY 复制文件(推荐)
ADD 复制文件(支持 URL 和 tar 解压)
RUN 构建时执行命令
ENV 设置环境变量
EXPOSE 声明容器端口(文档作用)
CMD 容器启动默认命令(可被覆盖)
ENTRYPOINT 容器入口命令(不易被覆盖)
ARG 构建参数
LABEL 添加元数据
USER 切换运行用户

Node.js 应用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 使用官方 Node.js 镜像作为基础
FROM node:20-alpine

# 设置工作目录
WORKDIR /app

# 先复制依赖文件(利用层缓存)
COPY package*.json ./

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

# 复制源码
COPY . .

# 声明端口
EXPOSE 3000

# 使用非 root 用户运行
USER node

# 启动命令
CMD ["node", "server.js"]

Python 应用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FROM python:3.11-slim

WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

构建镜像

1
2
3
docker build -t myapp:latest .
docker build -t myapp:v1.0 -f Dockerfile.prod . # 指定 Dockerfile
docker build --no-cache -t myapp:latest . # 不使用缓存

Dockerfile 最佳实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# ✅ 合并 RUN 命令减少层数
RUN apt-get update \
&& apt-get install -y curl wget \
&& rm -rf /var/lib/apt/lists/*

# ✅ 使用 .dockerignore 排除不必要文件
# .dockerignore 内容:
# node_modules
# .git
# *.log
# .env

# ✅ 多阶段构建(减小最终镜像体积)
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM node:20-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]

Docker Compose

安装

1
2
3
4
5
# Docker Desktop 已内置
docker compose version

# Linux 单独安装
sudo apt-get install docker-compose-plugin

docker-compose.yml 示例

Web 应用 + 数据库 + Redis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
version: '3.9'

services:
# Web 应用
app:
build: .
container_name: myapp
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=db
- REDIS_HOST=redis
depends_on:
db:
condition: service_healthy
networks:
- mynet
restart: unless-stopped

# MySQL 数据库
db:
image: mysql:8.0
container_name: myapp-db
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: myapp
MYSQL_USER: user
MYSQL_PASSWORD: userpass
volumes:
- db_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
networks:
- mynet
restart: unless-stopped

# Redis 缓存
redis:
image: redis:7-alpine
container_name: myapp-redis
volumes:
- redis_data:/data
networks:
- mynet
restart: unless-stopped

volumes:
db_data:
redis_data:

networks:
mynet:
driver: bridge

Compose 常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 启动所有服务(后台)
docker compose up -d

# 构建并启动
docker compose up -d --build

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs -f
docker compose logs -f app # 指定服务

# 停止服务
docker compose stop

# 停止并删除容器(保留数据卷)
docker compose down

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

# 进入指定服务容器
docker compose exec app bash

# 扩容(横向扩展)
docker compose up -d --scale app=3

# 重启某个服务
docker compose restart app

实战示例

场景一:快速启动 MySQL

1
2
3
4
5
6
7
8
9
10
11
docker run -d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=mydb \
-v mysql_data:/var/lib/mysql \
--restart unless-stopped \
mysql:8.0

# 连接进入
docker exec -it mysql8 mysql -uroot -p123456

场景二:快速启动 Redis

1
2
3
4
5
docker run -d \
--name redis \
-p 6379:6379 \
-v redis_data:/data \
redis:7-alpine redis-server --requirepass 123456

场景三:Nginx 静态站点

1
2
3
4
5
6
docker run -d \
--name website \
-p 80:80 \
-v $(pwd)/html:/usr/share/nginx/html:ro \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
nginx:alpine

场景四:临时调试工具

1
2
3
4
5
6
7
8
# 快速进入 alpine 环境做网络调试
docker run --rm -it alpine sh

# 测试 curl
docker run --rm curlimages/curl https://example.com

# 在容器内跑 Python 脚本
docker run --rm -v $(pwd):/app -w /app python:3.11 python script.py

场景五:私有镜像仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
# 启动本地 Registry
docker run -d \
--name registry \
-p 5000:5000 \
-v registry_data:/var/lib/registry \
registry:2

# 推送镜像到私有仓库
docker tag myapp:latest localhost:5000/myapp:latest
docker push localhost:5000/myapp:latest

# 从私有仓库拉取
docker pull localhost:5000/myapp:latest

常用技巧与最佳实践

清理空间

1
2
3
4
5
# 一键清理所有未使用资源(镜像、容器、网络、缓存)
docker system prune -a

# 查看 Docker 占用磁盘空间
docker system df

限制容器资源

1
2
3
4
5
docker run -d \
--memory="512m" \ # 限制内存 512MB
--cpus="1.5" \ # 限制 CPU 1.5 核
--memory-swap="1g" \ # swap 空间
myapp

环境变量管理

1
2
3
4
# 使用 .env 文件
docker run --env-file .env myapp

# docker-compose 自动读取同目录下的 .env

健康检查

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

查看镜像构建历史

1
docker history myapp:latest

查看容器 IP

1
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' myapp

容器内时区设置

1
2
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

常见问题排查

容器启动失败

1
2
3
# 查看退出原因
docker logs my-container
docker inspect my-container | grep -A 5 '"State"'

端口被占用

1
2
3
4
# 查看宿主机端口占用
lsof -i :8080
# 或
netstat -tlnp | grep 8080

镜像拉取慢

1
2
3
4
5
6
7
8
9
10
11
# 配置国内镜像加速(/etc/docker/daemon.json)
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://hub-mirror.c.163.com"
]
}

# 重启 Docker
sudo systemctl daemon-reload
sudo systemctl restart docker

容器间无法通信

1
2
3
4
5
# 确认容器在同一网络
docker network inspect mynet

# 测试连通性
docker exec app ping db

磁盘空间不足

1
2
3
docker system df            # 查看使用情况
docker system prune -a -f # 清理所有未使用资源
docker volume prune -f # 清理未使用数据卷

权限问题

1
2
3
4
# 如果遇到 permission denied
sudo chmod 666 /var/run/docker.sock
# 或将用户加入 docker 组
sudo usermod -aG docker $USER

速查表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# ===== 镜像 =====
docker pull <image> # 拉取镜像
docker images # 列出镜像
docker rmi <image> # 删除镜像
docker build -t <name> . # 构建镜像
docker push <image> # 推送镜像

# ===== 容器 =====
docker run -d -p 80:80 --name x img # 运行容器
docker ps / docker ps -a # 列出容器
docker start/stop/restart <name> # 启停容器
docker exec -it <name> bash # 进入容器
docker logs -f <name> # 查看日志
docker rm -f <name> # 删除容器
docker stats # 资源监控

# ===== Compose =====
docker compose up -d # 启动服务
docker compose down # 停止删除
docker compose logs -f # 查看日志
docker compose exec <svc> bash # 进入服务

# ===== 清理 =====
docker system prune -a # 清理所有
docker volume prune # 清理数据卷

最后更新:2025 年 | 适用 Docker 25.x


Docker 完全指南:从入门到日常使用
https://www.psnow.sbs/2026/03/09/Docker-完全指南:从入门到日常使用/
作者
Psnow
发布于
2026年3月9日
许可协议