Docker中启动php-fpm服务,解决仅监听IPv6无法访问9000端口问题
问题描述
以下为用于构建PHP运行环境的Dockerfile:
FROM php:7.4-fpm RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ libmcrypt-dev \ gcc \ make \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) gd RUN set -xe; \ apt-get update -yqq && \ pecl channel-update pecl.php.net && \ apt-get install -yqq \ apt-utils \ libzip-dev zip unzip && \ docker-php-ext-configure zip; \ docker-php-ext-install zip && \ php -m | grep -q 'zip' RUN docker-php-ext-install pdo_mysql RUN apt-get install -y nano RUN apt-get install -y build-essential cron RUN apt-get install -y cron RUN apt-get install -y procps RUN apt-get install -y net-tools RUN apt-get update && apt-get install libmagickwand-dev -y --no-install-recommends \ && pecl install imagick-3.5.1 \ && docker-php-ext-enable imagick RUN apt-get install -y ghostscript COPY --from=composer /usr/bin/composer /usr/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin WORKDIR /var/www RUN apt-get install -y git COPY ./src /var/www COPY ./php/php.ini /usr/local/etc/php/php.ini COPY ./php/policy.xml /etc/ImageMagick-6/policy.xml RUN chmod -R 777 /var/www/storage RUN chmod -R 777 /var/www/bootstrap
使用该Dockerfile可以正常创建容器,但容器内没有可正常访问的服务。进入容器查看端口监听状态,发现服务仅接收IPv6协议的请求:
tcp6 0 0 :::9000 :::* LISTEN
诉求为可以通过curl localhost:9000的方式访问fpm-cgi服务,需要确认需要调整的配置项。
问题原因
- 官方
php:7.4-fpm镜像默认的FPM进程池配置文件/usr/local/etc/php-fpm.d/www.conf中,默认监听地址为[::]:9000,当容器内核参数net.ipv6.bindv6only=1时,该监听地址仅绑定IPv6协议栈,不会接收IPv4侧的请求,因此IPv4地址的9000端口无法访问。 - 关键提示:PHP-FPM是FastCGI协议服务,本身不支持直接解析HTTP请求,即使端口正常监听,直接用curl发送HTTP请求访问9000端口也无法得到正常的HTTP响应,这是协议特性决定的,不属于配置错误。
解决方案
- 调整FPM监听地址配置,在Dockerfile中添加指令修改默认监听规则,强制绑定IPv4地址:
重新构建镜像启动容器后,再查看端口监听会看到IPv4的9000端口处于LISTEN状态,此时IPv4侧的连通性恢复。# 放在COPY配置文件的相关指令附近即可 RUN sed -i 's/listen = \[::\]:9000/listen = 0.0.0.0:9000/' /usr/local/etc/php-fpm.d/www.conf - 访问验证注意事项:
- 如果仅验证端口连通性,不要使用curl,可使用
nc -zv localhost 9000或者telnet localhost 9000测试。 - 如果需要通过HTTP形式访问PHP服务,需要额外部署Nginx作为Web服务器,配置Nginx将PHP请求转发为FastCGI协议请求发送给FPM处理,不能直接对FPM端口发起HTTP请求。
- 如果仅验证端口连通性,不要使用curl,可使用
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

