Estou configurando o nginx para lidar com algumas páginas de erro e outros arquivos de mídia "padrão" (como favicon.ico e robots.txt) no momento, e tive um pequeno problema para que as coisas funcionassem da maneira que desejo para determinadas páginas de erro .
Basicamente, o que estou tentando fazer é fornecer determinados arquivos para um servidor na raiz desse servidor, por exemplo, /var/www/someserver.com/robots.txt. Se esse arquivo não existir, quero que o nginx vá para o "padrão", ou seja, /var/www/default/robots.txt. Esta é a essência básica de como eu tenho isso (com sucesso) configurado:
server {
...
root /var/www/someserver.com;
location ~* ^/(robots\.txt)$ {
error_page 404 = @default;
}
location @default {
root /var/www/default;
}
}
Isso funciona muito bem.
Estou tentando fazer o mesmo com páginas de erro e, no entanto, não consigo fazer isso acontecer:
server {
...
root /var/www/someserver.com;
error_page 404 /404.html;
location ~* ^/(404\.html)$ {
error_page 404 = @default;
}
location @default {
root /var/www/default;
}
}
Observe que isso "funciona" no sentido de que se você visitar someserver.com/404.html, primeiro tentará carregar /var/www/someserver.com/404.html e depois voltará para / var / www / default /404.html se não for encontrado. No entanto, se você visitar someserver.com/blahblah, ele exibirá a página 404 apenas se estiver definida em /var/www/someserver.com/. Ele não retorna ao diretório padrão se esse arquivo não existir.
De qualquer forma, você pode provavelmente o que eu estava tentando realizar (foi por isso que incluí o primeiro exemplo de trabalho).
Alguma ideia?
Editar:
Com base na resposta de Martin F, foi o que acabei montando:
# Doesn't work when error page is returned on a POST request
server {
...
root /var/www/someserver.com;
error_page 404 = @notfound;
error_page 500 502 504 = @server_error;
error_page 503 = @maintenance;
location @notfound {
try_files /404.html /../default/404.html =404;
}
location @server_error {
try_files /500.html /../default/500.html =500;
}
location @maintenance {
try_files /503.html /../default/503.html =503;
}
}
Isso funciona demais. O bloco real de páginas de erro e locais acima está em um arquivo server_defaults.conf que é incluído em todos os hosts virtuais, por isso não codifiquei o caminho em cada local e usei um caminho relativo para os padrões.
Edição 2:
Essa abordagem tem um problema. Se você POSTAR em um URL que retorne um erro, o método de solicitação POST será enviado com as tentativas try_files. Isso (para mim) resulta em um erro 405 não permitido, porque o nginx está essencialmente tentando POST para, por exemplo, /default/500.html, em vez de apenas obter a página.
Edição 3:
Postei uma solução que funciona muito mais próxima da minha ideia original.