16

During CentOS 7 system boot nginx start fails with the following error:

2014/08/04 17:27:34 [emerg] 790#0: bind() to a.b.c.d:443 failed (99: Cannot assign requested address)

I suspect this is happening due to the network interfaces not being up yet before attempting to bind to that IP address for serving a vhost over SSL.

My guess is I need to specify the network.service as a requirement for the nginx.service, but I can't find the network service in /etc/systemd/ at all.

How can I configure the service order or dependencies in systemd?

  • 1
    Aren't you looking more for service dependencies than order? – a CVn Aug 4 '14 at 15:48
  • Good point! Updated. – vincent.io Aug 4 '14 at 15:49
  • 1
    This may help: serverfault.com/questions/482730/… – Belmin Fernandez Aug 4 '14 at 16:02
  • Thanks, that solves it! Mind to put it in an answer so I can close it? :) – vincent.io Aug 4 '14 at 16:05
  • Deleted my answer. Source of that answer posted (Mr. Hampton). Should mark his as the correct answer. – Belmin Fernandez Aug 4 '14 at 18:25
18

You need, at minimum, After=network.target in the [Unit] section of your unit file, to ensure that the network is up before starting nginx. I have no idea why your unit file doesn't have it.

Here is a complete example from my handy Fedora system, as shipped by Fedora:

[Unit]
Description=The nginx HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
  • Thanks, great answer! I installed nginx from the remi repository (third-party), which might explain why "After" is missing in the unit file. – vincent.io Aug 5 '14 at 8:36
  • 1
    Interesting. I would drop him a note and let him know about the problem. His packages are usually very high quality and I'm not sure how he missed that. – Michael Hampton Aug 5 '14 at 12:47
  • Great suggestion, done. – vincent.io Aug 6 '14 at 18:44
5

From the error log, it looks like your nginx config. file has a listen directive with an explicit ip address:

listen a.b.c.d:443

This means that nginx won't start unless your network interface is up and the IP a.b.c.d has been assigned to the interface.

You have two options:

  • change the listen directive to: listen 443; (bind to all ip addresses)
  • make nginx depend on network-online.target

As described in http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ the network.target only indicates that the network management stack is up [...] Whether any network interfaces are already configured when it is reached is undefined.

If you want to make sure that the IP address is already assigned and the interface is up, you need to add the network-online.target to your nginx's systemd unit file.

Your /etc/systemd/system/multi-user.target.wants/nginx.service file should have network-online.target in the After= and Requires= lines.

[Unit]
Description=The nginx HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target network-online.target
Requires=network-online.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
  • 1
    +1 for mentioning network-online.target - in case somebody is also wondering: yes, both Requires= and After= are necessary because Requires= (arguably surprisingly) doesn't imply an ordering between the required unit and the requiring one. – maxschlepzig Aug 5 '16 at 7:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.