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

NGINX虚拟子目录配置问题:多区域路径继承现有规则

Fixing NGINX Virtual Subdirectory Static Asset Loading Issues

Alright, let's tackle this NGINX problem you're dealing with. So you've got a working config for www.site.com pointing to /srv/public_html, but when you added virtual subdirectories like /us, /ca, and /fr-ca (all supposed to use the same document root), static assets broke even though the root index.php loads fine. That makes sense—the issue is NGINX isn't stripping the virtual prefix when resolving static file paths, so it's looking for /srv/public_html/us/css/style.css instead of the correct /srv/public_html/css/style.css.

Here's how to fix this properly, making sure the virtual subdirectories fully inherit your existing rules:

1. Core Virtual Subdirectory Location Block

First, add a location block that matches your virtual prefixes, strips them from the request URI, and passes the rest through to your existing root rules. This ensures all requests to /us/xxx are treated like they're going to /xxx:

# Match our virtual subdirectories: /us, /ca, /fr-ca
location ~ ^/(us|ca|fr-ca)(/.*)?$ {
    # Keep using our existing document root
    root /srv/public_html;
    
    # Strip the virtual prefix from the request URI
    rewrite ^/(us|ca|fr-ca)(/.*)?$ $2 break;
    
    # Inherit our existing index file rules
    index index.php index.html index.htm;
    
    # Reuse the existing try_files logic for clean URLs/rewrites
    try_files $uri $uri/ /index.php?$args;
    
    # If you have other root-level rules (like CORS headers, security settings), copy them here too
}

2. Fix Static Asset Handling

If you have dedicated location blocks for static assets (like CSS, JS, images), you need to make sure they also handle the virtual prefixes. You can either adjust the existing blocks or nest them inside the virtual subdirectory block for cleaner organization.

Option A: Adjust Existing Static Asset Rules

Update your existing static asset location to recognize and strip the virtual prefix:

# Updated static asset rule that works with both root and virtual subdirectories
location ~ ^/(us|ca|fr-ca)/(.+\.(css|js|png|jpg|gif|svg))$ {
    root /srv/public_html;
    rewrite ^/(us|ca|fr-ca)/(.+)$ /$2 break;
    
    # Keep your existing cache/expiry rules here
    expires 30d;
    add_header Cache-Control "public, no-transform";
}

# Keep the original rule for root-level static assets
location ~* \.(css|js|png|jpg|gif|svg)$ {
    expires 30d;
    add_header Cache-Control "public, no-transform";
}

Option B: Nest Static Asset Rules (Cleaner Approach)

If you prefer to keep all virtual subdirectory logic contained, nest the static asset and PHP rules inside the main virtual prefix location block:

location ~ ^/(us|ca|fr-ca)(/.*)?$ {
    root /srv/public_html;
    rewrite ^/(us|ca|fr-ca)(/.*)?$ $2 break;
    index index.php index.html;
    try_files $uri $uri/ /index.php?$args;
    
    # Nest static asset handling for virtual subdirectories
    location ~* \.(css|js|png|jpg|gif)$ {
        expires 30d;
        add_header Cache-Control "public";
    }
    
    # Nest PHP processing (match your existing PHP config)
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # Adjust to your PHP-FPM socket/path
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

3. Key Things to Remember

  • Avoid alias here: While alias /srv/public_html; might seem like a shortcut, it can cause unexpected path issues with try_files and complex rewrites. Using root + rewrite is more reliable for inheriting root-level rules.
  • Check relative vs absolute paths: If your HTML uses relative paths (like css/style.css), browsers will automatically append the virtual prefix (e.g., /us/css/style.css), which our rewrite rules fix. If you use absolute paths (like /css/style.css), they'll work fine out of the box.
  • Test before reloading: Always run nginx -t to check for syntax errors, then reload with systemctl reload nginx (or your distro's equivalent) to apply changes.

Full Working Config Example

Here's how this fits into a complete server block, assuming your original root config was already working:

server {
    listen 80;
    server_name www.site.com;
    root /srv/public_html;
    index index.php index.html;
    
    # Virtual subdirectory handling
    location ~ ^/(us|ca|fr-ca)(/.*)?$ {
        rewrite ^/(us|ca|fr-ca)(/.*)?$ $2 break;
        try_files $uri $uri/ /index.php?$args;
        
        location ~ \.php$ {
            fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
        
        location ~* \.(css|js|png|jpg)$ {
            expires 30d;
            add_header Cache-Control "public";
        }
    }
    
    # Original root directory rules (unchanged)
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    
    location ~* \.(css|js|png|jpg)$ {
        expires 30d;
        add_header Cache-Control "public";
    }
}

This setup will make /us, /ca, and /fr-ca behave exactly like your root directory—all static assets load correctly, and your existing rewrite/PHP rules are fully inherited.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:33:13