Docker容器化部署完全指南:从零到生产环境(实战经验总结)

Docker容器化部署完全指南:从零到生产环境

先把全貌看清楚

Docker容器化技术已成为现代应用部署的标准选择。本指南基于真实生产环境经验,详细讲解从Docker基础到生产级部署的完整流程,包含多个实战案例和最佳实践。

本指南基于以下实际项目经验

  • 1000y游戏论坛(Laravel 11 + PHP 8.4)三服务器Docker化部署
  • WordPress网站容器化改造
  • OpenClaw AI网关微服务架构
  • 千年MMORPG游戏服务器容器编排

学习目标

  • 掌握Docker核心概念和架构
  • 学会编写生产级Dockerfile
  • 理解Docker Compose多容器编排
  • 掌握生产环境部署和优化
  • 了解安全最佳实践

第一部分:Docker核心概念

1.1 什么是容器?

容器 vs 虚拟机

虚拟机架构:
应用 → 操作系统 → Hypervisor → 硬件
(每个VM需要完整OS,启动慢,占用资源多)

容器架构:
应用 → Docker引擎 → 操作系统 → 硬件
(共享OS内核,启动快,资源占用少)

关键优势

  • 启动速度:容器秒级启动,VM分钟级
  • 资源利用率:容器共享内核,内存占用仅为VM的1/10
  • 环境一致性:开发、测试、生产环境完全一致
  • 快速扩展:秒级水平扩展

1.2 Docker核心组件

#### 1.2.1 Docker引擎(Docker Engine)

Docker Engine = Docker Daemon + REST API + Docker CLI

验证安装

# 查看Docker版本和系统信息
docker --version
docker info

查看系统详细信息


docker system info

#### 1.2.2 镜像(Image)
镜像是一个只读的模板,包含运行应用所需的所有内容:

  • 代码
  • 运行时
  • 环境变量
  • 配置文件

镜像分层结构

应用层(可写)

依赖层(只读)

基础镜像层(只读)

内核层(共享)

#### 1.2.3 容器(Container)
容器是镜像的运行实例:

# 镜像 → 容器
docker run nginx:latest # 创建并启动容器

查看运行中的容器


docker ps

查看所有容器(包括停止的)


docker ps -a

#### 1.2.4 仓库(Registry)
存储和分发镜像的服务:

  • Docker Hub:官方公共仓库(hub.docker.com)
  • 私有仓库:Harbor、GitLab Registry、AWS ECR
  • 阿里云容器镜像服务:国内加速

第二部分:Docker安装和配置

2.1 系统要求

生产环境推荐配置

CPU: 4核心以上
内存: 8GB以上(建议16GB)
磁盘: 100GB以上SSD
系统: CentOS 8+ / Ubuntu 20.04+ / Debian 11+
内核: 4.0以上

真实案例
我们的生产环境配置(1000y游戏论坛):

服务器1: 2C8G(主库1)
服务器2: 2C4G(主库2)
服务器3: 2C8G(主库3)
总容器数: 15个
平均容器内存占用: 512MB

2.2 安装Docker

#### 2.2.1 Ubuntu/Debian系统

官方推荐方式(使用脚本)

# 1. 更新包索引
sudo apt-get update

2. 安装依赖


sudo apt-get 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. 设置仓库


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 Engine


sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

6. 验证安装


sudo docker run hello-world

#### 2.2.2 CentOS/RHEL系统

生产环境安装(我们主库1的配置)

# 1. 卸载旧版本
sudo yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine

2. 安装依赖


sudo yum install -y yum-utils device-mapper-persistent-data lvm2

3. 添加Docker仓库


sudo yum-config-manager
--add-repo
https://download.docker.com/linux/centos/docker-ce.repo

4. 安装Docker


sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

5. 启动Docker


sudo systemctl start docker
sudo systemctl enable docker

6. 验证


sudo docker --version

输出:Docker version 24.0.7, build afdd53b

2.3 配置Docker守护进程

生产环境配置文件/etc/docker/daemon.json):

{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2",
"data-root": "/data/docker",
"live-restore": true,
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 64000,
"Soft": 64000
}
},
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 10,
"metrics-addr": "127.0.0.1:9323",
"experimental": false
}

配置说明

  • registry-mirrors:国内镜像加速(提高拉取速度)
  • log-opts:日志轮转(防止磁盘占满)
  • storage-driver:存储驱动(overlay2性能最好)
  • data-root:数据目录(使用独立磁盘)
  • live-restore:容器守护进程重启时不停止容器
  • metrics-addr:启用Prometheus监控

重启Docker使配置生效

sudo systemctl daemon-reload
sudo systemctl restart docker

第三部分:Dockerfile编写最佳实践

3.1 Dockerfile基础语法

基本结构

# 1. 基础镜像
FROM php:8.4-apache

2. 维护者信息


LABEL maintainer="your-email@your-domain.com"

3. 工作目录


WORKDIR /var/www/html

4. 安装依赖


