Skip to content

部署 PHP

快速启动 PHP 环境

bash
# 运行 PHP 内置服务器(测试用)
docker run -d \
  --name php-test \
  -p 8080:8080 \
  -v $(pwd):/app \
  -w /app \
  php:8.3-alpine \
  php -S 0.0.0.0:8080

Nginx + PHP-FPM(推荐生产方式)

yaml
# docker-compose.yml
services:
  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - ./src:/var/www/html:ro
      - ./nginx/php.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - php-fpm
    networks:
      - web

  php-fpm:
    image: php:8.3-fpm-alpine
    restart: unless-stopped
    volumes:
      - ./src:/var/www/html
      - ./php/php.ini:/usr/local/etc/php/conf.d/custom.ini:ro
    networks:
      - web

  mysql:
    image: mysql:8.0
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - web

volumes:
  mysql-data:

networks:
  web:

Nginx 配置(nginx/php.conf):

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

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

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

自定义 PHP 镜像(含扩展)

dockerfile
FROM php:8.3-fpm-alpine

# 安装系统依赖
RUN apk add --no-cache \
    libpng-dev \
    libjpeg-turbo-dev \
    libwebp-dev \
    freetype-dev \
    libzip-dev \
    icu-dev

# 安装 PHP 扩展
RUN docker-php-ext-configure gd \
      --with-freetype \
      --with-jpeg \
      --with-webp \
    && docker-php-ext-install \
       pdo_mysql \
       mysqli \
       gd \
       zip \
       intl \
       opcache \
       bcmath

# 安装 Redis 扩展
RUN apk add --no-cache --virtual .build-deps $PHPIZE_DEPS \
    && pecl install redis \
    && docker-php-ext-enable redis \
    && apk del .build-deps

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

WORKDIR /var/www/html

# 配置 PHP
COPY php.ini /usr/local/etc/php/conf.d/custom.ini

USER www-data

Laravel 应用部署

dockerfile
FROM php:8.3-fpm-alpine AS deps

RUN apk add --no-cache libzip-dev icu-dev \
    && docker-php-ext-install pdo_mysql zip intl opcache

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

WORKDIR /app

COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts

FROM php:8.3-fpm-alpine AS runtime

RUN apk add --no-cache libzip-dev icu-dev \
    && docker-php-ext-install pdo_mysql zip intl opcache

WORKDIR /app

COPY --from=deps /app/vendor ./vendor
COPY . .

RUN php artisan config:cache \
    && php artisan route:cache \
    && php artisan view:cache \
    && chown -R www-data:www-data storage bootstrap/cache

USER www-data

EXPOSE 9000
CMD ["php-fpm"]

WordPress 快速部署

yaml
services:
  wordpress:
    image: wordpress:php8.3-apache
    restart: unless-stopped
    ports:
      - "80:80"
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: wppassword
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress-data:/var/www/html
    depends_on:
      - mysql

  mysql:
    image: mysql:8.0
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: wppassword
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  wordpress-data:
  mysql-data:

PHP 配置优化

ini
; php/php.ini
memory_limit = 256M
max_execution_time = 60
upload_max_filesize = 50M
post_max_size = 50M
date.timezone = Asia/Shanghai

; OPcache 配置(生产环境)
opcache.enable = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 0