Nginx keeps throwing nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Solution 1
What is your nginx.conf
look like? I assume you have not changed the config, maybe just added the gzip and a new include folder to have separate location for the websites. For each of your doman / sub-domain have a separate config file. Like:
example.com
&www.example.com
api.example.com
blog.example.com
This is because I assume these are separate websites under the same domain. If they are on the same website and they are just a so-called sub-page, then you would be better at creating just sub-pages with the location options.
To re-organise your nginx
config I would create a com.example.conf
file with 3 separate server sections. First is to redirect the non-www users to the www website:
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;
}
The third section would contain the main site:
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;
}
}
(I have to say, your fastcgi part in your index.php location looks weird to me, but I'll leave that to you)
Then create separate config files as com.example.api.conf
and com.example.blog.conf
. Add the first two sections from the previous config similarly as before, then you can just add yourself each sub-domain a different config for the locations.
For example I have this for my laravel websites:
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;
}
Hope this helps you, if not, comment your questions.
Solution 2
To fix the bind() to 0.0.0.0:80 or 443 failed (98: Address already in use)
Run following commands:
sudo pkill -f nginx & wait $!
sudo systemctl start nginx
Related videos on Youtube
xarlymg89
Entrepreneur since born. Geek. Traveler. At the moment I'm working on a Hiking app: www.walkaholic.me to ease the planning of adventures in the nature.
Updated on September 18, 2022Comments
-
xarlymg89 almost 2 years
I have been checking plenty of websites, and many questions/answer here in ServerFault about this issue. However, I don't seem to be getting into the root of the configuration error.
I have 4 domains in my nginx server:
example.com
www.example.com
api.example.com
blog.example.com
They are all up and running, both in ports 80 and 443. This is the template
nginx.conf
I used for all of them, changing only theserver_name
,root
,error_log
andaccess_log
directives. There are some other changes, but in principle shouldn't affect. Like differentfastcgi_param
.This is the template for
example.com
andwww.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 }
And this is the exact error I get when I restart the server:
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'.
When I try to renew the certificates using
sudo certbot renew --dry-run
I obtain a similar error, although not exactly the same one.If I kill the nginx threads, then I'm able to restart the server. But the next time I try to restart it, it throws the same error. And the worst thing is that I cannot manage to renew my SSL certificates (although that could be due to a different reason and I wouldn't like to put in here, since this could be the reason).
EDIT
I have set up a local machine using Vagrant with the exact same configuration, except that I commented the SSL certificates data. I can restart the server without issues. So perhaps it does have something to do with Certbot/SSL configuration.
To help with the debugging of this issue, here is the output of
netstat -tulpn
(only nginx is using ports 80 and 443, which is the expected output as I understand):/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
-
xarlymg89 over 6 yearsThanks for answering @Bert, I really appreciated. I have just posted what seemed to be the solution. My nginx.conf looks as what you just described. There is the gzip improvement, and the include of sites_enabled/* so I can load the subdomains config files. About the server sections, what's really the benefit of having them that way? I don't expect the nginx.conf to change that much.
-
xarlymg89 over 6 yearsAnd by the way, yes, each subdomain (except the www/non-www, which are the same) are different websites, with even different programming languages behind.
-
Bert over 6 yearsNormally IPv6 is not used by NginX, unless you have it enabled. Or at least I haven't seen any sign of proof that my websites are served on IPv6 addresses as well. I'm glad you have solved it, but think about removing the if from the nginx config. nginx.com/resources/wiki/start/topics/depth/ifisevil/#examples
-
Bert over 6 yearsThe main thing you benefit is a more smooth nginx work (less workload is required / config / page) and better visibility if a 3rd person watches your config. Also use a separate config for the main site because nginx.conf is supposed to be used by everything. If anything happens and you have to add a new subdomain, this nginx config will be used. So make it as plain as you can.
-
xarlymg89 over 6 yearsI should have explained myself really badly both in the question and in my previous comment. I am using different conf files for each subdomain. Except www.mydomain.me and mydomain.me, which I don't think I should split them. About the the clarity, it definitely adds more clarity. Have just changed it right now :)
-
xarlymg89 over 6 yearsI had again the error while restarting, and after I applied the split of the server sections, it was finally gone. Now I can restart as many times as I want. So I'll give you the bounty for the help in both, suggesting the split of server sections (to get the ifs removed) and the time spent. By the way, the 3rd server section, isn't it supposed to have only server_name www.mydomain.me; instead of server_name mydomain.me www.mydomain.me; ? It threw this warning nginx[2131]: nginx: [warn] conflicting server name "mydomain.me" on 0.0.0.0:80, ignored
-
Bert over 6 yearsWell, yes. Assuming you want only HTTPS on only www.mydomain.me, you'll need 1 server block for 80: mydomain.me and www.mydomain.me, another server block for 443 and mydomain.me, (these needs to be redirected with 301) and a third server block for 443 and www.mydomain.me.
-
xarlymg89 over 6 yearsSmooth, clear and fully working. Thanks again! As soon as the time for giving the bounty is passed, I'll give it to you. Thank you for taking the time and effort @Bert