Este é um guia passo a passo de como configurar o Nginx no Ubuntu Server para executar uma única ou múltiplas ASP.NET Core APIs em um domínio (sem subdomínio).
Esse post é bem extenso então vamos dividí-lo em etapas para alcançar isso:
Primeiro precisamos do Nginx instalado no servidor. Nós podemos usar o apt-get
para instalar.
sudo apt-get install nginx
Depois da instalação o servidor já deve está executando. Para checar o status do Nginx execute o seguinte comando:
sudo systemctl status nginx
Após instalar o Nginx pode ser preciso abrir as portas HTTP e HTTPS no firewall. Se você está usando o Amazon EC2 (assim como eu) apenas use o console da AWS (AWS Management Console) para fazer isso e você estará pronto para ir para o próximo tópico.
Vamos listar as configurações de aplicação que o ufw
conhece:
sudo ufw app list
Existem três perfis disponíveis para o Nginx abrir as portas 80 (HTTP) e 443 (HTTPS):
Vamos executar o seguinte comando para habilitar o perfil Nginx Full.
sudo ufw allow 'Nginx Full'
Agora vamos executar o seguinte comando para verificar a alteração:
sudo ufw status
A configuração a seguir é a que eu estou usando e deve ser o suficiente para iniciar. Caso você esteja interessado no detalhes, a documentação do Nginx é um bom lugar para referência e também devdocs.io/nginx.
Crie o arquivo de configuração /etc/nginx/proxy.conf
com o conteúdo:
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
large_client_header_buffers 4 16k;
Modifique o arquivo /etc/nginx/nginx.conf
e substitua com o seguinte conteúdo:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.config;
events {
worker_connections 1024;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
keepalive_timeout 30;
server_tokens off;
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.config;
include /etc/nginx/sites-enabled/*;
include /etc/nginx/proxy.config;
default_type application/octet-stream;
log_format custom '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_x_forwarded_for" $request_id ';
access_log /var/log/nginx/access.log custom;
error_log /var/log/nginx/error.log;
}
Edite o server block padrão para tratar server_name
desconhecido retornando o status code 444 (conexão fechada sem resposta — connection closed without response). Modifique o server block padrão do Nginx /etc/nginx/sites-available/default
e substitua com o seguinte conteúdo:
server {
listen 80 default_server;
listen [::]:80 default_server;
return 444;
}
Teste a configuração do Nginx para verificar se a sintaxe está correta:
sudo nginx -t
Se não houver erros, reinicie o Nginx.
sudo systemctl restart nginx
Primeiro vamos criar uma pasta para o domínio (ex.: example.com) dentro do diretório /var/www
usando a flag -p
para criar os diretórios pais se necessário:
sudo mkdir -p /var/www/example.com
Em seguida, para evitar qualquer problema de permissão, torne o usuário do Nginx www-data
proprietário do diretório que acabamos de criar:
sudo chown -R www-data: /var/www/example.com
Permita o proprietário e grupos para escrever no diretório:
sudo chmod -R 775 /var/www/example.com
Adicione outro usuário para o grupo www-data
caso precise (o usuário ubuntu da Amazon EC2, por exemplo):
sudo usermod -a -G www-data ubuntu
Agora vamos criar o server block (um arquivo de configuração) /etc/nginx/sites-available/example.com
com o seguinte conteúdo:
server {
listen 80;
listen [::]:80;
server_name example.com *.example.com;
location / {
return 200 "OK";
}
}
Para habilitar o novo server block é necessário criar um link simbólico partindo do arquivo no diretório sites-available
para o diretório sites-enabled
, o qual é lido pelo Nginx quando é iniciado:
sudo ln -sfn /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Então teste a sintaxe da configuração e reinicie o Nginx:
sudo nginx -t
sudo systemctl restart nginx
Agora você deve obter o texto "OK" quando acessar http://example.com no seu navegador.
Basicamente nós precisamos configurar a ASP.NET Core API como um serviço e configurar o Nginx como um proxy reverso. A documentação da Microsoft me ajudou muito.
Durante esse processo os seguintes arquivos serão criados ou editados:
/etc/systemd/system/my-example-api.service:
Arquivo de configuração do serviço para a ASP.NET Core API./etc/nginx/proxy.conf:
Arquivo de configuração do proxy./etc/nginx/nginx.conf:
Arquivo de configuração do Nginx./etc/nginx/sites-available/default:
Server block padrão./etc/nginx/sites-available/example.com:
Server block do domínio.Nginx não é configurado para gerenciar processos do Kestrel. Por isso, vamos utilizar o systemd
para criar um arquivo de configuração do serviço para comandar (iniciar, parar, reiniciar) e monitorar a API.
Crie um arquivo de configuraração para o serviço:
sudo vim /etc/systemd/system/my-example-api.service
A seguir está um exemplo de arquivo de configuração do serviço para My Example API (se necessário, altere para atender o seu caso de uso):
[Unit]
Description=My Example API
[Service]
WorkingDirectory=/var/www/example-api/current
ExecStart=/usr/bin/dotnet /var/www/example-api/current/ExampleAPI.dll
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=my-example-api
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=ASPNETCORE_URLS=http://localhost:5000
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
EnvironmentFile=/path/to/file.conf
[Install]
WantedBy=multi-user.target
Inicie o serviço e verifique que está executando.
sudo systemctl start my-example-api.service
sudo systemctl status my-example-api.service
Uma vez que a API que está sendo executada no Kestrel é gerenciada pelo systemd
, todos os eventos e processos são logados para o journal (um componente do systemd
). Para visualizar os registros do serviço do API my-example-api.service
, use o seguinte comando:
sudo journalctl -fu my-example-api.service
Para filtrar por período e reduzir o número de registros retornados:
sudo journalctl -fu my-example-api.service --since "2019-01-01" --until "2019-01-20 06:00"
É necessário configurar o Nginx como um proxy reverso para encaminhar requisições feitas de http://example.com para a ASP.NET Core API executandp no Kestrel em http://localhost:5000. Modifique o server block /etc/nginx/sites-available/example.com
e substitua o conteúdo com o seguinte:
server {
listen 80;
listen [::]:80;
server_name example.com *.example.com;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
}
Então teste a sintaxe da configuração e reinicie o Nginx:
sudo nginx -t
sudo systemctl restart nginx
A API estará disponível em http://example.com.
Nós iremos configurar o Nginx como um proxy reverso para encaminhar as requisições de várias ASP.NET Core APIs usando a diretiva rewrite
. Modifique /etc/nginx/sites-available/example.com
e substitua o conteúdo com o seguinte:
server {
listen 80;
listen [::]:80;
server_name example.com *.example.com;
location /myapi1 {
rewrite /myapi1/?(.*) /$1 break;
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
location /myapi2 {
rewrite /myapi2/?(.*) /$1 break;
proxy_pass http://localhost:5010;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
}
Você precisará ter um arquivo de configuração para cada API para executar ambas as APIs como um serviço. Apenas repita o passo já descrito neste post prestando atenção nos caminhos e na porta usada.
Então teste a sintaxe da configuração e reinicie o Nginx:
sudo nginx -t
sudo systemctl restart nginx
Agora ambas as APIs myapi1
e myapi2
estarão disponíveis no mesmo servidor em http://example.com/myapi1 e http://example.com/myapi2 respectivamente.