𝑻𝒆𝒏𝑪𝒍𝒂𝒘正在头脑风暴···
𝑻𝒆𝒏𝑲𝒊𝑺𝒆𝒀𝒂の𝑨𝒈𝒆𝒏𝒕助手
𝑻𝒆𝒏-𝒇𝒍𝒂𝒔𝒉

Docker入门教程:容器化部署完全指南

Docker是现代应用开发中不可或缺的容器化技术,它让应用的构建、分发和运行变得前所未有的简单。本教程将从零开始,带你全面掌握Docker的使用。

目录


什么是Docker?

Docker简介

Docker是一个开源的容器化平台,它将应用程序及其依赖打包到一个轻量级、可移植的容器中。通过容器化技术,开发者可以在任何环境中保持应用的一致性。

Docker的核心优势:

  • 🚀 一致性开发:开发、测试、生产环境完全一致
  • 快速部署:容器启动速度快,秒级启动
  • 📦 环境隔离:每个容器独立运行,互不干扰
  • 🔄 版本管理:支持版本控制和回滚
  • 🔧 微服务友好:非常适合微服务架构

Docker与虚拟化的区别

特性Docker容器传统虚拟机
启动速度秒级分钟级
资源占用小(MB级别)大(GB级别)
隔离级别进程级系统级
性能损耗接近原生有性能损耗
镜像大小
graph LR
A[物理机] --> B[Docker Host]
B --> C[Docker Engine]
C --> D[容器1]
C --> E[容器2]
C --> F[容器3]

D --> G[应用程序]
D --> H[系统依赖]
D --> I[系统库]

E --> J[应用程序]
E --> K[系统依赖]
E --> L[系统库]

F --> M[应用程序]
F --> N[系统依赖]
F --> O[系统库]

Docker核心概念

1. 镜像(Image)

镜像是一个只读的模板,包含运行应用程序所需的所有内容:代码、运行时、系统工具、系统库等。

镜像特点:

  • 分层存储,每个只读层都是只读的
  • 不可变性,一旦创建就不会改变
  • 可通过命令创建和修改

2. 容器(Container)

容器是镜像的运行实例,是轻量级、可执行的软件包。

容器特点:

  • 从镜像创建
  • 可写层
  • 与主机隔离
  • 可启动、停止、删除

3. 仓库(Repository)

仓库用于存储和分发镜像,Docker Hub是最大的公开仓库。

仓库类型:

  • 公共仓库:Docker Hub,任何人都可以访问
  • 私有仓库:私有服务器,仅供特定人员访问
  • 镜像仓库:Harbor、Registry等

4. Dockerfile

Dockerfile是用于构建镜像的文本文件,包含了一系列命令和指令。

概念关系图

graph TD
A[镜像 Image] --> B[容器 Container]
B --> C[运行中的应用]
D[Dockerfile] --> A
E[构建命令] --> D
F[仓库 Repository] --> G[拉取 Pull]
F --> H[推送 Push]
G --> A
A --> F

环境安装

系统要求

在开始之前,确保你的系统满足以下要求:

操作系统版本要求架构
Windows10 64-bit Pro/Enterprisex86_64
macOS10.14+x86_64, Apple Silicon
LinuxUbuntu 18.04+, CentOS 7+x86_64, ARM

Windows安装

方法一:使用Docker Desktop

  1. 下载Docker Desktop

    # 访问官网下载
    https://www.docker.com/products/docker-desktop
  2. 安装步骤

    • 双击下载的.exe文件
    • 按照安装向导完成安装
    • 重启计算机
  3. 验证安装

    # 打开PowerShell,运行以下命令
    docker --version
    docker run hello-world

方法二:使用包管理器

  1. 配置包源
    # 设置包源
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

    # 使用chocolatey安装
    choco install docker-desktop

macOS安装

使用Homebrew安装

# 安装Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 安装Docker Desktop
brew install --cask docker

# 启动Docker Desktop
open /Applications/Docker.app

# 验证安装
docker --version

手动安装

  1. 下载Docker Desktop for Mac
  2. 将Docker.app拖拽到Applications文件夹
  3. 启动Docker Desktop
  4. 等待Docker完全启动

