Nginx continua lançando nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Endereço já em uso)

Nginx continua lançando nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Endereço já em uso)

Tenho verificado muitos sites e muitas perguntas/respostas aqui no ServerFault sobre esse problema. No entanto, não parece que estou chegando à raiz do erro de configuração.

Tenho 4 domínios em meu servidor nginx:

  • example.com
  • www.example.com
  • api.example.com
  • blog.example.com

Eles estão todos funcionando, tanto nas portas 80 quanto na 443. Este é o template que nginx.confusei para todos eles, alterando apenas as server_namediretivas root, error_loge access_log. Existem algumas outras mudanças, mas em princípio não deveriam afetar. Como diferente fastcgi_param.

Este é o modelo para example.come www.example.com:

server {
listen 80;

server_name example.com www.example.com;
root /var/www/example.com/public_html/web;

if ($http_host = example.com) {
    return 301 https://www.example.com$request_uri;
}

location / {
    # try to serve file directly, fallback to front controller
    try_files $uri /index.php$is_args$args;
}

location ~ ^/index\.php(/|$) {
    fastcgi_pass   unix:/var/run/php/php7.0-fpm.sock;

    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTPS off;
    fastcgi_param   DATABASE_NAME           some_database;
    fastcgi_param   DATABASE_USER           some_user;
    fastcgi_param   DATABASE_PASSWORD       some_pwd;
}

#return 404 for all php files as we do have a front controller
location ~ \.php$ {
    return 404;
}

error_log /var/log/nginx/www.example.com_error.log;
access_log /var/log/nginx/www.example.com_access.log;

# Redirect non-https traffic to https
if ($scheme != "https") {
    return 301 https://$host$request_uri;
} # managed by Certbot


listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

E este é exatamente o erro que recebo quando reinicio o servidor:

root@vps_server:/etc/nginx# journalctl -xe
Mar 09 09:17:16 vps_server systemd[1]: Starting A high performance web server and a reverse proxy server...
-- Subject: Unit nginx.service has begun start-up
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
-- 
-- Unit nginx.service has begun starting up.
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:16 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:17 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:18 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Mar 09 09:17:18 vps_server nginx[30764]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)
Mar 09 09:17:18 vps_server nginx[30764]: nginx: [emerg] still could not bind()
Mar 09 09:17:18 vps_server systemd[1]: nginx.service: Control process exited, code=exited status=1
Mar 09 09:17:18 vps_server systemd[1]: Failed to start A high performance web server and a reverse proxy server.
-- Subject: Unit nginx.service has failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
-- 
-- Unit nginx.service has failed.
-- 
-- The result is failed.
Mar 09 09:17:18 vps_server systemd[1]: nginx.service: Unit entered failed state.
Mar 09 09:17:18 vps_server systemd[1]: nginx.service: Failed with result 'exit-code'.

Quando tento renovar os certificados usando sudo certbot renew --dry-runobtenho um erro semelhante, embora não exatamente o mesmo.

Se eu encerrar os threads nginx, poderei reiniciar o servidor. Mas na próxima vez que tento reiniciá-lo, ocorre o mesmo erro. E o pior é que não consigo renovar os meus certificados SSL (embora isso possa ser por um motivo diferente e não gostaria de colocar aqui, pois pode ser esse o motivo).

EDITAR

Configurei uma máquina local usando Vagrant com exatamente a mesma configuração, exceto que comentei os dados dos certificados SSL. Posso reiniciar o servidor sem problemas. Então, talvez tenha algo a ver com a configuração do Certbot/SSL.

Para ajudar na depuração deste problema, aqui está a saída de netstat -tulpn(apenas o nginx está usando as portas 80 e 443, que é a saída esperada pelo que entendi):

