6 meses depois, aqui está sua solução mais limpa.
# config/environments/production.rb
config.ssl_options = { exclude: proc { |env| env['PATH_INFO'].start_with?('/health_check') } }
Eu quero rodar todo o meu aplicativo Rails com SSL, então eu pensei em usar a opção de configuração global force_ssl do Rails, que funciona muito bem, exceto que o healthbecker do ELB nunca funcionará porque se eu configurá-lo para http, o Rails https com um 301 e a verificação de integridade falhará, pois não é 200. Se eu configurá-lo para https, o nginx / rails não conseguirá manipular a solicitação, já que o SSL é tratado pelo ELB e o nginx / rails está manipulando apenas HTTP .
Minha solução não ideal seria abrir uma exceção para a global force_ssl
apenas para a página de verificação de integridade, mas o global force_ssl
config do Rails sempre substitui o force_ssl :except => :health_check
, então parece que não funciona.
Outra solução seria não usar o ELB para terminação SSL, e configurar o HAProxy, mas eu quero usar a infraestrutura da Amazon o máximo possível para as coisas, para me concentrar mais no desenvolvimento principal do projeto ao invés da infraestrutura. / p>
Este é meu primeiro post de falha de servidor, então eu agradeço qualquer ajuda que eu possa obter (ou mais informações que eu possa dar). Obrigado.
Atualização:
Até agora, "resolvi" isso fazendo com que o ELB acessasse a instância do EC2 por uma porta diferente da 80, que somente ela pode acessar, o que parece extremo, mas mantém uma separação entre o aplicativo e as camadas do servidor. Se a solicitação healthcheck vier do ELB a partir desta porta, o nginx encaminhará o cabeçalho X-Forwarded-Proto para 'https', o que permitirá que o Rack pense que ele veio através do SSL e deixe-o passar. Para todos os outros tráfegos vindos da porta padrão 80, ele apenas encaminha o cabeçalho X-Forwarded-Proto dado pelo ELB, que informará com precisão o que o usuário externo estava usando, e permitirá que o Rails decida forçar https ou não dependendo. / p>
Ainda aguardando uma solução mais limpa, mas é isso que tenho.
6 meses depois, aqui está sua solução mais limpa.
# config/environments/production.rb
config.ssl_options = { exclude: proc { |env| env['PATH_INFO'].start_with?('/health_check') } }
Deve-se observar que a opção de exclusão para config.ssl_options está obsoleta e você precisa use a gem do rack-ssl para obter o mesmo comportamento .
Não pareceu uma boa idéia incluir e inicializar um novo middleware de rack apenas para a verificação de integridade, então decidi usar o nginx para definir o cabeçalho $ http_x_forwarded_proto para o verificador de integridade.
Veja o que eu criei:
location @unicorn {
if ($http_user_agent ~ "ELB-HealthChecker")
{
set $http_x_forwarded_proto https;
}
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
Agora o rails vê as solicitações do Health Checker como https (embora não sejam) e retorna com sucesso.
Depois de dias com wrestling com configs, etc eu encontrei esta grande jóia:
Não há necessidade de nenhuma configuração nginx personalizada (funciona através do rack). Ele retorna 200
on / healthcheck, que funciona como um encanto. Basta adicioná-lo às suas gemas e pronto.
f você realmente não se importa se sua verificação de saúde atingir seu aplicativo Rails (o que você provavelmente deveria ...), então você pode apontá-la em um arquivo estático, como /robots.txt e usar HTTP / 80 em vez de HTTPS / 443. O Nginx servirá o arquivo estático sem envolver o Rails.
Não que eu realmente recomende isso a longo prazo, mas se você estiver com dificuldades para obter algo através do seu ELB, isso ajudará a solucionar problemas.