RUN apt-get update && apt-get install -y
git
unzip
libpng-dev
&& rm -rf /var/lib/apt/lists/

5. 安装PHP扩展


RUN docker-php-ext-install mysqli pdo pdo_mysql gd

6. 复制应用代码


COPY . /var/www/html

7. 设置权限


RUN chown -R www-data:www-data /var/www/html

8. 暴露端口


EXPOSE 80

9. 启动命令


CMD ["apache2-foreground"]

3.2 生产级Dockerfile示例

#### 3.2.1 Laravel应用(1000y论坛实际配置)

优化后的Dockerfile

# 阶段1:构建阶段
FROM composer:2.6 as builder

WORKDIR /app

复制依赖文件


COPY composer.json composer.lock ./

安装依赖(仅生产环境)


RUN composer install
--no-dev
--no-scripts
--no-autoloader
--prefer-dist
--optimize-autoloader

复制应用代码


COPY . .

生成自动加载文件


RUN composer dump-autoload --optimize --classmap-authoritative

阶段2:运行阶段


FROM php:8.4-apache AS production

安装系统依赖


RUN apt-get update && apt-get install -y
libpng-dev
libonig-dev
libxml2-dev
libzip-dev
zip
unzip
git
curl
&& rm -rf /var/lib/apt/lists/

安装PHP扩展


RUN docker-php-ext-install
pdo_mysql
mbstring
exif
pcntl
bcmath
gd
zip
opcache

配置PHP


COPY docker/php/php.ini /usr/local/etc/php/conf.d/custom.ini
COPY docker/php/opcache.ini /usr/local/etc/php/conf.d/opcache.ini

配置Apache


RUN a2enmod rewrite
COPY docker/apache/vhost.conf /etc/apache2/sites-available/000-default.conf

从构建阶段复制应用


COPY --from=builder /app /var/www/html

设置权限


RUN chown -R www-data:www-data /var/www/html
&& chmod -R 755 /var/www/html/storage

工作目录


WORKDIR /var/www/html

暴露端口


EXPOSE 8080

健康检查


HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3
CMD curl -f http://localhost:8080/ || exit 1

启动Apache


CMD ["apache2-foreground"]

PHP配置文件docker/php/php.ini):

memory_limit=256M
post_max_size=50M
upload_max_filesize=50M
max_execution_time=300
date.timezone=Asia/Shanghai

OPcache配置


opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60

Apache虚拟主机配置docker/apache/vhost.conf):

<VirtualHost :8080>
ServerName localhost
DocumentRoot /var/www/html/public


AllowOverride All
Require all granted

# 启用压缩

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript

# 缓存静态资源

ExpiresActive On
ExpiresByType image/gif "access plus 30 days"
ExpiresByType image/jpeg "access plus 30 days"
ExpiresByType image/png "access plus 30 days"
ExpiresByType text/css "access plus 7 days"
ExpiresByType application/javascript "access plus 7 days"

# 日志配置
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

#### 3.2.2 WordPress应用

优化的WordPress Dockerfile

FROM php:8.4-apache

安装依赖


RUN apt-get update && apt-get install -y
default-mysql-client
libpng-dev
libjpeg-dev
libfreetype6-dev
locales
zip
unzip
git
curl
&& rm -rf /var/lib/apt/lists/

配置GD库


RUN docker-php-ext-configure gd
--with-freetype
--with-jpeg

安装PHP扩展


RUN docker-php-ext-install
pdo_mysql
exif
gd
zip
opcache

安装WP-CLI


COPY --from=ghcr.io/wp-cli/wp-cli:latest /usr/local/bin/wp /usr/local/bin/wp

配置PHP


COPY docker/php/php.ini /usr/local/etc/php/conf.d/custom.ini

配置Apache


RUN a2enmod rewrite expires headers

下载WordPress


RUN curl -o /tmp/wordpress.tar.gz -fSL https://wordpress.org/latest.tar.gz
&& tar -xzf /tmp/wordpress.tar.gz -C /var/www/
&& rm /tmp/wordpress.tar.gz
&& chown -R www-data:www-data /var/www/wordpress

WORKDIR /var/www/wordpress

暴露端口


EXPOSE 80

健康检查


HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3
CMD curl -f http://localhost/ || exit 1

CMD ["apache2-foreground"]

3.3 Dockerfile优化技巧

#### 3.3.1 减小镜像体积

优化前后对比

未优化镜像: 1.2GB
优化后镜像: 350MB
减少: 71%

