Docker与PHP:面向开发者的应用容器化

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么使用 Docker 容器化 PHP 应用?

现代 PHP Web 开发几乎离不开容器化。Docker 允许您将应用程序及其所有依赖项(Web 服务器、PHP 扩展、数据库)打包到一个隔离的容器中。这保证了应用程序在开发者的本地机器、测试服务器和生产环境中能够一致地运行。本文将详细讲解如何正确配置用于 PHP 的 Docker,创建一个现成的项目,并回顾最佳实践。



在 PHP 中使用 Docker 的优势

  • 环境可复现性: 告别“在我机器上能运行”的问题。
  • 隔离性: 每个应用程序都运行在自己独立的容器中,拥有所需的 PHP 版本和库。
  • 可扩展性: 使用 docker-compose 轻松运行多个应用实例。
  • 简化 CI/CD: 容器非常适合自动化构建和部署流水线。


为 PHP 应用创建 Dockerfile

让我们从最重要的文件开始 —— Dockerfile。它描述了如何构建您的 PHP 应用程序镜像。让我们看一个使用 Apache Web 服务器的 PHP 8.2 应用的基本示例。



# DockerfileFROM php:8.2-apache

# Install PHP extensionsRUN docker-php-ext-install pdo pdo_mysql mysqli

# Enable mod_rewrite for Apache (useful for frameworks)RUN a2enmod rewrite

# Copy application source codeCOPY . /var/www/html/

# Change owner for correct file permissionsRUN chown -R www-data:www-data /var/www/html

# Expose port 80EXPOSE 80


这个 Dockerfile 使用官方的 PHP 8.2 镜像(带 Apache),安装 MySQL 驱动,然后复制您的代码。对于更复杂的项目,例如基于 Laravel 或 Symfony 的项目,将需要额外的配置。



使用 Nginx 和 PHP-FPM 的 Laravel 示例

对于现代框架,通常使用 Nginx + PHP-FPM 的组合。这是一个 PHP-FPM 的 Dockerfile 示例:



# Dockerfile.php-fpmFROM php:8.2-fpm

# Install system dependencies and extensionsRUN apt-get update && apt-get install -y \ libpq-dev \ libzip-dev \ unzip \ git \ && docker-php-ext-install pdo pdo_mysql zip

# Install ComposerCOPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Copy projectWORKDIR /var/wwwCOPY . .

# Install PHP dependenciesRUN composer install --no-interaction --optimize-autoloader

# File permissions for LaravelRUN chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache

CMD ["php-fpm"]


这是 Nginx 配置,需要通过 docker-compose 将其放在一个单独的容器中:



# default.conf (for Nginx)server {    listen 80;    server_name localhost;    root /var/www/public;

add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff";

index index.php;

charset utf-8;

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

location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; }

error_page 404 /index.php;

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

location ~ /\\.(?!well-known).* { deny all; }}


使用 docker-compose 进行编排

为了管理多个容器(PHP、Nginx、MySQL),请使用 docker-compose.yml。这是本地开发和测试的标准工具。



# docker-compose.ymlversion: '3.8'

services: php: build: context: . dockerfile: Dockerfile.php-fpm container_name: php_app volumes: - .:/var/www networks: - app-network

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

mysql: image: mysql:8.0 container_name: mysql_db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: root_password MYSQL_DATABASE: app_database MYSQL_USER: app_user MYSQL_PASSWORD: app_password ports: - "3306:3306" volumes: - db_data:/var/lib/mysql networks: - app-network

networks: app-network: driver: bridge

volumes: db_data:


优化和最佳实践

为了让您的 Docker 镜像更小、更安全,请遵循以下建议:



  • 使用多阶段构建: 这样可以分离构建依赖项和运行依赖项,从而减小最终镜像的大小。
  • 不要以 root 身份运行: 始终使用 USER 指令切换到非特权用户,以增强安全性。
  • 利用 .dockerignore 文件: 排除不必要的文件(如 node_modules、.git),以加快构建速度。
  • 对非敏感数据使用环境变量: 通过 .env 文件或 Docker Secrets 管理配置。
  • 优先使用官方基础镜像: 它们经过优化并且会定期接收安全更新。


多阶段构建示例



# Stage 1: Build stageFROM composer:latest AS composer

FROM php:8.2-cli AS builder
WORKDIR /app
COPY --from=composer /usr/bin/composer /usr/bin/composer
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
COPY . .

# Stage 2: Production stageFROM php:8.2-fpm
COPY --from=builder /app /var/www
RUN docker-php-ext-install pdo_mysql
USER www-data
CMD ["php-fpm"]


容器化 PHP 应用不仅仅是一种趋势——它是为项目提供稳定、安全和可扩展环境的成熟标准。通过理解这些基本的 Docker 构建块,您将能够为您的具体需求定制配置。您可以使用哪种 PHP 框架呢?在 Docker 的加持下,它们都能完美运行!

博客

书籍推荐