Linux安装

Ubuntu/Debian安装

# 更新包列表
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组
sudo usermod -aG docker $USER

# 验证安装
docker --version
docker run hello-world

CentOS/RHEL安装

# 安装yum-utils
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 -y docker-ce docker-ce-cli containerd.io

# 启动Docker
sudo systemctl start docker
sudo systemctl enable docker

# 添加用户到docker组
sudo usermod -aG docker $USER

# 验证安装
docker --version
docker run hello-world

配置加速镜像

配置国内镜像源

# 创建配置目录
sudo mkdir -p /etc/docker

# 创建配置文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
],
"experimental": true,
"storage-driver": "overlay2"
}
EOF

# 重启Docker
sudo systemctl restart docker

Docker Compose安装

# 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

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

# 验证安装
docker-compose --version

基本操作

镜像管理

搜索镜像

# 搜索官方镜像
docker search nginx

# 搜索带关键词的镜像
docker search --filter is-official=true nginx

# 搜索stars多的镜像
docker search --filter stars=1000 nginx

拉取镜像

# 拉取最新版本
docker pull nginx

# 拉取指定版本
docker pull nginx:1.21

# 拉取镜像并重命名
docker pull nginx:latest --tag my-nginx

查看镜像

# 列出所有镜像
docker images
docker image ls

# 查看镜像详细信息
docker image inspect nginx

# 查看镜像历史
docker history nginx

删除镜像

# 删除单个镜像
docker rmi nginx:1.21

# 删除多个镜像
docker rmi nginx nginx:alpine

# 强制删除(即使容器正在使用)
docker rmi -f nginx

# 清理悬空镜像
docker image prune

# 清理所有未使用的镜像
docker image prune -a

容器管理

运行容器

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

# 运行后台容器
docker run -d --name my-nginx nginx

# 运行并暴露端口
docker run -d --name my-web -p 8080:80 nginx

# 运行并挂载卷
docker run -d --name my-app -v /data:/app/data nginx

# 运行并设置环境变量
docker run -d --name my-db -e MYSQL_ROOT_PASSWORD=root mysql:8

查看容器

# 列出运行中的容器
docker ps

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

# 查看容器详细信息
docker inspect my-nginx

# 查看容器日志
docker logs my-nginx

# 查看实时日志
docker logs -f my-nginx

停止和启动容器

# 停止容器
docker stop my-nginx

# 启动容器
docker start my-nginx

# 重启容器
docker restart my-nginx

# 停止所有容器
docker stop $(docker ps -q)

# 启动所有容器
docker start $(docker ps -aq)

删除容器

# 删除单个容器
docker rm my-nginx

# 删除多个容器
docker rm my-app my-db

# 强制删除正在运行的容器
docker rm -f my-nginx

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

# 清理所有容器
docker rm -f $(docker ps -aq)

数据管理

数据卷

# 创建数据卷
docker volume create my-data

# 查看数据卷
docker volume ls

# 查看数据卷详情
docker volume inspect my-data

# 删除数据卷
docker volume rm my-data

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

容器间数据共享

# 创建共享数据卷
docker run -d --name shared-data -v shared-data:/data busybox

# 使用共享数据卷
docker run -d --name app1 -v shared-data:/app/data nginx
docker run -d --name app2 -v shared-data:/app/data nginx

网络管理

查看网络

# 查看网络列表
docker network ls

# 查看网络详情
docker network inspect bridge

创建自定义网络

# 创建桥接网络
docker network create --driver bridge my-network

# 创建自定义网络
docker network create --driver overlay --subnet=192.168.1.0/24 my-network

# 将容器连接到网络
docker run -d --name app1 --network my-network nginx
docker run -d --name app2 --network my-network nginx

网络连接管理

# 连接容器到网络
docker network connect my-network my-nginx

# 断开网络连接
docker network disconnect my-network my-nginx

Dockerfile编写

Dockerfile基础语法

# 指定基础镜像
FROM ubuntu:20.04

# 设置维护者信息
LABEL maintainer="yourname@example.com"

# 设置工作目录
WORKDIR /app

