在实际的项目部署中,我们有时候会遇到在一个服务器上部署多个 php 环境的情况。遇到这种情况,我们可以在同一物理机上装多个 php-fpm 监听不同端口,Nginx 根据不同的 Vhost 去找不同的 php-fpm 解析。
上述方法虽然可以,但是在项目管理上并不是很友好,比如我需要在某个项目执行 PHP 脚本,那还需要写 /path/php script.php 这样的话就需要每个维护项目的人都十分清楚,哪个项目应该用哪个版本的 PHP 去执行相应的脚本。
其次,如果某天需要把某个项目迁移到其他服务器了,我们还需要在新机器上安装 PHP 环境。
如果用 docker 进行部署,就不会有上面的问题,我们只需要写一次 Dockfile 可以在任何服务器上构建出相同的 php-fpm 环境,从而让迁移更简单,如果需要执行脚本,只需要进入对应的容器,直接执行 php script.php 即可。
php-fpm 官方镜像介绍
在 php Tags | Docker Hub 找到你所需的基础镜像的 tag
扩展安装
Docker PHP 安装有三种方式
Core Extensions:
FROM php:8.2-fpm
RUN apt-get update && apt-get install -y \
libfreetype-dev \
libjpeg62-turbo-dev \
libpng-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd
PECL extensions :
FROM php:8.2-cli
RUN pecl install redis-5.3.7 \
&& pecl install xdebug-3.2.1 \
&& docker-php-ext-enable redis xdebug
手动编译安装:
FROM php:8.2-cli
RUN curl -fsSL '[url-to-custom-php-module]' -o module-name.tar.gz \
&& mkdir -p module-name \
&& sha256sum -c "[shasum-value] module-name.tar.gz" \
&& tar -xf module-name.tar.gz -C module-name --strip-components=1 \
&& rm module-name.tar.gz \
&& ( \
cd module-name \
&& phpize \
&& ./configure --enable-module-name \
&& make -j "$(nproc)" \
&& make install \
) \
&& rm -r module-name \
&& docker-php-ext-enable module-name
php 配置文件介绍
如果你需要修改或新增 php 的配置,可以在 /usr/local/etc/php/conf.d/
里建立对应的配置文件,然后把配置写在里面重启容器即可。
比如我想覆盖 php-fpm 对于上传文件的限制,就可以按照下面的脚本来实现。
echo "file_uploads = On" >> /usr/local/etc/php/conf.d/uploads.ini \
&& echo "memory_limit = 64M" >> /usr/local/etc/php/conf.d/uploads.ini \
&& echo "upload_max_filesize = 64M" >> /usr/local/etc/php/conf.d/uploads.ini
Dockerfile
FROM php:7.3.8-fpm
RUN cd /tmp \
&& php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" \
&& php composer-setup.php \
&& php -r "unlink('composer-setup.php');" \
&& mv composer.phar /bin/composer \
&& composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ \
&& composer clear
RUN echo " " > /etc/apt/sources.list \
&& echo "deb http://mirrors.aliyun.com/debian buster main" >> /etc/apt/sources.list \
&& echo "deb http://mirrors.aliyun.com/debian-security buster/updates main" >> /etc/apt/sources.list \
&& echo "deb http://mirrors.aliyun.com/debian buster-updates main" >> /etc/apt/sources.list \
&& echo "file_uploads = On" >> /usr/local/etc/php/conf.d/uploads.ini \
&& echo "memory_limit = 64M" >> /usr/local/etc/php/conf.d/uploads.ini \
&& echo "upload_max_filesize = 64M" >> /usr/local/etc/php/conf.d/uploads.ini \
&& echo "post_max_size = 64M" >> /usr/local/etc/php/conf.d/uploads.ini \
&& echo "max_execution_time = 600" >> /usr/local/etc/php/conf.d/uploads.ini \
&& apt-get update \
&& apt-get install -y --no-install-recommends git vim libpng-dev libjpeg-dev libfreetype6-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
Run pecl install redis \
&& docker-php-ext-enable redis \
&& docker-php-ext-install mysqli \
&& docker-php-ext-install pdo_mysql bcmath\
&& docker-php-ext-configure gd --enable-gd-native-ttf --with-freetype-dir=DIR --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/ && docker-php-ext-install gd
WORKDIR /var/www
EXPOSE 9000
CMD ["php-fpm"]
上述 Dockerfile 基于 php:7.3.8-fpm
安装了所需扩展
构建镜像
docker build -t php73 .
启动镜像
docker run -p 9001:9000 -d --name php-fpm73 -v /path/to/project:/opt/www -it php73
配置 Nginx
...
# 配置 php 文件解析
location ~ [^/]\.php(/|$)
{
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9001;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
...
systemctl reload nginx
重载 nginx 使配置生效。
到此就完成了使用 docker php-fpm 去解析 PHP 对应的脚本了。