1285 lines
26 KiB
Markdown
1285 lines
26 KiB
Markdown
---
|
||
title: Docker 部署完全指南:从入门到实战
|
||
id: 019d3951-f81b-7300-8118-318761bb0138
|
||
date: 2026-03-30
|
||
author: liuhangyv
|
||
cover:
|
||
excerpt: Docker 部署完全指南 本文从基础概念讲起,逐步深入到 Docker Compose 实战配置,涵盖环境准备、镜像管理、数据持久化、网络配置等核心内容。 1. Docker 基础概念 在开始部署之前,让我们先了解 Docker 的核心概念。
|
||
permalink: /archives/docker-bu-shu-wan-quan-zhi-nan
|
||
categories:
|
||
- xie-hui-jin-xing-shi
|
||
tags:
|
||
- Docker
|
||
- container
|
||
- xiang-mu-shi-zhan
|
||
- ling-ji-chu-ru-men
|
||
---
|
||
|
||
<!-- markdownlint-disable MD025 -->
|
||
|
||
# Docker 部署完全指南:从入门到实战
|
||
|
||
本文档从基础概念讲起,逐步深入到 Docker Compose 实战配置,涵盖环境准备、镜像管理、数据持久化、网络配置等核心内容。无论你是初学者还是有一定基础的开发者,都能从中获得实用的部署知识。
|
||
|
||
## 1. Docker 基础概念
|
||
|
||
在开始部署之前,让我们先了解 Docker 的核心概念:
|
||
|
||
### 1.1 什么是 Docker
|
||
|
||
Docker 是一个开源的**容器化平台**,允许开发者将应用程序及其依赖打包成一个独立的容器,确保应用在任何环境中都能一致运行。
|
||
|
||
**核心优势**:
|
||
|
||
- **一致性**:开发、测试、生产环境保持一致
|
||
- **隔离性**:每个容器相互隔离,互不影响
|
||
- **轻量化**:相比虚拟机,容器启动更快、资源占用更少
|
||
- **可移植性**:一次构建,随处运行
|
||
|
||
### 1.2 核心概念解析
|
||
|
||
| 概念 | 说明 |
|
||
|
||
|------|------|
|
||
| **镜像(Image)** | 应用程序的模板,包含代码、运行时、环境变量等 |
|
||
| **容器(Container)** | 镜像的运行实例,可以启动、停止、删除 |
|
||
| **仓库(Repository)** | 存储和分发镜像的地方,如 Docker Hub |
|
||
| **Dockerfile** | 定义镜像构建步骤的脚本文件 |
|
||
|
||
### 1.3 Docker 与 Docker Compose 的区别
|
||
|
||
| 工具 | 用途 | 使用场景 |
|
||
|------|------|----------|
|
||
| **Docker** | 管理单个容器 | 快速测试、简单部署 |
|
||
| **Docker Compose** | 管理多容器应用 | 复杂应用、服务编排 |
|
||
|
||
---
|
||
|
||
## 2. 环境准备
|
||
|
||
### 2.1 Windows 系统
|
||
|
||
#### 安装 Docker Desktop
|
||
|
||
1. 下载 Docker Desktop:[https://www.docker.com/products/docker-desktop/](https://www.docker.com/products/docker-desktop/)
|
||
2. 运行安装程序,**务必勾选 WSL2 后端**(推荐)
|
||
3. 安装完成后重启电脑
|
||
4. 打开 Docker Desktop,检查是否正常运行
|
||
|
||
#### 验证安装
|
||
|
||
打开 PowerShell 或命令提示符,执行以下命令:
|
||
|
||
```powershell
|
||
# 检查 Docker 版本
|
||
docker --version
|
||
|
||
# 检查 Docker Compose 版本(V2)
|
||
docker compose version
|
||
|
||
# 如果是旧版 V1(需要单独安装)
|
||
docker-compose --version
|
||
```
|
||
|
||
> **📝 注意**:Docker Desktop for Windows 已默认集成 Docker Compose V2,推荐使用 `docker compose` 命令。
|
||
|
||
#### WSL2 配置(如未自动配置)
|
||
|
||
```powershell
|
||
# 打开 PowerShell(管理员)
|
||
wsl --install
|
||
|
||
# 设置 WSL2 为默认版本
|
||
wsl --set-default-version 2
|
||
|
||
# 查看已安装的发行版
|
||
wsl --list -v
|
||
```
|
||
|
||
### 2.2 Linux 系统
|
||
|
||
#### Ubuntu/Debian
|
||
|
||
```bash
|
||
# 更新软件包
|
||
sudo apt update
|
||
|
||
# 安装依赖
|
||
sudo apt 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
|
||
|
||
# 添加 Docker 仓库
|
||
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
|
||
sudo apt update
|
||
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||
|
||
# 将当前用户加入 docker 组(无需 sudo)
|
||
sudo usermod -aG docker $USER
|
||
|
||
# 重新登录后生效
|
||
```
|
||
|
||
#### CentOS/RHEL
|
||
|
||
```bash
|
||
# 删除旧版本
|
||
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
|
||
|
||
# 安装依赖
|
||
sudo yum install -y yum-utils
|
||
|
||
# 添加 Docker 仓库
|
||
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||
|
||
# 安装 Docker
|
||
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||
|
||
# 启动并设置开机自启
|
||
sudo systemctl start docker
|
||
sudo systemctl enable docker
|
||
|
||
# 将当前用户加入 docker 组
|
||
sudo usermod -aG docker $USER
|
||
```
|
||
|
||
### 2.3 硬件资源建议
|
||
|
||
| 配置级别 | CPU | 内存 | 存储 |
|
||
|----------|-----|------|------|
|
||
| **最低配置** | 2核 | 2GB | 20GB |
|
||
| **推荐配置** | 4核 | 4GB | 50GB |
|
||
| **高性能配置** | 8核 | 8GB+ | 100GB+ |
|
||
|
||
---
|
||
|
||
## 3. Docker 核心操作
|
||
|
||
### 3.1 镜像操作
|
||
|
||
```bash
|
||
# 搜索镜像
|
||
docker search nginx
|
||
|
||
# 拉取镜像
|
||
docker pull nginx:latest
|
||
|
||
# 查看本地镜像
|
||
docker images
|
||
|
||
# 删除镜像
|
||
docker rmi nginx:latest
|
||
|
||
# 清理未使用的镜像
|
||
docker image prune
|
||
```
|
||
|
||
### 3.2 容器操作
|
||
|
||
```bash
|
||
# 运行容器(后台模式)
|
||
docker run -d --name my-nginx nginx:latest
|
||
|
||
# 运行容器(交互模式)
|
||
docker run -it ubuntu:latest /bin/bash
|
||
|
||
# 映射端口:宿主机:容器
|
||
docker run -d -p 8080:80 --name my-nginx nginx:latest
|
||
|
||
# 映射目录:宿主机路径:容器路径
|
||
docker run -d -p 8080:80 -v /host/data:/container/data --name my-nginx nginx:latest
|
||
|
||
# 查看运行中的容器
|
||
docker ps
|
||
|
||
# 查看所有容器(包括已停止)
|
||
docker ps -a
|
||
|
||
# 停止容器
|
||
docker stop my-nginx
|
||
|
||
# 启动已停止的容器
|
||
docker start my-nginx
|
||
|
||
# 重启容器
|
||
docker restart my-nginx
|
||
|
||
# 删除容器(必须先停止)
|
||
docker rm my-nginx
|
||
|
||
# 强制删除运行中的容器
|
||
docker rm -f my-nginx
|
||
|
||
# 进入容器内部
|
||
docker exec -it my-nginx bash
|
||
|
||
# 查看容器日志
|
||
docker logs -f my-nginx
|
||
|
||
# 查看容器资源使用
|
||
docker stats my-nginx
|
||
```
|
||
|
||
### 3.3 容器网络操作
|
||
|
||
```bash
|
||
# 查看网络列表
|
||
docker network ls
|
||
|
||
# 创建自定义网络
|
||
docker network create my-network
|
||
|
||
# 将容器连接到网络
|
||
docker network connect my-network my-nginx
|
||
|
||
# 从网络断开
|
||
docker network disconnect my-network my-nginx
|
||
|
||
# 查看网络详情
|
||
docker network inspect my-network
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Docker Compose 详解
|
||
|
||
### 4.1 docker-compose.yaml 基础结构
|
||
|
||
Docker Compose 使用 YAML 格式定义多容器应用的服务、网络、数据卷等。
|
||
|
||
**基础模板**:
|
||
|
||
```yaml
|
||
version: "3.8" # Docker Compose 文件版本
|
||
|
||
services: # 定义所有服务(容器)
|
||
web: # 服务名称
|
||
image: nginx:latest # 使用的镜像
|
||
container_name: my-web # 容器名称
|
||
restart: unless-stopped # 重启策略
|
||
ports: # 端口映射
|
||
- "80:80"
|
||
volumes: # 数据卷映射
|
||
- ./html:/usr/share/nginx/html:ro
|
||
networks: # 所属网络
|
||
- frontend
|
||
|
||
db: # 数据库服务
|
||
image: postgres:16
|
||
container_name: my-db
|
||
restart: unless-stopped
|
||
environment: # 环境变量
|
||
POSTGRES_DB: myapp
|
||
POSTGRES_USER: admin
|
||
POSTGRES_PASSWORD: secret
|
||
volumes:
|
||
- postgres-data:/var/lib/postgresql/data
|
||
networks:
|
||
- frontend
|
||
- backend
|
||
|
||
networks: # 定义网络
|
||
frontend:
|
||
driver: bridge
|
||
backend:
|
||
driver: bridge
|
||
|
||
volumes: # 定义数据卷
|
||
postgres-data:
|
||
```
|
||
|
||
### 4.2 常用配置项详解
|
||
|
||
#### 服务配置(services)
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
# 镜像配置
|
||
image: nginx:alpine # 镜像:标签
|
||
build: ./ # 从 Dockerfile 构建
|
||
container_name: my-app # 容器名称
|
||
|
||
# 启动策略
|
||
restart: "no" # 不自动重启
|
||
restart: on-failure # 失败时重启
|
||
restart: always # 始终重启
|
||
restart: unless-stopped # 除非手动停止,否则重启
|
||
|
||
# 端口映射
|
||
ports:
|
||
- "80:80" # 宿主机端口:容器端口
|
||
- "443:443"
|
||
- "8080-8090:8080" # 端口范围映射
|
||
|
||
# 目录映射
|
||
volumes:
|
||
- /host/path:/container/path # 绝对路径
|
||
- ./relative/path:/container/path # 相对路径
|
||
- volume-name:/container/path # 命名卷
|
||
- /host/path:/container/path:ro # 只读挂载
|
||
|
||
# 环境变量
|
||
environment:
|
||
- DB_HOST=localhost
|
||
- DB_PORT=5432
|
||
# 或使用键值对格式
|
||
DB_NAME: myapp
|
||
|
||
# 依赖关系(等待其他服务启动)
|
||
depends_on:
|
||
- db
|
||
- redis
|
||
|
||
# 健康检查
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost/health"]
|
||
interval: 30s
|
||
timeout: 3s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
# 资源限制
|
||
mem_limit: 512m # 最大内存
|
||
cpus: 1.0 # CPU 核心数
|
||
cpu_shares: 512 # CPU 权重
|
||
|
||
# 网络配置
|
||
networks:
|
||
- frontend
|
||
- backend
|
||
|
||
# 命令覆盖
|
||
command: ["python", "app.py", "--debug"]
|
||
|
||
# 备用命令(Shell 格式)
|
||
entrypoint: /bin/sh -c "python app.py"
|
||
```
|
||
|
||
#### 资源限制配置(ulimits)
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: postgres:16
|
||
ulimits:
|
||
nofile:
|
||
soft: 65536 # 软限制
|
||
hard: 65536 # 硬限制
|
||
nproc:
|
||
soft: 4096
|
||
hard: 4096
|
||
```
|
||
|
||
#### 共享内存配置
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: postgres:16
|
||
shm_size: '2gb' # 设置 /dev/shm 大小
|
||
```
|
||
|
||
#### init 进程配置
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: nginx:latest
|
||
init: true # 启用 init 进程,处理僵尸进程和信号传递
|
||
```
|
||
|
||
### 4.3 网络配置(networks)
|
||
|
||
```yaml
|
||
networks:
|
||
# 桥接网络(默认)
|
||
frontend:
|
||
driver: bridge
|
||
|
||
# 自定义网段
|
||
backend:
|
||
driver: bridge
|
||
ipam:
|
||
config:
|
||
- subnet: 172.20.0.0/16
|
||
|
||
# 外部网络(已存在的网络)
|
||
external-network:
|
||
external: true
|
||
```
|
||
|
||
### 4.4 数据卷配置(volumes)
|
||
|
||
```yaml
|
||
volumes:
|
||
# 命名卷(自动创建)
|
||
db-data:
|
||
driver: local
|
||
|
||
# 自定义数据卷配置
|
||
persistent-data:
|
||
driver: local
|
||
driver_opts:
|
||
type: none
|
||
o: bind
|
||
device: /mnt/data
|
||
|
||
# 使用已有数据卷
|
||
existing-volume:
|
||
external: true
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 实战配置示例
|
||
|
||
### 5.1 Nginx + PHP-FPM 组合
|
||
|
||
```yaml
|
||
version: "3.8"
|
||
|
||
services:
|
||
nginx:
|
||
image: nginx:alpine
|
||
container_name: web-server
|
||
restart: unless-stopped
|
||
ports:
|
||
- "80:80"
|
||
- "443:443"
|
||
volumes:
|
||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||
- ./html:/usr/share/nginx/html:ro
|
||
- ./logs:/var/log/nginx
|
||
depends_on:
|
||
php:
|
||
condition: service_healthy
|
||
networks:
|
||
- app-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "nginx -t"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 3
|
||
|
||
php:
|
||
image: php:8.2-fpm-alpine
|
||
container_name: php-fpm
|
||
restart: unless-stopped
|
||
volumes:
|
||
- ./html:/var/www/html
|
||
- ./php.ini:/usr/local/etc/php/php.ini:ro
|
||
networks:
|
||
- app-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "php-fpm -t"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 3
|
||
environment:
|
||
- PHP_MEMORY_LIMIT=256M
|
||
|
||
networks:
|
||
app-network:
|
||
driver: bridge
|
||
```
|
||
|
||
### 5.2 PostgreSQL + 应用组合
|
||
|
||
```yaml
|
||
version: "3.8"
|
||
|
||
services:
|
||
app:
|
||
image: node:18-alpine
|
||
container_name: node-app
|
||
restart: unless-stopped
|
||
working_dir: /app
|
||
volumes:
|
||
- ./app:/app
|
||
- ./data:/app/data
|
||
ports:
|
||
- "3000:3000"
|
||
depends_on:
|
||
db:
|
||
condition: service_healthy
|
||
environment:
|
||
- NODE_ENV=production
|
||
- DB_HOST=db
|
||
- DB_PORT=5432
|
||
- DB_USER=admin
|
||
- DB_PASSWORD=secret
|
||
- DB_NAME=myapp
|
||
networks:
|
||
- app-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1"]
|
||
interval: 30s
|
||
timeout: 5s
|
||
retries: 3
|
||
start_period: 20s
|
||
mem_limit: 512m
|
||
cpus: 0.5
|
||
|
||
db:
|
||
image: postgres:16-alpine
|
||
container_name: postgres-db
|
||
restart: unless-stopped
|
||
volumes:
|
||
- postgres-data:/var/lib/postgresql/data
|
||
- ./backup:/backup
|
||
ports:
|
||
- "5432:5432"
|
||
environment:
|
||
- POSTGRES_DB=myapp
|
||
- POSTGRES_USER=admin
|
||
- POSTGRES_PASSWORD=secret
|
||
networks:
|
||
- app-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -h localhost -U admin"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 5
|
||
mem_limit: 384m
|
||
cpus: 0.5
|
||
shm_size: 256m
|
||
ulimits:
|
||
nofile:
|
||
soft: 65536
|
||
hard: 65536
|
||
|
||
networks:
|
||
app-network:
|
||
driver: bridge
|
||
|
||
volumes:
|
||
postgres-data:
|
||
```
|
||
|
||
### 5.3 多阶段构建 Dockerfile 示例
|
||
|
||
```dockerfile
|
||
# 阶段1:构建
|
||
FROM node:18-alpine AS builder
|
||
WORKDIR /app
|
||
COPY package*.json ./
|
||
RUN npm ci --only=production
|
||
COPY . .
|
||
RUN npm run build
|
||
|
||
# 阶段2:运行
|
||
FROM node:18-alpine AS runtime
|
||
WORKDIR /app
|
||
ENV NODE_ENV=production
|
||
|
||
# 复制构建产物
|
||
COPY --from=builder /app/dist ./dist
|
||
COPY --from=builder /app/node_modules ./node_modules
|
||
|
||
# 创建非 root 用户
|
||
RUN addgroup -g 1001 -S nodejs && \
|
||
adduser -S nextjs -u 1001
|
||
USER nextjs
|
||
|
||
EXPOSE 3000
|
||
CMD ["node", "dist/server.js"]
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Docker Compose 常用命令
|
||
|
||
### 6.1 服务管理
|
||
|
||
```bash
|
||
# 启动所有服务(后台运行)
|
||
docker compose up -d
|
||
|
||
# 启动并重新构建镜像
|
||
docker compose up -d --build
|
||
|
||
# 停止所有服务
|
||
docker compose down
|
||
|
||
# 停止并删除容器、网络
|
||
docker compose down --volumes # 同时删除数据卷
|
||
|
||
# 重启所有服务
|
||
docker compose restart
|
||
|
||
# 重建特定服务
|
||
docker compose up -d --force-recreate service-name
|
||
```
|
||
|
||
### 6.2 查看与调试
|
||
|
||
```bash
|
||
# 查看服务状态
|
||
docker compose ps
|
||
|
||
# 查看服务日志
|
||
docker compose logs -f # 跟踪所有服务日志
|
||
docker compose logs -f web # 跟踪特定服务日志
|
||
docker compose logs --tail 100 web # 查看最近 100 行
|
||
|
||
# 查看资源使用
|
||
docker compose top
|
||
|
||
# 进入服务容器
|
||
docker compose exec web bash
|
||
docker compose exec db psql -U admin -d myapp
|
||
|
||
# 查看网络详情
|
||
docker compose network inspect app_network
|
||
```
|
||
|
||
### 6.3 镜像管理
|
||
|
||
```bash
|
||
# 拉取最新镜像
|
||
docker compose pull
|
||
|
||
# 拉取并更新服务
|
||
docker compose pull && docker compose up -d
|
||
|
||
# 清理未使用的镜像
|
||
docker compose images
|
||
docker image prune
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 数据持久化详解
|
||
|
||
### 7.1 为什么要数据持久化
|
||
|
||
Docker 容器默认是**临时的**:删除容器后,所有数据都会丢失。因此,重要数据必须通过数据卷(Volumes)持久化到宿主机。
|
||
|
||
### 7.2 三种数据卷类型
|
||
|
||
#### 1. 命名卷(推荐)
|
||
|
||
```yaml
|
||
services:
|
||
db:
|
||
image: postgres:16
|
||
volumes:
|
||
- db-data:/var/lib/postgresql/data
|
||
|
||
volumes:
|
||
db-data: # 自动创建命名卷
|
||
```
|
||
|
||
#### 2. 绑定挂载(开发环境)
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: nginx:latest
|
||
volumes:
|
||
- ./html:/usr/share/nginx/html:ro # 只读
|
||
- /host/path:/container/path # 读写
|
||
```
|
||
|
||
#### 3. tmpfs 挂载(内存存储)
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: redis:alpine
|
||
tmpfs:
|
||
- /data:size=100M,mode=0755 # 存储在内存中
|
||
```
|
||
|
||
### 7.3 数据备份与恢复
|
||
|
||
#### 备份命名卷
|
||
|
||
```bash
|
||
# 创建临时容器挂载卷进行备份
|
||
docker run --rm \
|
||
-v volume-name:/source \
|
||
-v $(pwd):/backup \
|
||
alpine \
|
||
tar czf /backup/backup.tar.gz -C /source .
|
||
```
|
||
|
||
#### 恢复数据
|
||
|
||
```bash
|
||
# 从备份恢复
|
||
docker run --rm \
|
||
-v volume-name:/target \
|
||
-v $(pwd):/backup \
|
||
alpine \
|
||
tar xzf /backup/backup.tar.gz -C /target
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 健康检查配置
|
||
|
||
### 8.1 为什么需要健康检查
|
||
|
||
健康检查(Health Check)用于:
|
||
- 确认容器是否正常运行
|
||
- 为 `depends_on` 提供真正的就绪状态
|
||
- 负载均衡器判断容器是否可用
|
||
- 自动恢复故障服务
|
||
|
||
### 8.2 常用健康检查示例
|
||
|
||
```yaml
|
||
services:
|
||
# HTTP 健康检查
|
||
web:
|
||
image: nginx:alpine
|
||
healthcheck:
|
||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 10s
|
||
|
||
# TCP 端口检查
|
||
redis:
|
||
image: redis:alpine
|
||
healthcheck:
|
||
test: ["CMD", "redis-cli", "ping"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 3
|
||
|
||
# 执行脚本检查
|
||
postgres:
|
||
image: postgres:16
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 3
|
||
```
|
||
|
||
### 8.3 depends_on 的 condition
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: node:18-alpine
|
||
depends_on:
|
||
db:
|
||
condition: service_healthy # 等待健康检查通过
|
||
redis:
|
||
condition: service_started # 仅等待启动
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 日志管理
|
||
|
||
### 9.1 日志驱动配置
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: nginx:latest
|
||
logging:
|
||
driver: "json-file" # 默认驱动
|
||
options:
|
||
max-size: "10m" # 单个日志文件最大 10MB
|
||
max-file: "3" # 保留 3 个日志文件
|
||
```
|
||
|
||
### 9.2 查看日志
|
||
|
||
```bash
|
||
# 查看所有日志
|
||
docker compose logs
|
||
|
||
# 跟踪日志
|
||
docker compose logs -f
|
||
|
||
# 查看最近 N 行
|
||
docker compose logs --tail 100
|
||
|
||
# 按时间过滤
|
||
docker compose logs --since 30m
|
||
|
||
# 搜索特定内容
|
||
docker compose logs | grep "error"
|
||
```
|
||
|
||
### 9.3 日志清理
|
||
|
||
```bash
|
||
# 清理所有容器的日志
|
||
truncate -s 0 /var/lib/docker/containers/*/*-json.log
|
||
|
||
# 或使用 docker system df
|
||
docker system df
|
||
docker system prune
|
||
```
|
||
|
||
---
|
||
|
||
## 10. 安全加固
|
||
|
||
### 10.1 容器安全最佳实践
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: nginx:latest
|
||
|
||
# 不使用特权模式
|
||
# privileged: true # 禁止!
|
||
|
||
# 使用只读根文件系统
|
||
read_only: true
|
||
|
||
# 限制资源
|
||
mem_limit: 512m
|
||
cpus: 1.0
|
||
|
||
# 不使用 root 用户运行
|
||
user: "1000:1000"
|
||
|
||
# 安全选项
|
||
security_opt:
|
||
- no-new-privileges:true
|
||
|
||
# 网络隔离
|
||
networks:
|
||
- internal-network
|
||
```
|
||
|
||
### 10.2 网络安全
|
||
|
||
```yaml
|
||
services:
|
||
web:
|
||
image: nginx:latest
|
||
networks:
|
||
- frontend
|
||
ports:
|
||
- "80:80"
|
||
|
||
app:
|
||
image: node:18-alpine
|
||
networks:
|
||
- backend
|
||
# 不暴露端口,仅内部访问
|
||
|
||
db:
|
||
image: postgres:16
|
||
networks:
|
||
- backend
|
||
# 不暴露端口,仅内部访问
|
||
|
||
networks:
|
||
frontend:
|
||
driver: bridge
|
||
backend:
|
||
driver: bridge
|
||
```
|
||
|
||
### 10.3 敏感信息管理
|
||
|
||
#### 使用 .env 文件
|
||
|
||
```bash
|
||
# 创建 .env 文件
|
||
cat > .env << EOF
|
||
DB_PASSWORD=secret123
|
||
API_KEY=your-api-key
|
||
EOF
|
||
|
||
# 在 docker-compose.yaml 中引用
|
||
```
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: node:18-alpine
|
||
env_file:
|
||
- .env
|
||
environment:
|
||
- DB_PASSWORD # 从 .env 读取
|
||
```
|
||
|
||
#### 使用 Docker Secrets(Swarm 模式)
|
||
|
||
```yaml
|
||
services:
|
||
db:
|
||
image: postgres:16
|
||
secrets:
|
||
- db_password
|
||
|
||
secrets:
|
||
db_password:
|
||
file: ./db_password.txt
|
||
```
|
||
|
||
---
|
||
|
||
## 11. 自动化维护脚本
|
||
|
||
### 11.1 自动备份脚本
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# 文件名:backup.sh
|
||
# 用途:备份 Docker Compose 项目的所有数据
|
||
|
||
# 配置
|
||
PROJECT_NAME="myapp"
|
||
BACKUP_DIR="/opt/backups/$PROJECT_NAME"
|
||
DATE=$(date +%Y%m%d_%H%M%S)
|
||
KEEP_DAYS=7
|
||
|
||
# 创建备份目录
|
||
mkdir -p "$BACKUP_DIR"
|
||
|
||
# 获取项目路径
|
||
COMPOSE_DIR=$(dirname "$(find /opt -name "docker-compose.yaml" -path "*$PROJECT_NAME*" 2>/dev/null | head -1)")
|
||
cd "$COMPOSE_DIR" || exit 1
|
||
|
||
# 备份数据卷
|
||
for volume in $(docker compose config --volumes 2>/dev/null | grep -v "^volume-"); do
|
||
echo "正在备份卷: $volume"
|
||
docker run --rm \
|
||
-v ${PROJECT_NAME}_${volume}:/source \
|
||
-v "$BACKUP_DIR":/backup \
|
||
alpine \
|
||
tar czf "/backup/${volume}_${DATE}.tar.gz" -C /source .
|
||
done
|
||
|
||
# 备份配置文件
|
||
cp docker-compose.yaml "$BACKUP_DIR/docker-compose_${DATE}.yaml"
|
||
cp -r .env "$BACKUP_DIR/.env_${DATE}" 2>/dev/null
|
||
|
||
# 清理旧备份
|
||
find "$BACKUP_DIR" -name "*_${DATE}.tar.gz" -mtime +$KEEP_DAYS -delete
|
||
|
||
echo "✓ 备份完成: $DATE"
|
||
```
|
||
|
||
### 11.2 定时清理脚本
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# 文件名:clean.sh
|
||
# 用途:清理未使用的 Docker 资源
|
||
|
||
# 清理停止的容器
|
||
docker container prune -f
|
||
|
||
# 清理未使用的镜像
|
||
docker image prune -f
|
||
|
||
# 清理未使用的网络
|
||
docker network prune -f
|
||
|
||
# 清理构建缓存
|
||
docker builder prune -f
|
||
|
||
# 清理所有未使用的资源
|
||
docker system prune -f
|
||
|
||
# 设置日志大小限制
|
||
LOG_DIR="/var/lib/docker/containers"
|
||
MAX_SIZE="10M"
|
||
|
||
for log in $(find $LOG_DIR -name "*-json.log"); do
|
||
size=$(stat -f%z "$log" 2>/dev/null || stat -c%s "$log" 2>/dev/null)
|
||
if [ "$size" -gt 10485760 ]; then
|
||
echo "截断日志文件: $log"
|
||
truncate -s "$MAX_SIZE" "$log"
|
||
fi
|
||
done
|
||
|
||
echo "✓ 清理完成"
|
||
```
|
||
|
||
### 11.3 健康检查脚本
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# 文件名:health_check.sh
|
||
# 用途:检查所有服务健康状态
|
||
|
||
COMPOSE_DIR="/opt/myapp" # 修改为你的项目路径
|
||
cd "$COMPOSE_DIR" || exit 1
|
||
|
||
echo "=== 服务状态检查 ==="
|
||
docker compose ps
|
||
|
||
echo ""
|
||
echo "=== 健康检查 ==="
|
||
|
||
# 检查每个服务
|
||
for service in $(docker compose config --services); do
|
||
status=$(docker compose ps $service | tail -1 | awk '{print $4}')
|
||
|
||
if [ "$status" = "Up" ]; then
|
||
# 检查健康状态
|
||
health=$(docker inspect --format='{{if .State.Health}}{{.State.Health.Status}}{{else}}no-healthcheck{{end}}' $service)
|
||
|
||
if [ "$health" = "healthy" ] || [ "$health" = "no-healthcheck" ]; then
|
||
echo "✓ $service 运行正常"
|
||
else
|
||
echo "✗ $service 健康检查失败: $health"
|
||
docker compose logs --tail=20 $service
|
||
fi
|
||
else
|
||
echo "✗ $service 已停止: $status"
|
||
echo " 尝试重启..."
|
||
docker compose restart $service
|
||
fi
|
||
done
|
||
|
||
echo ""
|
||
echo "=== 资源使用 ==="
|
||
docker stats --no-stream
|
||
```
|
||
|
||
### 11.4 定时任务配置(crontab)
|
||
|
||
```bash
|
||
# 编辑 crontab
|
||
crontab -e
|
||
|
||
# 添加以下任务(每天凌晨 2 点备份)
|
||
0 2 * * * /opt/scripts/backup.sh >> /opt/logs/backup.log 2>&1
|
||
|
||
# 每周日凌晨 3 点清理
|
||
0 3 * * 0 /opt/scripts/clean.sh >> /opt/logs/clean.log 2>&1
|
||
|
||
# 每小时健康检查
|
||
0 * * * * /opt/scripts/health_check.sh >> /opt/logs/health.log 2>&1
|
||
```
|
||
|
||
---
|
||
|
||
## 12. 常见问题与排查
|
||
|
||
### 12.1 容器启动失败
|
||
|
||
**错误信息**:`Cannot start service xxx: network not found`
|
||
|
||
**可能原因**:
|
||
- 网络被删除
|
||
- 网络配置错误
|
||
|
||
**解决步骤**:
|
||
```bash
|
||
# 1. 检查网络状态
|
||
docker network ls
|
||
|
||
# 2. 重新创建网络
|
||
docker network create app-network
|
||
|
||
# 3. 重新启动服务
|
||
docker compose down
|
||
docker compose up -d
|
||
```
|
||
|
||
### 12.2 端口冲突
|
||
|
||
**错误信息**:`Bind for 0.0.0.0:80: unexpected address (error during binding)`
|
||
|
||
**可能原因**:
|
||
- 端口已被其他程序占用
|
||
|
||
**解决步骤**:
|
||
```bash
|
||
# Windows: 查看端口占用
|
||
netstat -ano | findstr :80
|
||
|
||
# Linux: 查看端口占用
|
||
sudo lsof -i :80
|
||
|
||
# 杀死占用进程或更换端口
|
||
```
|
||
|
||
### 12.3 权限问题
|
||
|
||
**错误信息**:`Permission denied`
|
||
|
||
**可能原因**:
|
||
- 宿主机目录权限不足
|
||
- SELinux 或 AppArmor 限制
|
||
|
||
**解决步骤**:
|
||
```bash
|
||
# Linux: 修改目录权限
|
||
sudo chown -R $(id -u):$(id -g) ./data
|
||
|
||
# 添加 SELinux 策略(如果启用)
|
||
chcon -R -t svirt_sandbox_file_t ./data
|
||
|
||
# 或者在 docker-compose.yaml 中禁用
|
||
security_opt:
|
||
- apparmor:unconfined
|
||
```
|
||
|
||
### 12.4 内存溢出(OOM)
|
||
|
||
**错误信息**:`Killed` 或容器被 OOM
|
||
|
||
**解决步骤**:
|
||
```yaml
|
||
# 在 docker-compose.yaml 中添加资源限制
|
||
services:
|
||
app:
|
||
mem_limit: 512m
|
||
memswap_limit: 512m
|
||
# 调整 JVM 堆内存(Java 应用)
|
||
environment:
|
||
- JVM_OPTS=-Xmx256m
|
||
```
|
||
|
||
### 12.5 网络通信问题
|
||
|
||
**问题**:容器之间无法通信
|
||
|
||
**排查步骤**:
|
||
```bash
|
||
# 1. 检查网络
|
||
docker network inspect app-network
|
||
|
||
# 2. 测试网络连通性
|
||
docker compose exec app ping db
|
||
|
||
# 3. 检查 DNS 解析
|
||
docker compose exec app nslookup db
|
||
|
||
# 4. 查看日志
|
||
docker compose logs app
|
||
```
|
||
|
||
---
|
||
|
||
## 13. 性能优化建议
|
||
|
||
### 13.1 镜像优化
|
||
|
||
```dockerfile
|
||
# 使用多阶段构建减小镜像大小
|
||
FROM node:18-alpine AS builder
|
||
WORKDIR /app
|
||
COPY package*.json ./
|
||
RUN npm ci --only=production
|
||
|
||
FROM node:18-alpine
|
||
WORKDIR /app
|
||
COPY --from=builder /app/node_modules ./node_modules
|
||
COPY . .
|
||
CMD ["node", "app.js"]
|
||
|
||
# 使用 alpine 变体减小基础镜像大小
|
||
FROM nginx:alpine
|
||
FROM python:3.12-alpine
|
||
FROM node:18-alpine
|
||
```
|
||
|
||
### 13.2 资源限制调优
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
# 根据实际需求设置合理的资源限制
|
||
mem_limit: "512m" # 留出足够余量给系统和 Docker
|
||
cpus: "1.0"
|
||
# 对于 Java 应用,堆内存不应超过容器内存的 75%
|
||
environment:
|
||
- JVM_OPTS=-Xmx384m
|
||
```
|
||
|
||
### 13.3 日志优化
|
||
|
||
```yaml
|
||
services:
|
||
app:
|
||
logging:
|
||
driver: "json-file"
|
||
options:
|
||
max-size: "10m"
|
||
max-file: "3"
|
||
compress: "true"
|
||
```
|
||
|
||
---
|
||
|
||
## 14. 监控与日志聚合
|
||
|
||
### 14.1 使用 Portainer 管理容器
|
||
|
||
```yaml
|
||
version: "3.8"
|
||
|
||
services:
|
||
portainer:
|
||
image: portainer/portainer-ce:latest
|
||
container_name: portainer
|
||
restart: unless-stopped
|
||
ports:
|
||
- "9000:9000"
|
||
volumes:
|
||
- /var/run/docker.sock:/var/run/docker.sock
|
||
- portainer-data:/data
|
||
|
||
volumes:
|
||
portainer-data:
|
||
```
|
||
|
||
访问 `http://your-server:9000` 即可通过 Web UI 管理 Docker。
|
||
|
||
### 14.2 使用 GRAYLOG 日志聚合
|
||
|
||
(详见专门的日志聚合指南)
|
||
|
||
---
|
||
|
||
## 15. 总结
|
||
|
||
本文档涵盖了 Docker 部署的核心知识点:
|
||
|
||
| 章节 | 核心内容 |
|
||
|------|----------|
|
||
| 基础概念 | 镜像、容器、仓库的原理 |
|
||
| 环境准备 | Windows/Linux 安装配置 |
|
||
| 核心操作 | 镜像、容器、网络的常用命令 |
|
||
| Compose 详解 | YAML 配置语法详解 |
|
||
| 实战示例 | Nginx+PHP、PostgreSQL+应用 |
|
||
| 数据持久化 | 命名卷、绑定挂载、备份恢复 |
|
||
| 健康检查 | 配置与依赖管理 |
|
||
| 日志管理 | 日志配置与清理 |
|
||
| 安全加固 | 网络隔离、权限控制 |
|
||
| 自动化脚本 | 备份、清理、健康检查 |
|
||
| 常见问题 | 故障排查与解决 |
|
||
| 性能优化 | 镜像、资源、日志优化 |
|
||
|
||
**推荐学习路径**:
|
||
1. 先理解 Docker 基础概念
|
||
2. 动手实践基本操作命令
|
||
3. 深入学习 Docker Compose
|
||
4. 理解数据持久化和网络安全
|
||
5. 实践自动化维护
|
||
|
||
---
|
||
|
||
**延伸阅读**:
|
||
- [Docker 官方文档](https://docs.docker.com/)
|
||
- [Docker Compose 官方文档](https://docs.docker.com/compose/)
|
||
- [最佳实践指南](https://docs.docker.com/develop/)
|
||
|
||
---
|
||
|
||
*本文档由人工智能协会整理*
|
||
*2026年3月* |