# 复制文件
COPY . .

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

# 安装Python依赖
RUN pip3 install --no-cache-dir -r requirements.txt

# 设置环境变量
ENV PYTHONUNBUFFERED 1
ENV APP_PORT 8000

# 暴露端口
EXPOSE 8000

# 运行命令
CMD ["python3", "app.py"]

常用指令详解

1. FROM指令

# 使用基础镜像
FROM ubuntu:20.04
FROM python:3.9-slim
FROM node:16-alpine

# 使用多阶段构建
FROM python:3.9 as builder
# ... 构建步骤 ...

FROM python:3.9-slim
# 复制构建结果
COPY --from=builder /app/build /app

2. RUN指令

# 执行命令
RUN apt-get update
RUN apt-get install -y python3 python3-pip

# 使用&&连接多个命令
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*

# 使用shell形式
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "python3"]

3. COPY和ADD指令

# 复制文件
COPY . .
COPY requirements.txt /app/
COPY --from=builder /app/build /app

# ADD指令(支持自动解压)
ADD archive.tar.gz /app/
ADD https://example.com/file.txt /app/

4. CMD和ENTRYPOINT

# CMD指令(可被覆盖)
CMD ["python3", "app.py"]
CMD ["nginx", "-g", "daemon off;"]

# ENTRYPOINT指令(不可被覆盖)
ENTRYPOINT ["python3"]
CMD ["app.py"]

# 结合使用
ENTRYPOINT ["npm"]
CMD ["start"]

5. ENV指令

# 设置环境变量
ENV PYTHON_VERSION=3.9
ENV NODE_ENV=production
ENV APP_PORT=3000

# 清除环境变量
ENV NODE_ENV=

6. ARG指令

# 构建时变量
ARG BUILD_DATE
ARG VERSION=1.0
ARG IMAGE_NAME=my-app

# 使用ARG
LABEL build_date=${BUILD_DATE}
LABEL version=${VERSION}

7. EXPOSE和VOLUME

# 暴露端口
EXPOSE 80
EXPOSE 443

# 声明数据卷
VOLUME ["/data", "/logs"]

多阶段构建示例

# 第一阶段:构建
FROM node:16-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 第二阶段:生产环境
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

最佳实践Dockerfile

# 使用官方基础镜像
FROM python:3.9-slim

# 设置元数据
LABEL maintainer="team@example.com"
LABEL version="1.0.0"
LABEL description="My Python Application"

# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV APP_HOME=/app

# 创建应用目录
WORKDIR $APP_HOME

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

# 安装Python依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码
COPY . .

# 创建非root用户
RUN useradd --create-home --shell /bin/bash appuser && \
chown -R appuser:appuser $APP_HOME
USER appuser

# 暴露端口
EXPOSE 8000

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

# 启动命令
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "app:app"]

Docker Compose

Compose文件基础

# version: '3.8'  # 3.8版本支持最新特性
services:
web:
build: .
ports:
- "8080:80"
volumes:
- ./src:/app/src
environment:
- NODE_ENV=production
depends_on:
- db
networks:
- app-network

db:
image: postgres:13
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypassword
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- app-network

redis:
image: redis:6-alpine
ports:
- "6379:6379"
networks:
- app-network

volumes:
postgres-data:

networks:
app-network:
driver: bridge

常用指令详解

1. 服务配置

services:
web:
# 构建镜像
build:
context: .
dockerfile: Dockerfile
args:
VERSION: 1.0

# 使用镜像
image: nginx:latest

# 容器名称
container_name: my-web-app

# 端口映射
ports:
- "8080:80"
- "443:443"

# 挂载卷
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./logs:/var/log/nginx

# 环境变量
environment:
- NODE_ENV=production
- API_URL=http://backend:5000

# 环境文件
env_file:
- ./.env
- ./production.env

# 数据卷
volumes:
- app-data:/app/data

# 网络配置
networks:
- frontend
- backend

# 依赖服务
depends_on:
- backend
- database

# 健康检查
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3

# 重启策略
restart: unless-stopped

# 资源限制
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M

# 日志配置
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

2. 网络配置

networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16

