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 the server_name
, root
, error_log
and access_log
directives. There are some other changes, but in principle shouldn't affect. Like different fastcgi_param
.
This is the template for example.com
and 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
}
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
Best Answer
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 acom.example.conf
file with 3 separate server sections. First is to redirect the non-www users to the www website:The third section would contain the main site:
(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
andcom.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:
Hope this helps you, if not, comment your questions.