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

Docker实战指南:从入门到精通

记得刚接触Docker的时候,我就被它的魅力深深吸引。想象一下,你开发的应用在任何环境里都能保持一致,再也不用经历”在我电脑上明明是好的”这种尴尬场面。今天,我想把这些年的实战经验分享给你,帮你真正掌握Docker这个强大的工具。

目录


初识Docker

什么是Docker?

如果你对容器技术还不熟悉,没关系,我用大白话给你解释一下。

简单来说,Docker就像一个标准化的集装箱。你开发的应用和它的依赖(各种库、环境配置等)打包在这个集装箱里,这个集装箱就可以在任何码头(服务器、本地机器等)都能正常运作,不会出现”水土不服”的情况。

为什么我们需要Docker?

想象一下这个场景:

  • 你的开发环境:Ubuntu 20.04,Python 3.8,PostgreSQL 12
  • 测试环境:CentOS 7,Python 3.7,PostgreSQL 10
  • 生产环境:Ubuntu 18.04,Python 3.8,PostgreSQL 12

没有Docker之前,你可能会遇到:

  • 开发环境能跑,测试环境报错
  • 本地运行正常,服务器上就是不行
  • 依赖版本冲突,各种诡异的错误

有了Docker之后,这些问题基本就消失了,因为每个环境都是完全一致的

Docker vs 传统虚拟化

传统的虚拟机就像每个虚拟机都运行一个完整的操作系统,而Docker容器则是共享宿主机的内核,只隔离进程和文件系统。

特性Docker容器虚拟机
启动时间秒级分钟级
资源占用小(MB级)大(GB级)
性能接近原生有损耗
隔离性进程级系统级
graph TD
A[宿主机] --> B[Docker Engine]
B --> C[容器1]
B --> D[容器2]
B --> E[容器3]

C --> F[应用+依赖]
D --> G[应用+依赖]
E --> H[应用+依赖]

安装与环境配置

Windows安装

说实话,Windows上的Docker安装曾经是个噩梦,但现在Docker Desktop已经做得相当不错了。

方法一:Docker Desktop(推荐)

  1. 下载安装包

    • 访问Docker官网
    • 下载Windows版本(需要Windows 10 Pro/Enterprise)
  2. 安装过程

    • 双击安装文件
    • 一路点击”下一步”(保持默认设置)
    • 安装完成后重启电脑
  3. 验证安装

    # 打开PowerShell或命令提示符
    docker --version
    docker run hello-world

常见问题:权限错误

如果遇到”permission denied”错误,右键点击PowerShell,选择”以管理员身份运行”。

# 或者将用户添加到docker组(需要重启)
net localgroup docker-users "你的用户名" /add

macOS安装

macOS用户有几种选择,但最简单的是使用Homebrew。

使用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完全启动后验证
docker --version

小提示

Docker Desktop在macOS上需要系统权限,可能会弹出一个窗口让你确认,一定要允许哦!

Linux安装

Linux用户的福音来了,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)
sudo usermod -aG docker $USER
newgrp docker # 立即生效

# 第七步:验证安装
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
newgrp docker

# 验证安装
docker run hello-world

配置国内镜像加速

默认从Docker Hub拉取镜像很慢,特别是国内用户,一定要配置镜像加速。

创建配置文件

# 创建配置目录(如果没有)
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信息
docker info

# 应该能看到Registry Mirrors部分

Docker Compose安装

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

基本操作入门

镜像操作

镜像就像蛋糕的配方,包含了制作蛋糕的所有材料。镜像是一个只读的模板。

搜索镜像

# 搜索nginx镜像
docker search nginx

# �搜索官方镜像(更安全)
docker search --filter is-official=true nginx

# 搜索星星多的镜像(通常质量好)
docker search --filter stars=1000 nginx

拉取镜像

# 拉取最新版本
docker pull nginx

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

# 拉取特定版本的alpine(更小)
docker pull nginx:1.21-alpine

查看镜像

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

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

# 查看镜像历史
docker history nginx

删除镜像

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

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

# 删除所有镜像(谨慎使用)
docker rmi $(docker images -q)

# 清理悬空镜像
docker image prune

容器操作

容器是镜像的实例,是真正运行的应用。

运行容器

这是最常用的命令,有几个重要参数:

# 运行一个交互式容器(测试用)
docker run -it ubuntu /bin/bash

# 运行一个后台容器
docker run -d nginx

# 运行并映射端口(最常用)
docker run -d --name my-web -p 8080:80 nginx

# 运行并挂载目录(开发时很有用)
docker run -d --name my-app -v /path/to/code:/app nginx

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

参数解释

  • -d: 后台运行
  • -p 8080:80: 将宿主机的8080端口映射到容器的80端口
  • -v: 挂载卷
  • -e: 设置环境变量
  • --name: 给容器起个名字

