12

I created systemd unit for x0vncserver like this

[Unit]
Description=Remote desktop service (VNC)
After=graphical.target


[Service]
Type=forking
User=user
ExecStart=/usr/bin/sh -c '/usr/bin/x0vncserver -display :0 -rfbport 5900 -passwordfile /home/user/.vnc/passwd &'

[Install]
WantedBy=multi-user.target

and enabled it to run but it fails. Then I realized as I am trying to load the original desktop using x0vncserver, I can only do that after loading the desktop itself completely. So I have to set the system unit to run after loading the desktop but how? Or any timed way to set it up? Though it may be possible by using desktop session tools but any systemd way solution?

and my default.target is

# systemctl get-default       
graphical.target
3

4 Answers 4

11

After looking at the lack of answers that do not include some sort of additional workaround, I came up with this solution myself. The solution was in the unit file after all, I checked out the systemd.unit man file under "After=", which requires a certain target/service to be running before starting the current unit, the "Requires=" alone will start up the service along with its dependency simultaneously. Here is a quote from that manual:

If a unit foo.service requires a unit bar.service as configured with Requires= and no ordering is configured with After= or Before=, then both units will be started simultaneously and without any delay between them if foo.service is activated.

So if the x server and the x0vncserver start up at the same time, the x0vncserver will fail due to not being able to connect up to an initialized x server. I needed to specifically add my DM to the "Requires=" and "After=" to get this to work. Now that this is done, it works every time without any additional magic. You will need to replace the "nodm.service" entries with the specific display manager that you are using. The "Restart" lines are there just in case I decide to restart my session by logging out, which will terminate the X server and then restart it immediately (since I am using nodm). I don't know for sure, but I would think this would also apply when using a standard DM as the x server would be running for login, and then be terminated with the new user x session replacing it after successful login. The only side effects of this are the VNC session being disconnected and needing to be restarted, but I don't think there is any solution to that specific issue without further magic.

Here is my [email protected] file:

[Unit]
Description=Remote desktop service (VNC)
After=syslog.target network.target multi-user.target nodm.service
Requires=nodm.service

[Service]
Type=simple
ExecStart=/usr/bin/x0vncserver -display %i -rfbport 5900 -securitytypes none
Restart=always
RestartSec=3


[Install]
WantedBy=multi-user.target

As an additional note, I would suggest modifying the "-securitytypes" directive to something more secure, as I am just using this in a local network in which I am the only user and am not concerned with any security issues.

1
  • Does this really work? What if the DM depends on multi-user -- as it usually does, I think -- isn't there a cycle then?
    – q.undertow
    14 hours ago
9

The first suggestion didn't work for me. So I tried a workaround instead. I set my x0vncserver systemd unit as follows

[Unit]
Description=Remote desktop service (VNC)
After=multi-user.target

[Service]
Type=forking
User=user
ExecStart=/bin/sh -c '/usr/bin/x0vncserver -display :0 -rfbport 5900 -passwordfile /home/user/.vnc/passwd &'

[Install]
WantedBy=default.target

And then as the above service fails because it tries to load before the desktop:0 loads, I set a systemd timer unit as x0vncserver.timer to run the x0vncserver.service unit after a defined time considering the desktop loading time for my machine (with poor old config) like below

[Unit]
Description=x0vncserver timer

[Timer]
# Time to wait after booting before it run for first time
OnBootSec=2m
Unit=x0vncserver.service

[Install]
WantedBy=default.target

And then I activated the timer unit by systemctl enable x0vncserver.timer and rebooted. This time it worked as my goal was to start the server without my manual intervention :).

1
  • 1
    Indeed this approach works for Ubuntu Server 18.0.4. I had trouble bringing up USB Ethernet adapter during boot and configuring it in custom script, this what saved a day.
    – Croll
    Mar 21, 2019 at 10:06
2

This is already answered in Setting DISPLAY in systemd service file.

If that doesn't work, I recommend using the "autostart" feature offered by most every Desktop. Using systemd would be preferred though, since systemd would restart your app if it fails, and the autostart feature will not.

2

You can use

Requires=xdg-desktop-autostart.target

This will happen after graphical.target

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .