跳转到内容
搜索 Fedora 文档

    浏览当前文档目录

    在 Fedora 上搭 nginx + PHP-FPM:从默认页到跑通 PHP 8.5

    Fedora 上搭 Web 服务只需要两个包,而且都很小:

    Terminal window
    sudo dnf install nginx php-fpm
    nginx version: nginx/1.30.5
    PHP 8.5.12 (fpm-fcgi) (built: Oct 19 2026 17:02:46) (NTS gcc x86_64)

    nginx 包只有 126.5 KiB(安装后 123.6 KiB 级别),php-fpm 是 PHP 的一部分。

    nginx 经 Unix socket 交给 php-fpm,以及 SELinux 端口标签的限制

    Terminal window
    sudo systemctl enable --now nginx php-fpm
    systemctl is-active nginx php-fpm
    active
    active

    nginx 默认监听 80:

    Terminal window
    ss -lntp | grep :80
    LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
    LISTEN 0 511 [::]:80 [::]:*

    访问本机:

    Terminal window
    curl -s http://127.0.0.1/ | grep -oE "Fedora|nginx" | head -2
    Fedora

    这是 Fedora 自带的欢迎页,根目录在 /usr/share/nginx/html。

    php-fpm 默认不走 TCP,走 Unix socket:

    Terminal window
    ss -lx | grep php
    /run/php-fpm/www.sock

    池配置在 /etc/php-fpm.d/www.conf:

    user = apache
    group = apache
    listen = /run/php-fpm/www.sock
    listen.acl_users = apache,nginx

    listen.acl_users 里已经有 nginx——这是 Fedora/上游打包特意留的,nginx 进程有权限读写这个 socket,不用自己改属主。

    在 /etc/nginx/conf.d/ 放一个 server 块(这里是实测可用的完整配置):

    server {
    listen 8008;
    server_name _;
    root /usr/share/nginx/html;
    index index.php index.html;
    location ~ \.php$ {
    fastcgi_pass unix:/run/php-fpm/www.sock;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
    }
    Terminal window
    sudo nginx -t
    sudo systemctl reload nginx
    nginx: configuration file /etc/nginx/nginx.conf test is successful

    写一个测试文件:

    Terminal window
    printf '<?php echo "PHP " . PHP_VERSION . " OK\n"; ?>' | \
    sudo tee /usr/share/nginx/html/demo.php >/dev/null

    访问:

    Terminal window
    curl -s http://127.0.0.1:8008/demo.php
    PHP 8.5.12 OK

    这就是全链路打通了:nginx → Unix socket → php-fpm 8.5.12。

    关键坑:SELinux 不让 nginx 绑非标准端口

    Section titled “关键坑:SELinux 不让 nginx 绑非标准端口”

    我最初用 8081 起这个 server,nginx -t 成功、reload 也成功,但访问直接连不上。看错误日志:

    [emerg] bind() to 0.0.0.0:8081 failed (13: Permission denied)

    这不是权限位问题,是 SELinux——nginx 只允许绑定标记为 http_port_t 的端口:

    Terminal window
    sudo semanage port -l | grep '^http_port_t'
    http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
    http_port_t udp 80, 443

    8081 不在里面,8008 在。所以要么换到已允许的端口(我就是改成 8008 后一次跑通),要么显式加标签:

    Terminal window
    sudo semanage port -a -t http_port_t -p tcp 8081

    默认根目录 /usr/share/nginx/html,把文件丢进去即可:

    Terminal window
    sudo cp -r mysite/* /usr/share/nginx/html/

    如果放到别处(比如 /srv/www),要同时处理两件事:

    Terminal window
    # 1. SELinux 标签
    sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
    sudo restorecon -Rv /srv/www
    # 2. nginx 配置里的 root

    只改 root 不改标签,nginx 会返回 403 Forbidden——文件明明存在且有读权限,但 SELinux 上下文不对。原理见 SELinux。

    默认防火墙只开了三项:

    Terminal window
    sudo firewall-cmd --list-services
    dhcpv6-client mdns ssh

    放行 HTTP:

    Terminal window
    sudo firewall-cmd --add-service=http --permanent
    sudo firewall-cmd --reload

    HTTPS 同理用 --add-service=https。细节见防火墙。

    Terminal window
    sudo nginx -t # 改完配置先测语法
    sudo systemctl reload nginx # 平滑重载,不断连接
    sudo systemctl restart php-fpm # 改了 php.ini 或池配置才需要
    tail -f /var/log/nginx/error.log # 排障第一现场
    tail -f /var/log/php-fpm/www-error.log

    reload 和 restart 的区别:reload 不掐断已有连接,改 nginx 配置用 reload 就够;php-fpm 的池配置(www.conf)改了要 restart。

    现象原因
    bind() ... (13: Permission denied)SELinux 不允许该端口,换 http_port_t 里的端口或 semanage port -a
    PHP 页面返回 404少了 fastcgi_param SCRIPT_FILENAME
    静态文件 403SELinux 上下文不是 httpd_sys_content_t
    502 Bad Gatewayphp-fpm 没起来,或 socket 路径写错
    改了配置没生效忘了 systemctl reload nginx
    外网访问不了防火墙没放行 http
    中文路径/文件名乱码检查 charset utf-8; 与文件系统编码