backend:
driver: overlay
driver_opts:
encrypted: "true"

proxy:
external:
name: my-proxy-network

3. 数据卷配置

volumes:
app-data:
driver: local

database-data:
driver: local
driver_opts:
type: none
o: bind
device: /mnt/data/database

cache-data:
name: my-redis-cache
external: true

Compose常用命令

服务管理

# 启动服务
docker-compose up

# 后台启动
docker-compose up -d

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

# 停止服务
docker-compose down

# 停止并删除容器
docker-compose down --volumes

# 重启服务
docker-compose restart

# 查看服务状态
docker-compose ps

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

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

# 进入容器
docker-compose exec web bash

# 运行命令
docker-compose run --rm web npm install

多环境配置

# 开发环境
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up

# 生产环境
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up

# 查看配置
docker-compose config

# 验证配置
docker-compose config --quiet

实际项目示例

微服务架构

# docker-compose.yml
version: '3.8'

services:
api-gateway:
build: ./api-gateway
ports:
- "3000:3000"
environment:
- SERVICES_URL=http://auth:3001
networks:
- micro-network
depends_on:
- auth-service

auth-service:
build: ./auth-service
ports:
- "3001:3001"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/auth
- JWT_SECRET=your-secret-key
networks:
- micro-network
depends_on:
- db

user-service:
build: ./user-service
ports:
- "3002:3002"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/user
- REDIS_URL=redis://cache:6379
networks:
- micro-network
depends_on:
- db
- cache

product-service:
build: ./product-service
ports:
- "3003:3003"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/product
- REDIS_URL=redis://cache:6379
networks:
- micro-network
depends_on:
- db
- cache

db:
image: postgres:13
environment:
- POSTGRES_DB=app
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- micro-network

cache:
image: redis:6-alpine
ports:
- "6379:6379"
networks:
- micro-network

# 监控服务
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
networks:
- monitoring-network

grafana:
image: grafana/grafana:latest
ports:
- "3001:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
networks:
- monitoring-network
depends_on:
- prometheus

networks:
micro-network:
driver: bridge
monitoring-network:
driver: bridge

volumes:
postgres-data:

实战项目

项目一:Node.js Web应用

项目结构

node-docker-app/
├── src/
│ ├── app.js
│ ├── package.json
│ └── package-lock.json
├── Dockerfile
├── docker-compose.yml
├── .env
└── README.md

应用代码

// src/app.js
const express = require('express');
const { exec } = require('child_process');

const app = express();
const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
res.json({
message: 'Hello from Docker!',
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV || 'development'
});
});

app.get('/api/users', (req, res) => {
const users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
];
res.json(users);
});

app.get('/health', (req, res) => {
res.status(200).json({ status: 'healthy' });
});

app.listen(port, () => {
console.log(`Server running on port ${port}`);
});

Dockerfile

# 使用官方Node.js镜像
FROM node:16-alpine

# 设置工作目录
WORKDIR /app

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

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

# 复制应用代码
COPY src/ ./src/

# 暴露端口
EXPOSE 3000

# 设置环境变量
ENV NODE_ENV=production

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

# 启动应用
CMD ["node", "src/app.js"]

docker-compose.yml

version: '3.8'

services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
networks:
- app-network

# 监控服务
monitoring:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
networks:
- app-network

networks:
app-network:
driver: bridge

运行项目

# 构建镜像
docker build -t node-app .

# 运行容器
docker run -d --name node-app -p 3000:3000 node-app

# 使用docker-compose启动
docker-compose up -d

# 查看日志
docker-compose logs -f web

# 查看健康状态
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

# 停止并清理
docker-compose down

项目二:WordPress博客系统

docker-compose.yml

version: '3.8'

services:
wordpress:
image: wordpress:6.0
ports:
- "8080:80"
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=wordpress
- WORDPRESS_DB_PASSWORD=password
- WORDPRESS_DB_NAME=wordpress
- WORDPRESS_DEBUG=1
volumes:
- wordpress-data:/var/www/html
- ./custom-theme:/var/www/html/wp-content/themes/custom-theme
- ./plugins:/var/www/html/wp-content/plugins
depends_on:
- db
restart: unless-stopped
networks:
- wordpress-network