/var/log/nginx# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      16700/mysqld        
tcp        0      0 0.0.0.0:5355            0.0.0.0:*               LISTEN      1578/systemd-resolv 
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      30608/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1675/sshd           
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      10001/master        
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      30608/nginx: master 
tcp6       0      0 :::5355                 :::*                    LISTEN      1578/systemd-resolv 
tcp6       0      0 :::22                   :::*                    LISTEN      1675/sshd           
tcp6       0      0 :::25                   :::*                    LISTEN      10001/master        
udp        0      0 127.0.0.53:53           0.0.0.0:*                           1578/systemd-resolv 
udp        0      0 0.0.0.0:68              0.0.0.0:*                           1343/dhclient       
udp        0      0 0.0.0.0:5355            0.0.0.0:*                           1578/systemd-resolv 
udp6       0      0 :::5355                 :::*                                1578/systemd-resolv

Responder1

Como é a sua nginx.confaparência? Presumo que você não tenha alterado a configuração, talvez apenas tenha adicionado o gzip e uma nova pasta de inclusão para ter um local separado para os sites. Para cada um dos seus domínios/subdomínios, tenha um arquivo de configuração separado. Como:

  • example.com&www.example.com
  • api.example.com
  • blog.example.com

Isso ocorre porque presumo que sejam sites separados no mesmo domínio. Se eles estiverem no mesmo site e forem apenas uma chamada subpágina, seria melhor criar apenas subpáginas com as opções de localização.

Para reorganizar sua nginxconfiguração, eu criaria um com.example.confarquivo com 3 seções de servidor separadas. A primeira é redirecionar os usuários não www para o site www:

server {
    listen       80;
    server_name  example.com;
    return       301 https://www.example.com$request_uri;
}

server {
    listen       443 ssl;
    server_name  example.com;
    return       301 https://www.example.com$request_uri;
}

A terceira seção conteria o site principal:

server {
    listen 443 ssl;

    server_name example.com www.example.com;

    root /var/www/example.com/public_html/web;

    index    index.php;

    error_log /var/log/nginx/www.example.com_error.log;
    access_log /var/log/nginx/www.example.com_access.log;

    location / {
        # try to serve file directly, fallback to front controller
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass   unix:/var/run/php/php7.0-fpm.sock;

        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
        fastcgi_param   DATABASE_NAME           some;
        fastcgi_param   DATABASE_USER           some_user;
        fastcgi_param   DATABASE_PASSWORD       some_pwd;
    }

    location ~ \.php$ {
        return 404;
    }
}

(Devo dizer que sua parte fastcgi em sua localização index.php parece estranha para mim, mas deixarei isso para você)

Em seguida, crie arquivos de configuração separados como com.example.api.confe com.example.blog.conf. Adicione as duas primeiras seções da configuração anterior da mesma forma que antes, então você pode simplesmente adicionar a cada subdomínio uma configuração diferente para os locais.

Por exemplo, eu tenho isso para meus sites laravel:

rewrite ^/index\.php?(.*)$ /$1 permanent;

location / {
        try_files $uri @rewrite;
}

location        @rewrite {
        rewrite ^(.*)$ /index.php/$1 last;
}
location ~ ^/index.php(/|$) {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS on;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_read_timeout 299;
}

Espero que isso ajude você, se não, comente suas dúvidas.

Responder2

Falha ao corrigir bind() para 0.0.0.0:80 ou 443 (98: Endereço já em uso)

Execute os seguintes comandos:

sudo pkill -f nginx & wait $!

sudo systemctl start nginx

Responder3

Finalmente resolvi o problema. Parecia que o IPV6 estava habilitado no servidor e exigia que a configuração do nginx fosse um pouco diferente.

Em vez de usar isso:

listen 80;
listen 443 ssl;

Eu tive que usar o seguinte:

listen [::]:80;
listen [::]:443 ssl;

Neste site obtive uma explicação mais precisa e detalhada:https://chrisjean.com/fix-nginx-emerg-bind-to-80-failed-98-address-already-in-use/

O curioso é que meu erro foi:

nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)

em vez do descrito (no URL que forneci):

nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)

No entanto, isso resolveu o problema e consegui reiniciar o servidor nginx sem problemas.

O servidor vagrant que eu configurei não tinha IPV6 habilitado, então isso pode ter algo a ver com o fato de ele não se comportar da mesma maneira.

informação relacionada