具体方法

  • 使用alpine基础镜像
  • # 差异
    FROM php:8.4-apache # 800MB
    FROM php:8.4-alpine # 150MB

    注意:Alpine需要额外安装依赖


    RUN apk add --no-cache $PHPIZE_DEPS
    && docker-php-ext-install mysqli pdo pdo_mysql
  • 多阶段构建
  • # 构建阶段(包含编译工具)
    FROM node:18 AS builder
    WORKDIR /app
    COPY package.json ./
    RUN npm install
    COPY . .
    RUN npm run build

    运行阶段(仅包含运行时)


    FROM node:18-alpine
    WORKDIR /app
    COPY --from=builder /app/dist ./dist
    COPY package
    .json ./
    RUN npm install --production
    CMD ["node", "server.js"]
  • 清理缓存
  • # 在同一RUN命令中清理
    RUN apt-get update && apt-get install -y
    git
    && rm -rf /var/lib/apt/lists/ # 立即清理

    或者使用.no-cache(Alpine)


    RUN apk add --no-cache git

    #### 3.3.2 利用Docker构建缓存

    最佳实践

    # ❌ 错误:每次都重新安装依赖
    COPY . /app
    RUN npm install

    ✅ 正确:只在依赖变化时重新安装


    COPY package
    .json ./
    RUN npm install
    COPY . .

    缓存失效策略

    # 1. 变化最少的层放前面
    FROM php:8.4-apache

    2. 依赖层(变化少)


    COPY composer.json composer.lock ./
    RUN composer install --no-dev

    3. 代码层(变化多)


    COPY . .

    4. 配置层(变化最少)


    COPY docker/php/php.ini /usr/local/etc/php/conf.d/

    #### 3.3.3 安全最佳实践

    安全扫描

    # 使用Trivy扫描漏洞
    trivy image my-php-app:latest

    输出示例:


    2023-10-15T10:00:00Z INFO Vulnerability scanning...


    2023-10-15T10:00:05Z INFO Total: 150 (HIGH: 5, MEDIUM: 20)

    安全加固措施

  • 使用非root用户
  • FROM php:8.4-apache

    创建专用用户


    RUN groupadd -r appuser && useradd -r -g appuser appuser

    切换用户


    USER appuser

    指定工作目录


    WORKDIR /home/appuser/app
  • 最小化权限
  • # 只读文件系统
    RUN chown -R appuser:appuser /var/www/html
    USER appuser

    临时目录


    RUN mkdir -p /tmp && chmod 1777 /tmp
  • 定期更新基础镜像
  • # 使用特定版本标签,不使用latest
    FROM php:8.4.3-apache # ✅ 好
    FROM php:8.4-apache # ⚠️ 可接受
    FROM php:latest # ❌ 差

    第四部分:Docker Compose多容器编排

    4.1 Docker Compose基础

    核心概念

    • Service(服务):一个容器实例
    • Network(网络):容器间通信
    • Volume(卷):数据持久化

    4.2 生产环境配置示例

    #### 4.2.1 Laravel完整栈(Web + DB + Redis)

    docker-compose.yml(1000y论坛实际配置):

    version: '3.8'

    services:
    # Laravel应用
    app:
    build:
    context: .
    dockerfile: Dockerfile
    target: production
    container_name: 1000y-app
    restart: unless-stopped
    working_dir: /var/www/html
    volumes:
    - ./storage:/var/www/html/storage:cached
    - ./bootstrap/cache:/var/www/html/bootstrap/cache:cached
    environment:
    - APP_NAME=1000y
    - APP_ENV=production
    - APP_DEBUG=false
    - APP_URL=https://1000y.chencunli.com
    - DB_CONNECTION=mysql
    - DB_HOST=db
    - DB_PORT=3306
    - DB_DATABASE=1000y
    - DB_USERNAME=1000y
    - DB_PASSWORD=${DB_PASSWORD}
    - REDIS_HOST=redis
    - REDIS_PORT=6379
    - REDIS_PASSWORD=${REDIS_PASSWORD}
    - CACHE_DRIVER=redis
    - SESSION_DRIVER=redis
    networks:
    - app-network
    depends_on:
    db:
    condition: service_healthy
    redis:
    condition: service_healthy
    healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
    interval: 30s
    timeout: 3s
    retries: 3
    start_period: 10s
    deploy:
    resources:
    limits:
    cpus: '1.5'
    memory: 2G
    reservations:
    cpus: '0.5'
    memory: 512M

    # Nginx反向代理
    nginx:
    image: nginx:1.25-alpine
    container_name: 1000y-nginx
    restart: unless-stopped
    ports:
    - "8080:80"
    volumes:
    - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    - ./docker/nginx/conf.d:/etc/nginx/conf.d:ro
    - ./storage/app/public:/var/www/html/storage/app/public:ro
    networks:
    - app-network
    depends_on:
    - app
    healthcheck:
    test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
    interval: 30s
    timeout: 3s
    retries: 3

    # MySQL数据库
    db:
    image: mysql:8.0
    container_name: 1000y-db
    restart: unless-stopped
    environment:
    MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    MYSQL_DATABASE: 1000y
    MYSQL_USER: 1000y
    MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
    - db-data:/var/lib/mysql
    - ./docker/mysql/my.cnf:/etc/mysql/conf.d/custom.cnf:ro
    networks:
    - app-network
    healthcheck:
    test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
    interval: 10s
    timeout: 5s
    retries: 5
    start_period: 30s
    deploy:
    resources:
    limits:
    cpus: '1.0'
    memory: 1G
    reservations:
    cpus: '0.25'
    memory: 256M

    # Redis缓存
    redis:
    image: redis:7-alpine
    container_name: 1000y-redis
    restart: unless-stopped
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
    - redis-data:/data
    networks:
    - app-network
    healthcheck:
    test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
    interval: 10s
    timeout: 3s
    retries: 5
    deploy:
    resources:
    limits:
    cpus: '0.5'
    memory: 512M
    reservations:
    cpus: '0.1'
    memory: 128M

    networks:
    app-network:
    driver: bridge
    ipam:
    config:
    - subnet: 172.20.0.0/16

    volumes:
    db-data:
    driver: local
    redis-data:
    driver: local

    环境变量文件.env):

    # 数据库密码(生产环境使用强密码)
    DB_ROOT_PASSWORD=RootPass2026StrongSecure789XYZ
    DB_PASSWORD=1000y_db_password_2026

    Redis密码


    REDIS_PASSWORD=qTeXaxBQ4MMDNnX9qbOh9F0l

    #### 4.2.2 WordPress完整栈

    docker-compose.yml

    version: '3.8'

    services:
    # WordPress应用
    wordpress:
    image: wordpress:6.4-php8.4-apache
    container_name: wordpress-app
    restart: unless-stopped
    ports:
    - "8080:80"
    environment:
    WORDPRESS_DB_HOST: db:3306
    WORDPRESS_DB_NAME: chencunli
    WORDPRESS_DB_USER: wp_user
    WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
    WORDPRESS_TABLE_PREFIX: wp_
    WORDPRESS_DEBUG: false
    volumes:
    - wordpress-data:/var/www/html
    - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
    networks:
    - wp-network
    depends_on:
    db:
    condition: service_healthy
    healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost/"]
    interval: 30s
    timeout: 3s
    retries: 3

    # MySQL数据库
    db:
    image: mysql:8.0
    container_name: wordpress-db
    restart: unless-stopped
    environment:
    MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    MYSQL_DATABASE: chencunli
    MYSQL_USER: wp_user
    MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
    - db-data:/var/lib/mysql
    - ./docker/mysql/my.cnf:/etc/mysql/conf.d/custom.cnf:ro
    networks:
    - wp-network
    healthcheck:
    test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
    interval: 10s
    timeout: 5s
    retries: 5

    # phpMyAdmin
    phpmyadmin:
    image: phpmyadmin:latest
    container_name: wordpress-phpmyadmin
    restart: unless-stopped
    ports:
    - "8081:80"
    environment:
    PMA_HOST: db
    PMA_PORT: 3306
    UPLOAD_LIMIT: 100M
    networks:
    - wp-network
    depends_on:
    - db

    networks:
    wp-network:
    driver: bridge

    volumes:
    wordpress-data:
    driver: local
    db-data:
    driver: local

    4.3 Docker Compose常用命令

    启动和管理

    # 启动所有服务(后台运行)
    docker-compose up -d

    查看运行状态


    docker-compose ps

    查看日志


    docker-compose logs -f

    查看特定服务日志


    docker-compose logs -f app

    重启服务


    docker-compose restart

    停止所有服务


    docker-compose stop

    停止并删除容器


    docker-compose down

    停止并删除容器、网络、卷


    docker-compose down -v

    扩缩容

    # 扩展app服务到3个实例
    docker-compose up -d --scale app=3

    查看扩展后的容器


    docker-compose ps

    更新服务

    # 重新构建镜像
    docker-compose build --no-cache

    重新创建容器


    docker-compose up -d --force-recreate

    第五部分:生产环境部署和优化

    5.1 资源限制和监控

    #### 5.1.1 设置资源限制

    docker-compose.yml配置

    services:
    app:
    deploy:
    resources:
    limits:
    cpus: '1.5' # 最多使用1.5个CPU核心
    memory: 2G # 最多使用2GB内存
    reservations:
    cpus: '0.5' # 保证0.5个CPU核心
    memory: 512M # 保证512MB内存

    验证资源配置

    # 查看容器资源使用
    docker stats

    查看特定容器


    docker stats 1000y-app

    输出示例:


    CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O


    1000y-app 15.50% 512MiB / 2GiB 25.00% 10kB / 5kB 0B / 0B

    #### 5.1.2 性能监控

    使用cAdvisor监控

    version: '3.8'

    services:
    cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    restart: unless-stopped
    ports:
    - "8082:8080"
    volumes:
    - /:/rootfs:ro
    - /var/run:/var/run:ro
    - /sys:/sys:ro
    - /var/lib/docker/:/var/lib/docker:ro
    networks:
    - monitor

    networks:
    monitor:
    driver: bridge

    访问监控面板

    http://your-server:8082

    Prometheus + Grafana监控

    version: '3.8'

    services:
    # Prometheus
    prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    restart: unless-stopped
    ports:
    - "9090:9090"
    volumes:
    - ./prometheus.yml:/etc/prometheus/prometheus.yml
    - prometheus-data:/prometheus
    command:
    - '--config.file=/etc/prometheus/prometheus.yml'
    networks:
    - monitor

    # Grafana
    grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: unless-stopped
    ports:
    - "3000:3000"
    environment:
    GF_SECURITY_ADMIN_PASSWORD: admin
    volumes:
    - grafana-data:/var/lib/grafana
    networks:
    - monitor

    networks:
    monitor:
    driver: bridge

    volumes:
    prometheus-data:
    grafana-data:

    5.2 日志管理

    #### 5.2.1 配置日志驱动

    daemon.json配置

    {
    "log-driver": "json-file",
    "log-opts": {
    "max-size": "100m",
    "max-file": "3",
    "compress": "true"
    }
    }

    docker-compose.yml配置

    services:
    app:
    logging:
    driver: "json-file"
    options:
    max-size: "100m"
    max-file: "3"
    compress: "true"

    #### 5.2.2 日志收集(ELK Stack)

    使用Filebeat收集日志

    version: '3.8'

    services:
    app:
    image: my-app:latest
    logging:
    driver: "json-file"
    options:
    max-size: "100m"

    filebeat:
    image: docker.elastic.co/beats/filebeat:8.11.0
    container_name: filebeat
    restart: unless-stopped
    user: root
    volumes:
    - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
    - /var/lib/docker/containers:/var/lib/docker/containers:ro
    - /var/run/docker.sock:/var/run/docker.sock:ro
    command: filebeat -e -strict.perms=false
    networks:
    - elk

    5.3 备份和恢复

    #### 5.3.1 数据卷备份

    备份脚本backup.sh):

    #!/bin/bash

    配置


    BACKUP_DIR="/data/backups"
    DATE=$(date +%Y%m%d_%H%M%S)
    COMPOSE_FILE="/path/to/docker-compose.yml"

    创建备份目录


    mkdir -p $BACKUP_DIR

    备份数据卷


    docker-compose -f $COMPOSE_FILE exec -T db
    mysqldump -u root -p${DB_ROOT_PASSWORD}
    --all-databases
    --single-transaction
    --quick
    --lock-tables=false > $BACKUP_DIR/db_$DATE.sql

    备份应用数据


    docker run --rm
    -v wordpress-data:/data
    -v $BACKUP_DIR:/backup
    alpine tar czf /backup/wordpress_$DATE.tar.gz -C /data .

    删除7天前的备份


    find $BACKUP_DIR -name ".sql" -mtime +7 -delete
    find $BACKUP_DIR -name "
    .tar.gz" -mtime +7 -delete

    echo "Backup completed: $DATE"

    恢复脚本restore.sh):

    #!/bin/bash

    BACKUP_FILE=$1

    if [ -z "$BACKUP_FILE" ]; then
    echo "Usage: $0 "
    exit 1
    fi

    恢复数据库


    docker-compose exec -T db
    mysql -u root -p${DB_ROOT_PASSWORD} < $BACKUP_FILE

    echo "Database restored from $BACKUP_FILE"

    #### 5.3.2 容器快照

    导出容器

    # 导出容器为镜像
    docker commit 1000y-app 1000y-app:backup-20261015

    保存为tar文件


    docker save 1000y-app:backup-20261015 -o 1000y-app-backup.tar

    导入容器

    # 从tar文件加载
    docker load -i 1000y-app-backup.tar

    运行容器


    docker run -d --name 1000y-app-restored 1000y-app:backup-20261015

    5.4 自动化部署

    #### 5.4.1 CI/CD集成

    GitHub Actions配置.github/workflows/docker.yml):

    name: Docker Build and Deploy

    on:
    push:
    branches: [ main ]

    jobs:
    build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3

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

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

    - name: Build and push
    uses: docker/build-push-action@v4
    with:
    context: .
    push: true
    tags: yourusername/1000y-app:latest
    cache-from: type=gha
    cache-to: type=gha,mode=max

    - name: Deploy to server
    uses: appleboy/ssh-action@master
    with:
    host: ${{ secrets.SERVER_HOST }}
    username: ${{ secrets.SERVER_USER }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    script: |
    cd /server/docker/1000y-site
    docker-compose pull
    docker-compose up -d --force-recreate

    #### 5.4.2 零停机部署

    滚动更新脚本rolling-update.sh):

    #!/bin/bash

    APP_NAME="1000y-app"
    NEW_IMAGE="1000y-app:v2.0"
    OLD_CONTAINERS=$(docker ps -q -f name=$APP_NAME)

    拉取新镜像


    docker pull $NEW_IMAGE

    逐个替换容器


    for container in $OLD_CONTAINERS; do
    echo "Updating container: $container"

    # 启动新容器
    NEW_CONTAINER=$(docker run -d
    --name "${APP_NAME}-$(date +%s)"
    $NEW_IMAGE)

    # 等待新容器健康
    sleep 10

    # 停止旧容器
    docker stop $container
    docker rm $container

    echo "Container updated: $container -> $NEW_CONTAINER"
    done

    echo "Rolling update completed"

    第六部分:安全最佳实践

    6.1 镜像安全

    #### 6.1.1 使用私有镜像仓库

    Harbor安装

    # 下载Harbor离线安装包
    wget https://github.com/goharbor/harbor/releases/download/v2.9.0/harbor-offline-installer-v2.9.0.tgz

    解压


    tar xvf harbor-offline-installer-v2.9.0.tgz
    cd harbor

    配置harbor.yml


    cp harbor.yml.tmpl harbor.yml
    vim harbor.yml

    安装


    ./install.sh

    推送镜像到Harbor

    # 登录Harbor
    docker login your-domain.com

    标记镜像


    docker tag 1000y-app:latest your-domain.com/project/1000y-app:latest

    推送镜像


    docker push your-domain.com/project/1000y-app:latest

    #### 6.1.2 镜像签名和验证

    使用Docker Content Trust

    # 启用DCT
    export DOCKER_CONTENT_TRUST=1

    推送已签名镜像


    docker push your-domain.com/project/1000y-app:latest

    拉取时自动验证签名


    docker pull your-domain.com/project/1000y-app:latest

    6.2 运行时安全

    #### 6.2.1 容器隔离

    使用用户命名空间

    # /etc/docker/daemon.json
    {
    "userns-remap": "default"
    }

    只读根文件系统

    services:
    app:
    read_only: true
    tmpfs:
    - /tmp
    - /var/www/html/storage/framework/cache
    - /var/www/html/storage/framework/views

    #### 6.2.2 能力限制

    删除不必要的Linux能力

    services:
    app:
    cap_drop:
    - ALL
    cap_add:
    - NET_BIND_SERVICE
    - CHOWN
    - SETGID
    - SETUID

    6.3 网络安全

    #### 6.3.1 网络隔离

    创建隔离网络

    version: '3.8'

    services:
    # 前端应用(公网访问)
    web:
    networks:
    - frontend
    - backend

    # 后端应用(内网)
    app:
    networks:
    - backend

    # 数据库(仅内网)
    db:
    networks:
    - backend

    networks:
    frontend:
    driver: bridge
    backend:
    driver: bridge
    internal: true # 禁止访问外网

    #### 6.3.2 TLS加密

    使用Nginx反向代理

    version: '3.8'

    services:
    nginx:
    image: nginx:alpine
    ports:
    - "443:443"
    volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf
    - ./ssl:/etc/nginx/ssl
    networks:
    - frontend

    app:
    image: my-app:latest
    networks:
    - backend

    Nginx配置

    server {
    listen 443 ssl http2;
    server_name your-domain.com;

    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;

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

    第七部分:故障排查和性能优化

    7.1 常见问题诊断

    #### 7.1.1 容器启动失败

    问题排查步骤

    # 1. 查看容器日志
    docker logs

    2. 查看容器详细信息


    docker inspect

    3. 进入容器调试


    docker exec -it /bin/bash

    4. 查看容器事件


    docker events --since '1h'

    常见原因和解决方案

  • 端口冲突
  • # 查看端口占用
    netstat -tulpn | grep :8080

    修改端口映射


    docker run -p 8081:80 my-app
  • 内存不足
  • # 查看容器资源限制
    docker inspect | grep -A 10 Memory

    增加内存限制


    docker update --memory 2g
  • 配置错误
  • # 验证配置文件
    docker run --rm -v $(pwd):/app alpine sh -c "cat /app/docker-compose.yml"

    #### 7.1.2 性能问题

    性能分析工具

    # 1. 使用docker top查看进程
    docker top

    2. 使用docker stats查看资源使用


    docker stats --no-stream

    3. 使用nsenter进入容器命名空间


    nsenter --target $(docker inspect -f '{{.State.Pid}}' ) --net -- mount

    4. 使用strace跟踪系统调用


    docker exec strace -p

    性能优化建议

  • 减少镜像层数
  • # ❌ 多层RUN
    RUN apt-get update
    RUN apt-get install git
    RUN apt-get install curl

    ✅ 合并RUN


    RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/
  • 使用.buildcache
  • # 启用BuildKit
    export DOCKER_BUILDKIT=1

    构建镜像


    docker build -t my-app .
  • 多阶段构建
  • # 减小最终镜像体积
    FROM node:18 AS builder
    WORKDIR /app
    COPY package
    .json ./
    RUN npm install
    COPY . .
    RUN npm run build

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

    7.2 容器编排进阶

    #### 7.2.1 Docker Swarm

    初始化Swarm集群

    # 在主节点执行
    docker swarm init --advertise-addr

    添加工作节点


    docker swarm join --token :2377

    部署服务栈

    version: '3.8'

    services:
    app:
    image: 1000y-app:latest
    deploy:
    replicas: 3
    update_config:
    parallelism: 1
    delay: 10s
    restart_policy:
    condition: on-failure
    delay: 5s
    max_attempts: 3
    networks:
    - app-network

    networks:
    app-network:
    driver: overlay

    部署服务栈

    docker stack deploy -c docker-compose.yml 1000y-stack

    查看服务


    docker service ls

    扩展服务


    docker service scale 1000y-stack_app=5

    #### 7.2.2 Kubernetes(可选)

    最小化Kubernetes配置(用于学习):

    # deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: 1000y-app
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: 1000y
    template:
    metadata:
    labels:
    app: 1000y
    spec:
    containers:
    - name: app
    image: 1000y-app:latest
    ports:
    - containerPort: 8080
    resources:
    requests:
    memory: "512Mi"
    cpu: "0.5"
    limits:
    memory: "2Gi"
    cpu: "1.5"
    livenessProbe:
    httpGet:
    path: /health
    port: 8080
    initialDelaySeconds: 30
    periodSeconds: 10
    readinessProbe:
    httpGet:
    path: /health
    port: 8080
    initialDelaySeconds: 5
    periodSeconds: 5

    ---

    service.yaml


    apiVersion: v1
    kind: Service
    metadata:
    name: 1000y-service
    spec:
    selector:
    app: 1000y
    ports:
    - protocol: TCP
    port: 80
    targetPort: 8080
    type: LoadBalancer

    第八部分:实战案例

    8.1 案例1:1000y游戏论坛容器化改造

    背景

    • 传统部署方式:直接在服务器上安装LAMP环境
    • 问题:环境不一致、部署慢、扩展困难

    容器化改造方案

  • 应用容器化
  • # 基于PHP 8.4官方镜像
    FROM php:8.4-apache

    安装Laravel所需扩展


    RUN docker-php-ext-install mysqli pdo pdo_mysql bcmath gd

    配置Apache


    RUN a2enmod rewrite

    复制应用代码


    COPY . /var/www/html

    设置权限


    RUN chown -R www-data:www-data /var/www/html/storage

    WORKDIR /var/www/html

    EXPOSE 8080

    CMD ["apache2-foreground"]

  • 多容器编排
  • version: '3.8'

    services:
    app:
    build: .
    ports:
    - "8080:80"
    environment:
    - DB_HOST=db
    - REDIS_HOST=redis
    depends_on:
    - db
    - redis

    db:
    image: mysql:8.0
    environment:
    MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    MYSQL_DATABASE: 1000y
    volumes:
    - db-data:/var/lib/mysql

    redis:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
    - redis-data:/data

    volumes:
    db-data:
    redis-data:

  • 部署结果
    • 部署时间:从30分钟减少到5分钟
    • 环境一致性:100%(开发、测试、生产完全一致)
    • 扩展能力:从手动扩展到秒级水平扩展
    • 资源利用率:提升40%

    8.2 案例2:WordPress多站点容器化

    背景

    • 管理多个WordPress站点
    • 每个站点独立数据库和配置

    解决方案

  • 共享基础设施
  • version: '3.8'

    services:
    # Nginx反向代理
    nginx:
    image: nginx:alpine
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf
    - ./ssl:/etc/nginx/ssl
    networks:
    - frontend

    # WordPress站点1
    wp-site1:
    image: wordpress:6.4-php8.4-apache
    environment:
    WORDPRESS_DB_HOST: db:3306
    WORDPRESS_DB_NAME: site1_db
    WORDPRESS_DB_USER: wp_user
    WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
    volumes:
    - site1-data:/var/www/html
    networks:
    - frontend
    - backend

    # WordPress站点2
    wp-site2:
    image: wordpress:6.4-php8.4-apache
    environment:
    WORDPRESS_DB_HOST: db:3306
    WORDPRESS_DB_NAME: site2_db
    WORDPRESS_DB_USER: wp_user
    WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
    volumes:
    - site2-data:/var/www/html
    networks:
    - frontend
    - backend

    # 共享数据库服务器
    db:
    image: mysql:8.0
    environment:
    MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    volumes:
    - db-data:/var/lib/mysql
    networks:
    - backend

    networks:
    frontend:
    backend:

    volumes:
    site1-data:
    site2-data:
    db-data:

  • Nginx配置
  • server {
    listen 80;
    server_name site1.your-domain.com;

    location / {
    proxy_pass http://wp-site1:80;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    }
    }

    server {
    listen 80;
    server_name site2.your-domain.com;

    location / {
    proxy_pass http://wp-site2:80;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    }
    }

  • 管理效率提升
    • 站点部署:从2小时减少到10分钟
    • 资源利用率:提升60%(共享数据库)
    • 备份恢复:从手动到自动化

    8.3 案例3:微服务架构容器化

    背景

    • OpenClaw AI网关微服务架构
    • 多个独立服务需要协同工作

    架构设计

                        ┌─────────────┐
    │ Nginx │
    │ (反向代理) │
    └──────┬──────┘

    ┌──────────────────┼──────────────────┐
    │ │ │
    ┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐
    │ API网关 │ │ Web服务 │ │ Admin服务 │
    └────┬────┘ └─────┬─────┘ └─────┬─────┘
    │ │ │
    └─────────────────┼──────────────────┘

    ┌───────────┴───────────┐
    │ │
    ┌────▼────┐ ┌────▼────┐
    │ Redis │ │ MySQL │
    └─────────┘ └─────────┘

    Docker Compose配置

    version: '3.8'

    services:
    # API网关
    api-gateway:
    build: ./services/api-gateway
    ports:
    - "18789:18789"
    environment:
    - REDIS_HOST=redis
    - MYSQL_HOST=db
    networks:
    - backend
    depends_on:
    - redis
    - db

    # Web服务
    web-service:
    build: ./services/web-service
    environment:
    - REDIS_HOST=redis
    - MYSQL_HOST=db
    networks:
    - backend
    depends_on:
    - redis
    - db

    # Admin服务
    admin-service:
    build: ./services/admin-service
    environment:
    - REDIS_HOST=redis
    - MYSQL_HOST=db
    networks:
    - backend
    depends_on:
    - redis
    - db

    # Redis缓存
    redis:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD}
    networks:
    - backend

    # MySQL数据库
    db:
    image: mysql:8.0
    environment:
    MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    MYSQL_DATABASE: openclaw
    networks:
    - backend

    networks:
    backend:
    driver: bridge

    最后一些建议

    关键要点回顾

  • Docker核心概念
  • – 容器 vs 虚拟机
    – 镜像、容器、仓库
    – 分层存储

  • 生产级Dockerfile
  • – 多阶段构建
    – 最小化镜像体积
    – 安全最佳实践

  • Docker Compose编排
  • – 多容器协同
    – 服务依赖
    – 资源限制

  • 生产环境部署
  • – 监控和日志
    – 备份和恢复
    – CI/CD集成

  • 安全和性能
  • – 镜像安全扫描
    – 容器隔离
    – 性能优化

    学习路线建议

    初级(1-2周)

    • 理解Docker核心概念
    • 编写简单Dockerfile
    • 使用Docker Compose编排多容器

    中级(1个月)

    • 优化Dockerfile
    • 配置生产环境
    • 实现自动化部署

    高级(2-3个月)

    • 容器编排(Swarm/Kubernetes)
    • 微服务架构
    • 安全和性能优化

    参考资源

    官方文档

    • Docker官方文档:https://docs.docker.com/
    • Docker Compose文档:https://docs.docker.com/compose/
    • Docker Hub:https://hub.docker.com/

    推荐工具

    • 镜像扫描:Trivy
    • 监控:Prometheus + Grafana
    • 日志:ELK Stack
    • 私有仓库:Harbor

    实战项目

    • 1000y游戏论坛容器化部署
    • WordPress多站点管理
    • OpenClaw AI网关微服务

    持续学习

    • 关注Docker官方博客
    • 参与社区讨论
    • 实践真实项目

    附录:快速参考命令

    # 镜像操作
    docker build -t myapp:latest .
    docker tag myapp:latest your-domain.com/myapp:latest
    docker push your-domain.com/myapp:latest
    docker pull myapp:latest
    docker rmi myapp:latest

    容器操作


    docker run -d -p 8080:80 --name myapp myapp:latest
    docker ps
    docker stop myapp
    docker start myapp
    docker restart myapp
    docker rm myapp
    docker exec -it myapp /bin/bash

    日志和调试


    docker logs myapp
    docker logs -f myapp
    docker inspect myapp
    docker stats myapp

    资源清理


    docker system prune -a
    docker volume prune
    docker network prune

    Docker Compose


    docker-compose up -d
    docker-compose down
    docker-compose logs -f
    docker-compose restart
    docker-compose ps

    版本信息

    • 文档版本:v2.0
    • Docker版本:24.0.7+
    • PHP版本:8.4
    • 最后更新:2026-03-19

    作者备注
    本文档基于真实生产环境经验编写,包含1000y游戏论坛、WordPress网站和OpenClaw AI网关的容器化部署实践。所有示例代码均经过生产环境验证。

    下一步学习

    建议继续学习以下主题:

  • Kubernetes:大规模容器编排
  • CI/CD:自动化部署流程
  • 微服务架构:服务拆分和治理
  • DevOps实践:持续集成和部署
  • 云原生技术:Service Mesh、Serverless
  • 实战练习

  • 将现有应用容器化
  • 搭建私有镜像仓库
  • 实现自动化部署
  • 配置监控和告警
  • 优化性能和安全
  • 相关文章

    反馈和改进
    如果您在使用本文档过程中遇到问题或有改进建议,欢迎通过以下方式联系:

    • 邮箱:tech@chencunli.com
    • 网站:https://www.chencunli.com
    • GitHub:https://github.com/yourusername

    版权声明
    本文档由Tech Future技术团队编写,遵循CC BY-NC-SA 4.0许可协议。欢迎非商业用途的转载和分享,但请注明出处。

    更新日志

    • v2.0 (2026-03-19): 全面重写,增加实战案例和最佳实践
    • v1.0 (2026-03-15): 初始版本

    关键词
    Docker、容器化、DevOps、CI/CD、微服务、PHP、Laravel、WordPress、生产环境、最佳实践、性能优化、安全

    发表评论