Docker 容器化技术已成为现代应用部署的标准方式之一,尤其对于 PHP 应用而言,Docker 能够提供一致的开发和生产环境,简化部署流程,提高资源利用率。本文将详细介绍如何使用 Docker 部署 PHP 应用的完整流程,包括环境准备、容器配置、应用部署及常见问题解决。

问题背景与适用场景

传统 PHP 应用部署常面临环境不一致、依赖冲突、扩展配置困难等问题。Docker 通过容器化技术解决了这些问题,特别适用于以下场景:

  • 多人协作开发时确保环境一致性
  • 需要快速创建和销毁开发环境
  • 应用需要跨平台部署
  • 微服务架构中 PHP 服务的独立部署
  • CI/CD 流程中的自动化部署

准备工作

在开始之前,确保已安装以下软件:

  • Docker (版本 20.10+)
  • Docker Compose (版本 1.29+)

验证安装:

docker --version
docker-compose --version

创建一个基本的 PHP 项目结构,包含以下文件:

php-app/
├── src/
│   └── index.php
├── Dockerfile
├── docker-compose.yml
└── nginx.conf

原理讲解

Docker 部署 PHP 应用的核心原理基于容器化技术:

  1. 镜像 (Image): 包含应用运行所需的完整环境,包括操作系统、PHP 解释器、扩展和依赖
  2. 容器 (Container): 镜像的运行实例,隔离了应用及其依赖
  3. 网络与存储: Docker 提供容器间的网络通信和数据持久化机制

PHP 应用容器化通常采用多容器架构,包括:

  • PHP-FPM 容器:处理 PHP 代码执行
  • Nginx 容器:处理静态文件和反向代理
  • 数据库容器:提供数据存储(可选)

操作步骤

1. 编写 Dockerfile

创建 PHP-FPM 容器的 Dockerfile:

# 使用官方 PHP 镜像作为基础
FROM php:8.1-fpm

# 安装系统依赖和 PHP 扩展
RUN apt-get update && apt-get install -y \
    libzip-dev \
    unzip \
    && docker-php-ext-install pdo_mysql zip

# 安装 Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# 设置工作目录
WORKDIR /var/www/html

# 复制应用代码
COPY src/ .

# 设置目录权限
RUN chown -R www-data:www-data /var/www/html

2. 配置 docker-compose.yml

创建 docker-compose.yml 文件定义服务:

version: '3.8'

services:
  php:
    build: .
    volumes:
      - ./src:/var/www/html
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

3. 配置 Nginx

创建 nginx.conf 文件配置 PHP-FPM 连接:

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    root /var/www/html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

4. 构建和运行容器

在项目根目录执行以下命令:

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

# 查看容器状态
docker-compose ps

# 查看日志
docker-compose logs -f

5. 管理容器生命周期

# 停止容器
docker-compose down

# 重新构建容器
docker-compose up --build -d

# 进入容器
docker-compose exec php bash

示例代码

创建一个简单的 PHP 应用示例文件 src/index.php:

<?php
// 获取容器信息
$containerId = substr(exec('cat /proc/1/cgroup | grep -oP "[0-9a-f]{64}"'), 0, 12);
$hostName = gethostname();

// 显示 PHP 信息
phpinfo();
?>

常见问题与排错

1. 权限问题

现象: 无法写入文件或目录
解决: 确保 Docker 容器内的用户与主机用户 UID/GID 一致,或使用 volumes 的 :cached 或 :delegated 挂载选项

2. 端口冲突

现象: 容器启动失败,提示端口被占用
解决: 检查主机端口占用情况,修改 docker-compose.yml 中的端口映射

3. 文件挂载问题

现象: 代码更改后容器内未更新
解决:

  • 使用 docker-compose up --build -d 重新构建
  • 检查 volume 配置是否正确
  • 对于 macOS/Windows 用户,考虑使用 Docker 的文件同步优化选项

4. PHP 扩展安装失败

现象: 构建 Dockerfile 时安装扩展失败
解决:

  • 确认基础镜像版本与扩展兼容性
  • 检查系统依赖是否安装完整
  • 使用 docker-php-ext-install 命令安装扩展

5. 网络连接问题

现象: Nginx 无法连接到 PHP-FPM
解决:

  • 确认 docker-compose.yml 中网络配置正确
  • 检查 PHP-FPM 监听地址配置
  • 验证容器间网络连通性

总结

Docker 部署 PHP 应用通过容器化技术解决了环境一致性和部署复杂性问题。通过合理配置 Dockerfile、docker-compose.yml 和 Nginx,可以实现高效、可移植的 PHP 应用部署流程。在实际应用中,还需注意性能优化、安全性配置和日志管理等方面,以确保生产环境的稳定运行。

主楼