我正在创建一个“userdir”配置,其中 Web 服务器为每个用户的 ~/www 目录内的文件提供服务。
我有以下配置片段:
server {
listen 443;
listen [::]:433;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
server_name ~^(?<user>\w+)\.example\.com$;
root /var/www/userdir;
index index.html;
error_page 404 = @not_found;
add_header X-User $user;
location / {
root /home/$user/www;
try_files $uri $uri/ =404;
}
location @not_found {
if (-f /home/$user/www/404.html)
{
root /home/$user/www;
}
try_files /404.html =500;
}
}
当请求不存在的文件时,@not_found
将输入指定的位置。它首先检查用户是否有自定义 404 页面,如果有,它会在尝试提供 404.html 之前将文档根目录设置为用户的目录。
但是配置块的结果是,如果用户目录中存在 404.html,则返回通用 nginx 404 页面;如果不存在,则返回 /var/www/userdir/404.html。
答案1
if
在块内使用location
是违反直觉的,因为这个文件说明。此外,使用error_page
命名位置会将响应代码从 404 更改为 200,这可能不是所希望的。
您可以使用测试在块顶部设置一个变量server
,然后可以使用它来设置错误页面文件的位置。
例如:
set $ERROR_ROOT "/var/www/userdir";
if (-f /home/$user/www/404.html) {
set $ERROR_ROOT "/home/$user/www";
}
error_page 404 /404.html;
location / {
root /home/$user/www;
try_files $uri $uri/ =404;
}
location = /404.html {
root $ERROR_ROOT;
}
答案2
这似乎可以解决问题:
location / {
root /home/$user/www;
try_files $uri $uri/ =404;
error_page 404 /404.html;
}
您可能需要删除“error_page 404 = @not_found;”。