You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx配置求助:根路径WordPress与子路径Symfony共存失败

Nginx配置修复:根域名WordPress + 子路径Symfony 5.4共存

原配置核心问题分析

  1. 路径映射错误:location ~ ^/symfony/中使用root会让Nginx尝试在/var/www/symfony/current/public/symfony/下查找文件,但Symfony入口文件直接在public/目录下,需用alias替代root来正确映射路径。
  2. 语法错误:location = (/|/symfony)是无效写法,无法正确匹配根路径或/symfony路径。
  3. 嵌套规则优先级冲突:内部嵌套的location ~ ^/symfony/会覆盖更具体的规则,导致部分请求被错误拦截。

修正后的完整Nginx配置

client_max_body_size 0;

# DDoS Mitigation
##Limit the number of connections per IP
limit_conn_zone $binary_remote_addr zone=engine_con:10m;
limit_conn_status 429;

##Limit the number of requests per session
limit_req_zone $binary_remote_addr zone=engine_req:10m rate=50r/s;
limit_req_zone $binary_remote_addr zone=static_req:10m rate=100r/s;
limit_req_status 429;
# End DDoS Mitigation

server {
    listen 80;
    listen [::]:80;
    server_name my-website.fr www.my-website.fr;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "0";
    add_header Referrer-Policy origin-when-cross-origin;
    add_header Feature-Policy "midi 'none';";
    return 301 https://my-website.fr$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.my-website.fr;
    ssl_certificate /etc/letsencrypt/live/my-website.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my-website.fr/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "0";
    add_header Referrer-Policy origin-when-cross-origin;
    add_header Feature-Policy "midi 'none';";
    return 301 https://my-website.fr$request_uri;
}

server {
    listen [::]:443 ssl ipv6only=on http2;
    listen 443 ssl http2;

    ssl_certificate /etc/letsencrypt/live/my-website.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my-website.fr/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    server_name my-website.fr;

    # WordPress根目录配置
    root /var/www/wordpress;
    index index.php;

    add_header Strict-Transport-Security 'max-age=15768000; includeSubDomains; preload';
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "0";
    add_header Referrer-Policy origin-when-cross-origin;
    add_header Feature-Policy "midi 'none';";
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types application/font-woff application/javascript application/rss+xml application/vnd.ms-fontobject application/x-font application/x-font-opentype application/x-font-otf application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/opentype font/otf font/ttf image/svg+xml image/x-icon text/css text/javascript text/plain text/xml;

    auth_basic "Restricted Area";
    auth_basic_user_file /etc/nginx/htpasswd;

    # DDoS Mitigation
    limit_conn engine_con 100;
    # End DDoS

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
    
    # 修正路径跳转规则
    location = /symfony {
        return 301 https://my-website.fr/symfony/fr/;
    }

    # Symfony子路径核心配置:用alias替代root
    location ^~ /symfony/ {
        alias /var/www/symfony/current/public/;
        index index.php;

        limit_conn engine_con 100;

        # API路径限流
        location ^~ /symfony/api/ {
            limit_req zone=engine_req burst=5 nodelay;
            try_files $uri $uri/ /symfony/index.php$is_args$args;
        }

        # 静态资源路径限流+缓存
        location ~ ^/symfony/(assets|bundles|images|json)/ {
            limit_req zone=static_req burst=10 nodelay;
            expires 1y;
            add_header Cache-Control "public, immutable";
        }

        location ~ ^/symfony/media/cache/(?!resolve)/ {
            limit_req zone=static_req burst=10 nodelay;
            expires 1y;
            add_header Cache-Control "public, immutable";
        }

        # 媒体资源解析路由
        location ~ ^/symfony/media/cache/resolve/ {
            try_files $uri /symfony/index.php$is_args$args;
        }

        # elfinder特殊路由
        location ~ /symfony/elfinder\.main\.js$ {
            try_files $uri /symfony/index.php$is_args$args;
        }

        # Symfony入口文件处理
        location ~ ^/symfony/index.php(/|$) {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;
            fastcgi_param APP_ENV prod; # 根据实际环境调整
            fastcgi_buffers 16 32k;
            fastcgi_buffer_size 32k;
            fastcgi_busy_buffers_size 32k;
            internal;
        }

        # 上传文件类型限制
        location ~ ^/symfony/uploads/ {
            if ($request_filename !~* \.(gif|jpe?g|jfif|png|ico|tiff?|pdf|xml|docx?|xlsx?|pptx?|csv)$) {
                return 404;
            }
        }

        # 后台路径独立认证
        location ^~ /symfony/admin/ {
            auth_basic "Restricted Area";
            auth_basic_user_file /etc/nginx/htpasswd-exports;
        }

        # 日志文件访问配置
        location ~ ^/symfony/server/log/(.*)$ {
            add_header Content-Type text/html;
            auth_basic "Restricted Area";
            auth_basic_user_file /etc/nginx/htpasswd-tools;
            alias /var/www/symfony/shared/var/log/$1;
            autoindex on;
        }

        # 隐藏隐藏文件
        location ~ /\. {
            return 404;
        }

        # 禁止直接访问PHP文件
        location ~ \.php$ {
            return 404;
        }
    }

    # WordPress核心路由
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    # WordPress PHP文件处理
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_intercept_errors on;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $document_root;
    }

    # WordPress静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }
}

关键修正点说明

  1. 路径映射替换:将root改为alias,确保/symfony/路径直接映射到Symfony的public/目录,避免路径拼接错误。
  2. 提升规则优先级:给Symfony路径添加^~,确保Nginx优先匹配该路径,不会被WordPress的通用规则拦截。
  3. 修正跳转语法:拆分错误的跳转规则为单独的location = /symfony,解决语法问题。
  4. 优化静态资源:给Symfony静态资源添加长期缓存头,提升访问性能。
  5. 明确环境变量:添加APP_ENV参数,确保Symfony加载对应环境的配置。

验证步骤

  1. 测试并重新加载Nginx配置:sudo nginx -t && sudo systemctl reload nginx
  2. 确认Symfony目录权限:sudo chown -R www-data:www-data /var/www/symfony/current/public
  3. 分别访问根域名和/symfony/fr/路径,验证两个应用是否正常加载。

内容的提问来源于stack exchange,提问作者Skuti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:37:04