查看容器

# 查看运行中的容器
docker ps

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

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

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

# 查看实时日志(很有用)
docker logs -f my-web

管理容器

# 停止容器
docker stop my-web

# 启动容器
docker start my-web

# 重启容器
docker restart my-web

# 进入容器(调试用)
docker exec -it my-web bash

# 删除容器
docker rm my-web

# 强制删除运行的容器
docker rm -f my-web

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

数据管理

容器默认是临时的,数据需要通过持久化来保存。

数据卷(Volumes)

数据卷是Docker管理的数据存储,最推荐使用。

# 创建数据卷
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 my-app -v my-data:/app/data nginx

# 多个容器共享数据卷
docker run -d --name app1 -v shared-data:/app/data nginx
docker run -d --name app2 -v shared-data:/app/data nginx

绑定挂载(Bind Mounts)

直接挂载宿主机的目录。

# 挂载当前目录到容器
docker run -d -v "$(pwd)":/app nginx

# 挂载配置文件
docker run -d -v ./nginx.conf:/etc/nginx/nginx.conf nginx

网络管理

默认情况下,Docker会创建一个桥接网络,容器之间可以通过容器名通信。

查看网络

# 查看所有网络
docker network ls

# 查看桥接网络详情
docker network inspect bridge

创建自定义网络

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

# 查看网络详情
docker network inspect my-network

使用自定义网络

# 创建一个容器,连接到自定义网络
docker run -d --name web --network my-network nginx

# 创建另一个容器,连接到同一个网络
docker run -d --name db --network my-network mysql

# 现在web可以通过容器名访问db
docker exec -it web ping db

进阶技巧

多阶段构建

这是Docker的高级技巧,能有效减小镜像大小。想象一下你做蛋糕,需要烤箱、搅拌器等工具,但最后只需要成品蛋糕,不需要这些工具。

# 第一阶段:构建
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;"]

对比

  • 传统方式:可能包含几百MB的开发依赖
  • 多阶段构建:最终只有几十MB的运行环境

Dockerfile最佳实践

1. 选择合适的基础镜像

# ✅ 使用官方镜像,版本固定
FROM node:16.14-alpine
FROM python:3.9-slim

# ✅ 使用多阶段构建
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

# ❌ 避免使用不必要的大镜像
FROM ubuntu:20.04

2. 利用缓存

Docker的构建是分层的,相同的层会被缓存,构建会更快。

