How to set systemd service dependencies?

53,413

Solution 1

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

Solution 2

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
Share:
53,413

Related videos on Youtube

vincent.io
Author by

vincent.io

I'm an Entrepreneur and Product Designer, combining my backgrounds in design, business and software development to build products that deliver great experiences. I'm cofounder and CEO at Content Optimization service ContentKing. Apart from ContentKing I am the chairman of C-Squared, a non-profit organization based in Brno, Czech Republic that connects companies to local tech communities. From time to time I dabble in code and build robots. The first robot I ever built committed suicide by taking the stairs. I fixed that bug in the second revision, but it didn’t do much more than avoiding stairs. Originally from The Netherlands, I'm currently living in Brno, Czech Republic. In my spare time I love running, reading and hiking. On top of that I have a passion for aviation, and hope to fly my own HondaJet one day.

Updated on September 18, 2022

Comments

  • vincent.io
    vincent.io over 1 year

    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?

    • user
      user almost 10 years
      Aren't you looking more for service dependencies than order?
    • vincent.io
      vincent.io almost 10 years
      Good point! Updated.
    • NukaRakuForgotEmail
      NukaRakuForgotEmail almost 10 years
    • NukaRakuForgotEmail
      NukaRakuForgotEmail almost 10 years
      Deleted my answer. Source of that answer posted (Mr. Hampton). Should mark his as the correct answer.
  • vincent.io
    vincent.io almost 10 years
    Thanks, great answer! I installed nginx from the remi repository (third-party), which might explain why "After" is missing in the unit file.
  • Michael Hampton
    Michael Hampton almost 10 years
    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.
  • vincent.io
    vincent.io almost 10 years
    Great suggestion, done.
  • maxschlepzig
    maxschlepzig almost 8 years
    +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.