0
user-people-family-house-home
>

【Docker】Docker Compose 搭建多 PHP 版本開發環境 (5.6/7.2/7.4/8.1/8.2)

本篇介紹如何利用 Docker Compose 搭建支援多個 PHP 版本(5.6 / 7.2 / 7.4 / 8.1 ...

Posted by Roy on 2026-02-26 17:52:43
1 目前 1 人正在閱讀
|
| Views

本篇介紹如何利用 Docker Compose 搭建支援多個 PHP 版本(5.6 / 7.2 / 7.4 / 8.1 / 8.2)的本地開發環境,並透過 Nginx 依站台切換 PHP 版本。

為什麼需要多 PHP 版本環境?

實務上,不同專案使用的 PHP 版本往往不同:

  • 舊專案可能還在跑 PHP 5.6 / 7.2
  • 新專案已經使用 PHP 8.1 / 8.2
  • 同時維護多個專案時,需要在同一台機器上切換版本

透過 Docker Compose,可以讓每個 PHP 版本各自跑一個獨立的 FPM 容器,Nginx 再根據每個站台的設定,把請求導到對應的 PHP-FPM,完全不互相干擾。

目錄結構

docker-setup/
├── docker-compose.yml
├── nginx/
│   ├── Dockerfile
│   ├── nginx.conf
│   └── sites/
│       ├── blog.conf          # 各站台 Nginx 設定
│       ├── php82.conf.example
│       ├── php74.conf.example
│       └── ...
├── php/
│   ├── 5.6/
│   │   ├── Dockerfile
│   │   └── conf.d/xdebug.ini
│   ├── 7.2/
│   ├── 7.4/
│   ├── 8.1/
│   └── 8.2/
├── mysql/
└── redis/

docker-compose.yml

核心設計:每個 PHP 版本獨立一個 service,共用同一個 network 讓 Nginx 可以直接呼叫各版本的 FPM。

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

volumes:
  mysql:
    driver: local
  redis:
    driver: local

services:

  nginx:
    build:
      context: ./nginx
    container_name: nginx
    volumes:
      - /var/www:/var/www          # 掛載所有專案程式碼
      - ./nginx/sites:/etc/nginx/sites-available
      - ./nginx/ssl:/etc/nginx/ssl
      - ./logs/nginx:/var/log/nginx
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - php82-fpm
      - php81-fpm
      - php74-fpm
      - php72-fpm
      - php56-fpm
    restart: always
    networks:
      - backend

  php82-fpm:
    build:
      context: ./php/8.2
      dockerfile: Dockerfile
    container_name: php82_fpm
    volumes:
      - /var/www:/var/www
      - ./php/8.2/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
    restart: always
    networks:
      - backend

  php81-fpm:
    build:
      context: ./php/8.1
      dockerfile: Dockerfile
    container_name: php81_fpm
    volumes:
      - /var/www:/var/www
    restart: always
    networks:
      - backend

  php74-fpm:
    build:
      context: ./php/7.4
      dockerfile: Dockerfile
    container_name: php74_fpm
    volumes:
      - /var/www:/var/www
    restart: always
    networks:
      - backend

  php72-fpm:
    build:
      context: ./php/7.2
      dockerfile: Dockerfile
    container_name: php72_fpm
    volumes:
      - /var/www:/var/www
    restart: always
    networks:
      - backend

  php56-fpm:
    build:
      context: ./php/5.6
      dockerfile: Dockerfile
    container_name: php56_fpm
    volumes:
      - /var/www:/var/www
    restart: always
    networks:
      - backend

  mysql:
    build:
      context: ./mysql
    container_name: mysql
    environment:
      - MYSQL_DATABASE=homestead
      - MYSQL_USER=homestead
      - MYSQL_PASSWORD=secret
      - MYSQL_ROOT_PASSWORD=root
    volumes:
      - mysql:/var/lib/mysql
    ports:
      - "3306:3306"
    restart: always
    networks:
      - backend

  redis:
    image: redis
    container_name: redis
    command: --requirepass secret
    ports:
      - "6379:6379"
    restart: always
    networks:
      - backend

PHP Dockerfile 範例

每個版本有獨立的 Dockerfile,可以各自安裝需要的 extension:

# php/8.2/Dockerfile
FROM php:8.2-fpm-alpine

RUN apk add --no-cache \
    git curl zip unzip \
    libpng-dev libjpeg-turbo-dev \
    oniguruma-dev libxml2-dev

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

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

# 安裝 Xdebug(選用)
RUN pecl install xdebug && docker-php-ext-enable xdebug
# php/7.4/Dockerfile
FROM php:7.4-fpm-alpine

RUN apk add --no-cache \
    git curl zip unzip \
    libpng-dev libjpeg-turbo-dev \
    oniguruma-dev libxml2-dev

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

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

Nginx 站台設定

重點在 fastcgi_pass,指向不同版本的 PHP-FPM container name:

# sites/blog.conf(使用 PHP 8.2)
server {
    listen 80;
    server_name local-blog.test;
    root /var/www/blog/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass php82_fpm:9000;    # 指向 PHP 8.2 容器
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    error_log /var/log/nginx/blog-error.log;
    access_log /var/log/nginx/blog-access.log;
}
# sites/legacy-app.conf(使用 PHP 7.2)
server {
    listen 80;
    server_name legacy-app.test;
    root /var/www/legacy/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass php72_fpm:9000;    # 指向 PHP 7.2 容器
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }
}

啟動環境

# 第一次啟動(build image)
docker compose up -d --build

# 查看所有容器狀態
docker compose ps

# 只啟動特定服務
docker compose up -d nginx php82-fpm mysql redis

# 停止所有服務
docker compose down

# 重啟單一服務
docker compose restart php82-fpm

進入容器執行指令

# 進入 PHP 8.2 容器
docker exec -it php82_fpm sh

# 在容器內執行 artisan 指令
docker exec php82_fpm php /var/www/blog/artisan migrate

# 查看 PHP 版本確認
docker exec php82_fpm php -v
docker exec php72_fpm php -v

各版本容器對應表

PHP 版本 Container Name Nginx fastcgi_pass 適用情境
PHP 8.2 php82_fpm php82_fpm:9000 Laravel 10/11 新專案
PHP 8.1 php81_fpm php81_fpm:9000 Laravel 9/10
PHP 7.4 php74_fpm php74_fpm:9000 Laravel 8
PHP 7.2 php72_fpm php72_fpm:9000 舊版 Laravel / WordPress
PHP 5.6 php56_fpm php56_fpm:9000 超舊系統維護

小結

透過 Docker Compose,每個 PHP 版本只需要獨立一個 FPM service,Nginx 站台設定只要改一行 fastcgi_pass 就能切換版本,多個專案並行開發不再需要手動切換環境,大幅提升開發效率。

參考文獻:

https://docs.docker.com/compose/

https://hub.docker.com/_/php

留言區

請先登入才能發表留言