Deploy de funcionalidades e o NGINX


Leia em 2 minutos

Eu sempre gostei de NGINX e não poderia usar outra coisa em meus servidores que não fosse ele. Antes de fazer o deploy de funcionalidades em alguns projetos, eu uso o módulo geo para dar acesso ao meu endereço de IP, enquanto todas as outras pessoas recebem a página de manutenção com o status HTTP 503.

Neste artigo, nós iremos começar de uma configuração bastante simples:

http {
  include       /usr/local/etc/nginx/mime.types;
  default_type  application/octet-stream;

  server {
    listen 2345;
    server_name localhost;
    root /var/www/codeplane/current/public;
  }
}

Primeiro, você precisa usar o módulo geo para definir uma variável para o seu endereço IP. Dentro do bloco http, defina a variável $developer_ip.

http {
  include       /usr/local/etc/nginx/mime.types;
  default_type  application/octet-stream;

  geo $developer_ip {
    default no;
    127.0.0.1 yes;
    189.73.181.124 yes;
  }

  server {
    listen 2345;
    server_name localhost;
    root /var/www/codeplane/current/public;
  }
}

Aqui estamos definindo a variável $developer_ip para yes toda vez que o IP for um dos especificados naquele bloco; você deve adicionar todos os IPs que devem ser liberados ali. Note que você pode usar qualquer nome de variável.

Agora você precisa atualizar a configuração do seu site. No bloco server, definina uma variável chamada $maintenance com o valor off. Sempre que você mudar esta variável para on, nós iremos retornar o status 503 para todas as requisições.

http {
  include       /usr/local/etc/nginx/mime.types;
  default_type  application/octet-stream;

  geo $developer_ip {
    default no;
    127.0.0.1 yes;
    189.73.181.124 yes;
  }

  server {
    listen 2345;
    server_name localhost;
    root /var/www/codeplane/current/public;

    set $maintenance off;

    location / {
      if ($maintenance = on) {
        return 503;
      }
    }
  }
}

Nós precisamos garantir que os arquivos estáticos não são afetados por esta regra. Isso pode ser feito com um novo bloco dentro de location.

http {
  include       /usr/local/etc/nginx/mime.types;
  default_type  application/octet-stream;

  geo $developer_ip {
    default no;
    127.0.0.1 yes;
    189.73.181.124 yes;
  }

  server {
    listen 2345;
    server_name localhost;
    root /var/www/codeplane/current/public;

    set $maintenance off;

    location / {
      if ($request_uri ~* "\.(html?|ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$") {
        set $maintenance off;
        break;
      }

      if ($maintenance = on) {
        return 503;
      }
    }

    error_page 503  /503.html;
      location = /503.html {
      root   /var/www/codeplane/current/public;
    }
  }
}

Esta regra irá garantir que requisições como image.png ou style.css?123456789 (URLs geradas pelo Rails mais antigo) não são bloqueadas.

Finalmente, nós devemos identificar as requisições realizadas pelos IPs definidos no grupo de geo-localização.

http {
  include       /usr/local/etc/nginx/mime.types;
  default_type  application/octet-stream;

  geo $developer_ip {
    default no;
    127.0.0.1 yes;
    189.73.181.124 yes;
  }

  server {
    listen 2345;
    server_name localhost;
    root /var/www/codeplane/current/public;

    set $maintenance off;

    location / {
      if ($request_uri ~* "\.(html?|ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$") {
        set $maintenance off;
        break;
      }

      if ($developer_ip = yes) {
        set $maintenance off;
      }

      if ($maintenance = on) {
        return 503;
      }
    }
  }
}

Para ativar a página de manutenção, você pode definir a variável $maintenance para on antes de fazer um deploy. Embora você possa detectar a presença de arquivos (algo como maintenance.html, por exemplo), eu prefiro fazer isso manualmente, já que nem todo deploy precisa entrar em modo de manutenção.

Para recarregar as configurações do NGINX, envie um sinal HUP.

$ ps aux | grep nginx
www-data   37217   0:00.00 nginx: worker process
www-data   37216   0:00.01 nginx: master process nginx

$ kill -HUP 37216

Todos as requisições irão receber a página padrão definida pelo NGINX. Se você quiser servir um arquivo específico, pode adicionar mais uma configuração para isso.

http {
  include       /usr/local/etc/nginx/mime.types;
  default_type  application/octet-stream;

  geo $developer_ip {
    default no;
    127.0.0.1 yes;
    189.73.181.124 yes;
  }

  server {
    listen 2345;
    server_name localhost;
    root /var/www/codeplane/current/public;

    set $maintenance off;

    location / {
      if ($request_uri ~* "\.(html?|svg|ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$") {
        set $maintenance off;
        break;
      }

      if ($developer_ip = yes) {
        set $maintenance off;
      }

      if ($maintenance = on) {
        return 503;
      }
    }

    error_page 503  /503.html;
      location = /503.html {
      root   /var/www/codeplane/current/public;
    }
  }
}

Pronto! Certifique-se que o arquivo 503.html existe dentro do seu diretório $rails_root/public.