db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=password
volumes:
- mysql-data:/var/lib/mysql
- ./mysql-init:/docker-entrypoint-initdb.d
restart: unless-stopped
networks:
- wordpress-network

phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
ports:
- "8081:80"
environment:
- PMA_HOST=db
- PMA_USER=wordpress
- PMA_PASSWORD=password
depends_on:
- db
networks:
- wordpress-network

redis:
image: redis:6-alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
restart: unless-stopped
networks:
- wordpress-network

networks:
wordpress-network:
driver: bridge

volumes:
wordpress-data:
mysql-data:
redis-data:

运行项目

# 启动所有服务
docker-compose up -d

# 访问WordPress
# http://localhost:8080
# 用户名:admin
# 密码:在docker-compose logs中查找

# 访问phpMyAdmin
# http://localhost:8081
# 用户名:wordpress
# 密码:password

# 查看所有服务
docker-compose ps

# 停止所有服务
docker-compose down

# 备份数据
docker-compose exec db mysqldump -u wordpress -ppassword wordpress > backup.sql

项目三:监控与日志系统

项目结构

monitoring-system/
├── prometheus/
│ ├── prometheus.yml
│ └── Dockerfile
├── grafana/
│ ├── provisioning/
│ │ ├── dashboards/
│ │ └── datasources/
│ └── Dockerfile
├── elasticsearch/
│ └── Dockerfile
├── logstash/
│ └── Dockerfile
├── kibana/
│ └── Dockerfile
└── docker-compose.yml

Prometheus配置

# prometheus/prometheus.yml
global:
scrape_interval: 15s

scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']

- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']

- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']

- job_name: 'docker'
static_configs:
- targets: ['docker:9323']

docker-compose.yml

version: '3.8'

services:
prometheus:
build: ./prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
restart: unless-stopped
networks:
- monitoring-network

grafana:
build: ./grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-storage:/var/lib/grafana
restart: unless-stopped
networks:
- monitoring-network

node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
restart: unless-stopped
networks:
- monitoring-network

cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
ports:
- "8080:8080"
volumes:
- /:/rootfs
- /var/run:/var/run
- /sys:/sys
- /var/lib/docker:/var/lib/docker
restart: unless-stopped
networks:
- monitoring-network

elasticsearch:
build: ./elasticsearch
ports:
- "9200:9200"
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
restart: unless-stopped
networks:
- monitoring-network

logstash:
build: ./logstash
ports:
- "5000:5000"
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline
depends_on:
- elasticsearch
restart: unless-stopped
networks:
- monitoring-network

kibana:
build: ./kibana
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
- elasticsearch
restart: unless-stopped
networks:
- monitoring-network

networks:
monitoring-network:
driver: bridge

volumes:
grafana-storage:
elasticsearch-data:

最佳实践

Dockerfile最佳实践

1. 选择合适的基础镜像

# ✅ 使用官方镜像
FROM node:16-alpine
FROM python:3.9-slim

# ✅ 多阶段构建
FROM node:16 as builder
RUN npm ci && npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html

# ❌ 避免使用过大镜像
FROM ubuntu:20.04

2. 合理使用缓存

# ✅ 分层,有效利用缓存
FROM node:16-alpine
WORKDIR /app

# 复制依赖文件,先复制它们
COPY package*.json ./
RUN npm ci --only=production

# 然后再复制应用代码
COPY . .

# ❌ 一次性复制所有文件
FROM node:16-alpine
WORKDIR /app
COPY . .
RUN npm ci --only=production

3. 最小化镜像大小

# ✅ 清理缓存和临时文件
RUN apt-get update && \
apt-get install -y \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*

# ✅ 使用--no-cache-dir
RUN pip install --no-cache-dir -r requirements.txt