# ✅ 先复制依赖文件,再复制应用代码
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 \
build-essential \
&& rm -rf /var/lib/apt/lists/*

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

Docker Compose进阶

环境变量管理

# .env文件
NODE_ENV=production
PORT=8080
DB_HOST=db
DB_USER=appuser
DB_PASSWORD=secret

# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "${PORT}:3000"
environment:
- NODE_ENV=${NODE_ENV}
- DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:5432/myapp

健康检查

services:
web:
image: nginx
ports:
- "80:80"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s

资源限制

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

日志管理

集中日志收集

# docker-compose.yml
services:
app:
image: my-app
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

使用外部日志驱动

# 配置syslog
docker run -d \
--log-driver syslog \
--log-opt syslog-address=udp://192.168.1.1:514 \
my-app

实战案例

案例1:本地开发环境搭建

很多开发者都会遇到本地环境配置复杂的问题,用Docker可以完美解决。

项目结构

my-project/
├── docker-compose.yml
├── .env
├── web/
│ ├── Dockerfile
│ ├── app.py
│ └── requirements.txt
├── db/
│ └── init.sql
└── nginx/
└── nginx.conf

应用代码(Flask + MySQL)

# web/app.py
from flask import Flask
import mysql.connector
import os

app = Flask(__name__)

@app.route('/')
def hello():
db_host = os.getenv('DB_HOST', 'localhost')
return f'Hello from Flask! Connected to database at {db_host}'

@app.route('/users')
def get_users():
# 这里应该连接数据库并查询用户
return {'users': ['Alice', 'Bob']}

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

Dockerfile

# web/Dockerfile
FROM python:3.9-slim

WORKDIR /app

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

COPY app.py .

EXPOSE 5000

CMD ["python", "app.py"]

docker-compose.yml

version: '3.8'

services:
web:
build: ./web
ports:
- "5000:5000"
environment:
- DB_HOST=db
- DB_USER=root
- DB_PASSWORD=password
depends_on:
db:
condition: service_healthy

db:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=appdb
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10

nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- web

volumes:
db-data:

nginx配置

# nginx/nginx.conf
server {
listen 80;

location / {
proxy_pass http://web:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

启动应用

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

# 查看状态
docker-compose ps

# 查看日志
docker-compose logs -f

# 访问应用
# http://localhost

案例2:部署WordPress博客

这是一个经典的多容器应用案例。

docker-compose.yml

version: '3.8'

services:
wordpress:
image: wordpress:6.0
depends_on:
db:
condition: service_healthy
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: password
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
- ./custom-theme:/var/www/html/wp-content/themes/custom-theme
restart: unless-stopped

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
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10
restart: unless-stopped

phpmyadmin:
image: phpmyadmin/phpmyadmin
depends_on:
- db
ports:
- "8081:80"
environment:
PMA_HOST: db
PMA_USER: wordpress
PMA_PASSWORD: password
restart: unless-stopped

volumes:
wordpress_data:
mysql_data:

启动WordPress

# 启动服务
docker-compose up -d

# 访问WordPress
# http://localhost:8080
# 用户名:admin
# 密码:wordpress(需要检查日志确认)

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

案例3:开发环境的数据库管理

开发过程中经常需要初始化数据库,使用Docker可以很方便地处理。

MySQL初始化脚本

-- db/init.sql
CREATE DATABASE IF NOT EXISTS myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

USE myapp;

-- 创建用户
CREATE USER IF NOT EXISTS 'appuser'@'%' IDENTIFIED BY 'apppassword';
GRANT ALL PRIVILEGES ON myapp.* TO 'appuser'@'%';
FLUSH PRIVILEGES;

-- 创建表
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入示例数据
INSERT INTO users (name, email) VALUES
('Alice', 'alice@example.com'),
('Bob', 'bob@example.com')
ON DUPLICATE KEY UPDATE name=name;

使用初始化脚本

# 在docker-compose.yml中
services:
db:
image: mysql:8.0
volumes:
- db-data:/var/lib/mysql
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=myapp

常见问题解决

1. 安装问题

问题1:权限被拒绝

# 现象
Got permission denied while trying to connect to the Docker daemon socket

# 解决方法1:使用sudo
sudo docker run hello-world

# 解决方法2:添加用户到docker组(推荐)
sudo usermod -aG docker $USER
# 然后重新登录或执行
newgrp docker

问题2:Docker Desktop无法启动

# 现象:Docker Desktop无法启动,报错

# 解决方法1:检查Hyper-V
# Windows设置 -> 应用 -> 应用和功能 -> 程序和功能 -> 启用或关闭Windows功能
# 确保勾选:Hyper-V、Windows虚拟化平台、容器

# 解决方法2:重置Docker
# 删除Docker Desktop数据路径:
# %APPDATA%\Docker

# 解决方法3:清理Docker数据
docker system prune -a

2. 运行时问题

问题1:端口被占用

# 现象:端口已被另一个进程占用
bind: address already in use

# 解决方法1:查看端口占用
netstat -ano | findstr :8080
lsof -i :8080 # macOS/Linux

# 解决方法2:更改端口
docker run -d -p 8081:80 nginx

# 解决方法3:停止占用端口的进程
# Windows
taskkill /PID <PID> /F
# Linux/macOS
kill -9 <PID>

问题2:容器启动失败

# 查看容器状态
docker ps -a

# 查看错误日志
docker logs 容器名

# 进入容器排查
docker exec -it 容器名 bash

常见启动失败原因

  1. 端口冲突
  2. 文件权限问题
  3. 依赖服务未启动
  4. 内存不足

问题3:网络连接问题

# 现象:容器之间无法通信

# 解决方法1:使用自定义网络
docker network create my-network
docker run --name web --network my-network nginx
docker run --name db --network my-network mysql

# 解决方法2:检查网络配置
docker network inspect bridge

# 解决方法3:检查防火墙
# Windows
netsh advfirewall firewall add rule name="Docker" dir=in action=allow protocol=TCP localport=8080
# Linux
sudo ufw allow 8080

3. 构建问题

问题1:构建失败

# 解决方法1:查看详细构建日志
docker build --no-cache .

# 解决方法2:一步步构建
# 先构建基础层
docker build -t my-base -f Dockerfile.base .
# 然后基于基础层构建
docker build -t my-app .

问题2:镜像过大

# 使用多阶段构建
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

# 使用alpine版本的基础镜像
FROM python:3.9-alpine
# 而不是
# FROM python:3.9

问题3:构建缓存失效

# 复制依赖文件(不常变化)
COPY package*.json ./
RUN npm ci --only=production

# 复制应用代码(常变化)
COPY . .

# 这样修改代码不会重新安装依赖

4. 性能问题

问题1:容器运行缓慢

# 检查资源使用
docker stats

# 限制资源使用
docker run --cpus=1 --memory=1g my-app

# 使用--cpuset-cpus绑定CPU核心
docker run --cpuset-cpus=0-1 my-app

问题2:存储空间不足

# 查看磁盘使用
docker system df

# 清理不需要的资源
# 删除所有停止的容器
docker container prune

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

# 删除所有未使用的网络
docker network prune

# 删除所有悬空数据卷
docker volume prune

# 清理所有未使用的对象(谨慎使用)
docker system prune -a

5. 生产环境问题

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

# 解决方法1:使用host网络模式(不推荐)
docker run --network host my-app

# 解决方法2:配置DNS
docker run --dns 8.8.8.8 my-app

# 解决方法3:检查网络配置
docker network inspect bridge

问题2:日志管理

# 配置日志轮转
services:
app:
image: my-app
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

问题3:数据备份

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

# 备份整个容器
docker commit my-container my-backup
docker save my-backup > backup.tar

最佳实践

1. Dockerfile最佳实践

✅ 好的做法

# 使用官方基础镜像,版本固定
FROM node:16.14-alpine

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

# 设置工作目录
WORKDIR /app

# 只复制需要的文件
COPY package*.json ./

# 安装依赖并清理缓存
RUN npm ci --only=production && \
npm cache clean --force

# 复制应用代码
COPY . .

# 设置环境变量
ENV NODE_ENV=production

# 暴露端口
EXPOSE 3000

# 创建非root用户
RUN adduser --disabled-password appuser
USER appuser

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

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

❌ 避免的做法

# 不要使用latest标签
FROM node:latest

# 不要以root用户运行
USER root

# 一次性复制所有文件
COPY . .

# 不要忽略缓存优化
RUN apt-get update && apt-get install -y python
RUN apt-get update && apt-get install -y nginx

2. 安全最佳实践

最小权限原则

# 不要以root用户运行
RUN addgroup -g 1001 appgroup && \
adduser -u 1001 -G appgroup -s /bin/sh -D appuser
USER appuser

安全扫描

# 使用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

3. 生产环境配置

资源限制

version: '3.8'
services:
app:
image: my-app
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
restart: unless-stopped

日志配置

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

4. 开发环境优化

热重载配置

# 开发环境Dockerfile
FROM node:16-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci

# 挂载源码
COPY . .

# 安装开发依赖
RUN npm install

# 热重载
CMD ["npm", "run", "dev"]
# 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

扩展学习

1. 高级网络配置

自定义网络驱动

# 创建overlay网络(多主机)
docker network create --driver overlay --subnet=172.20.0.0/24 my-network

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

跨主机通信

# docker-compose.yml
version: '3.8'
services:
app:
image: my-app
networks:
- frontend
- backend

networks:
frontend:
driver: bridge
backend:
driver: overlay

2. 集群管理

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

3. 监控和日志

使用Prometheus

# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle'

grafana:
image: grafana/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-storage:/var/lib/grafana

ELK日志栈

version: '3.8'
services:
elasticsearch:
image: elasticsearch:7.10
ports:
- "9200:9200"
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data

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

kibana:
image: kibana:7.10
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200

volumes:
elasticsearch-data:
grafana-storage:

4. 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 Pipeline

// 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'
}
}
}
}

5. Kubernetes入门

虽然Kubernetes比Docker复杂,但它是容器编排的事实标准。

基本概念

  • Pod: 最小的部署单元,包含一个或多个容器
  • Deployment: 管理Pod的副本和更新
  • Service: 提供网络访问
  • Namespace: 资源隔离

示例YAML

# 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

总结

回顾一下我们今天学到的内容:

核心要点

  1. Docker的基本概念:镜像、容器、仓库、Dockerfile
  2. 环境搭建:Windows、macOS、Linux的安装和配置
  3. 基本操作:镜像和容器的管理、数据持久化、网络配置
  4. 进阶技巧:多阶段构建、Docker Compose、日志管理
  5. 实战应用:开发环境、WordPress部署、数据库管理
  6. 问题解决:常见错误的排查和解决
  7. 最佳实践:安全、性能、生产环境配置

学习建议

  1. 动手实践:理论很重要,但动手才能真正掌握
  2. 循序渐进:从简单的单容器开始,逐步过渡到复杂应用
  3. 文档参考:Docker官方文档是最好的学习资料
  4. 社区交流:遇到问题多查阅Stack Overflow和GitHub Issues

后续学习方向

  1. 深入理解容器技术:了解底层原理,如namespace、cgroup等
  2. 学习Kubernetes:掌握更复杂的容器编排
  3. 云原生开发:了解Service Mesh、Serverless等新技术
  4. DevOps实践:结合CI/CD,实现自动化部署

记住,技术学习是一个持续的过程。Docker只是一个工具,真正的价值在于如何用它来提高开发效率和系统可靠性。希望这篇文章能帮你打下坚实的基础,接下来就要靠你在实际项目中不断磨练了。

如果你在学习过程中遇到任何问题,欢迎在评论区留言交流。Happy Dockering!🐳


最后更新:2026年5月14日
分类:Docker | 容器化 | 运维 | 开发工具 | DevOps