# ✅ 清理不必要的文件
RUN apt-get clean && \
rm -rf /var/cache/apt/* && \
rm -rf /tmp/*

4. 安全实践

# ✅ 使用非root用户
FROM node:16-alpine
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
USER nextjs

# ✅ 多阶段构建减少攻击面
FROM python:3.9-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt

FROM python:3.9-slim
COPY --from=builder /root/.local /home/app/.local
USER app

Compose最佳实践

1. 环境分离

# 开发环境 - docker-compose.dev.yml
version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"
environment:
- NODE_ENV=development

# 生产环境 - docker-compose.prod.yml
version: '3.8'
services:
web:
build: .
ports:
- "80:3000"
environment:
- NODE_ENV=production
restart: unless-stopped

2. 资源限制

services:
app:
image: my-app
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M

3. 日志管理

services:
app:
image: my-app
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

安全最佳实践

1. 镜像安全扫描

# 使用Trivy进行安全扫描
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasecurity/trivy:latest image my-image

# 或扫描构建中的镜像
FROM python:3.9-slim
RUN apt-get update && \
apt-get install -y \
curl && \
curl -sSf https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list && \
apt-get update && \
apt-get install -y google-chrome-stable && \
rm -rf /var/lib/apt/lists/* && \
apt-get purge -y --auto-remove curl && \
rm -rf /root/.cache

2. 运行时安全

# 使用非root用户运行
docker run --user 1000:1000 my-image

# 限制权限
docker run --read-only --tmpfs /tmp my-image

# 使用安全选项
docker run --cap-drop ALL --cap-add CHOWN my-image

3. 网络安全

# 创建自定义网络
docker network create --driver bridge my-network

# 使用网络隔离
docker run --network my-network my-image

# 限制网络访问
docker run --publish 80:80 --publish 443:443 my-image

常见问题

1. 安装问题

问题:权限被拒绝

# 解决方案:添加用户到docker组
sudo usermod -aG docker $USER
newgrp docker

# 或者使用sudo
sudo docker run hello-world

问题:Docker服务启动失败

# 查看服务状态
sudo systemctl status docker

# 重启Docker服务
sudo systemctl restart docker

# 查看详细日志
sudo journalctl -u docker

问题:端口被占用

# 查看端口占用
netstat -tulpn | grep :8080
lsof -i :8080

# 或者更改端口
docker run -d -p 8081:80 nginx

2. 运行时问题

问题:容器启动失败

# 查看容器状态
docker ps -a

# 查看容器日志
docker logs container-name

# 进入容器调试
docker exec -it container-name bash

问题:文件权限问题

# 挂载时指定权限
docker run -v /host/path:/container/path:ro my-image

# 或者使用--user选项
docker run --user $(id -u):$(id -g) -v /host/path:/container/path my-image

问题:网络连接问题

# 创建自定义网络
docker network create my-network

# 连接容器到网络
docker network connect my-network container-name

# 检查网络连接
docker network inspect my-network

3. 构建问题

问题:构建失败

# 查看构建日志
docker build --no-cache .

# 或者使用详细输出
docker build --progress=plain .

问题:镜像大小过大

# 使用多阶段构建
FROM node:16 as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html

问题:构建缓存问题

# 清理缓存
docker builder prune

# 或者强制重新构建
docker build --no-cache -t my-image .

4. 性能问题

问题:容器运行缓慢

# 检查资源使用
docker stats

# 限制资源使用
docker run --cpus=0.5 --memory=512m my-image

# 使用--privileged(谨慎使用)
docker run --privileged my-image

问题:存储空间不足

# 清理未使用的镜像
docker image prune

# 清理未使用的容器
docker container prune

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

# 清理所有未使用资源
docker system prune -a

5. 生产环境问题

问题:容器无法连接外部服务

# 检查DNS配置
docker run --dns 8.8.8.8 my-image

# 或者使用网络模式
docker run --network host my-image

问题:日志量过大

# 配置日志驱动
docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 my-image

# 或者使用日志轮转
docker run --log-driver json-file --log-opt max-size="10m" --log-opt max-file="3" my-image

问题:数据持久化问题

# 使用命名数据卷
docker run -v my-volume:/app/data my-image

# 使用绑定挂载
docker run -v /host/path:/app/data my-image

# 备份数据
docker run --rm -v my-volume:/volume -v $(pwd):/backup alpine tar czf /backup/backup.tar -C /volume .

进阶学习

1. 高级网络配置

自定义网络驱动

# 创建自定义网络
docker network create --driver bridge --subnet=172.20.0.0/16 --gateway=172.20.0.1 my-network

# 使用网络隔离
docker run --network my-network my-image

跨主机网络

# 创建overlay网络
docker network create --driver overlay --subnet=172.20.0.0/24 my-overlay-network

# 使用跨主机网络
docker run --network my-overlay-network my-image

2. 安全加固

AppArmor配置

# 启用AppArmor
sudo aa-enforce /etc/apparmor.d/usr.bin.docker

# 创建安全配置
sudo nano /etc/apparmor.d/usr.bin.dockerd

SELinux配置

# 启用SELinux
sudo setenforce 1

# 创建安全策略
sudo semanage fcontext -a -t svirt_sandbox_file_t "/var/lib/docker(/.*)?"
sudo restorecon -R -v /var/lib/docker

3. 集群管理

Docker Swarm模式

# 初始化Swarm
docker swarm init

# 创建服务
docker service create --name web --publish 8080:80 nginx

# 扩展服务
docker service scale web=5

# 查看服务
docker service ls

Docker Compose在Swarm中运行

# docker-compose.yml
version: '3.8'
services:
web:
image: nginx
ports:
- "8080:80"
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure

4. 监控和日志

使用Prometheus监控

# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml

node-exporter:
image: prom/node-exporter
ports:
- "9100:9100"

使用ELK日志收集

# docker-compose.yml
version: '3.8'
services:
elasticsearch:
image: elasticsearch:7.10
ports:
- "9200:9200"

logstash:
image: logstash:7.10
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline

kibana:
image: kibana:7.10
ports:
- "5601:5601"

5. CI/CD集成

使用GitHub Actions

# .github/workflows/docker.yml
name: Docker Build and Push
on:
push:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: user/my-app:latest

使用Jenkins

// Jenkinsfile
pipeline {
agent any

stages {
stage('Build') {
steps {
sh 'docker build -t my-app:latest .'
}
}

stage('Test') {
steps {
sh 'docker run --rm my-app:latest npm test'
}
}

stage('Deploy') {
steps {
sh 'docker-compose up -d'
}
}
}
}

6. 容器编排

使用Kubernetes

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

使用Helm

# Chart.yaml
apiVersion: v2
name: my-app
description: A Helm chart for my application
version: 0.1.0

# values.yaml
replicaCount: 3
image:
repository: nginx
pullPolicy: IfNotPresent
tag: "1.14.2"

总结

学习路径建议

  1. 基础阶段(1-2周):

    • 掌握Docker基本概念和命令
    • 学会编写简单的Dockerfile
    • 熟悉Docker Compose基本使用
  2. 进阶阶段(2-3周):

    • 深入理解Dockerfile编写技巧
    • 掌握多阶段构建优化
    • 学习Docker Compose高级配置
  3. 实践阶段(3-4周):

    • 完成实际项目部署
    • 实现监控和日志系统
    • 集成CI/CD流程
  4. 高级阶段(持续):

    • 学习集群管理
    • 掌握安全加固
    • 研究容器编排技术

核心要点回顾

  1. 容器化理念:轻量级、可移植、一致性
  2. 镜像管理:构建、推送、拉取、优化
  3. 容器生命周期:运行、停止、重启、删除
  4. 数据持久化:卷、挂载、共享
  5. 网络配置:桥接、覆盖、自定义网络
  6. 编排工具:Docker Compose、Swarm、Kubernetes
  7. 安全实践:最小权限、安全扫描、网络隔离
  8. 监控日志:Prometheus、ELK、集中日志

发展方向建议

  • DevOps工程师:掌握CI/CD流水线和容器编排
  • 云原生开发:学习Kubernetes和微服务架构
  • 平台工程:构建内部容器平台和工具链
  • 安全专家:深入研究容器安全和合规要求

Docker作为容器化技术的核心,已经成为现代应用开发的基石。持续学习和实践,你会在这个充满机遇的领域中获得成功!


最后更新:2026年5月14日
分类:Docker | 容器技术 | DevOps | 部署运维 | 云原生