1

I'm running my Discord Music Bot on a VPS, and to start the bot as the VPS does, I have a service called "bot.service" (located in /etc/systemd/system), which have the following:

[Unit]
Description=blah blah

[Service]
ExecStart=/usr/bin/java /usr/java/Lavalink.jar #THIS SHOULD START FIRST
ExecStart=/usr/bin/python3 /home/launcher.py #THEN THIS
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

But it doesn't work, the bot does not start as the VPS does. And yes, I've run this two commands:

sudo systemctl daemon-reload
sudo systemctl enable bot.service

If someone knows what it's happening, I'd really appreciate any kind of help.

Regards.

2
  • Does journalctl show any useful information? (journalctl -u bot.service to filter its output). What does systemctl status bot.service say? Commented Jun 15, 2021 at 6:22
  • I suspect both will be started simultaneously. There is nothing in man systemd.service or man systemd.exec to suggest that it will wait for one to exit before the other starts or it will wait for one to be in some steady internal state before starting the other. If launcher.py depends on Lavalink.jar, then it might be a better idea to split them into seperate services with an After= and perhaps Requires= relationship. If Lavalink.jar implements watchdog, then this gets easy. Otherwise, you might want an ExecStartPre=sleep ... for the launcher.py service. Commented Jun 15, 2021 at 6:26

2 Answers 2

1

I suspect both ExecStart= commands will be started simultaneously. There is nothing in man systemd.service or man systemd.exec to suggest that it will wait for one to exit before the other starts or it will wait for one to be in some steady internal state before starting the other.

In fact, man systemd.service explicitly says this about ExecStartPre= and ExecStartPost=:

Syntax is the same as for ExecStart=, except that multiple command lines are allowed and the commands are executed one after the other.

ExecStart= does say multiple commands are allowed with Type=oneshot but does not say that one will be executed after the other.

If you want Lavalink.jar to exit before starting launcher.service the answer is simple: Use ExecStartPre= instead of ExecStart= for Lavalink.jar.

Otherwise, if launcher.py depends on Lavalink.jar and they are long-running services, then it might be a better idea to split them into seperate services like so:

# lavalink.service
[Service]
ExecStart=/usr/bin/java -jar /usr/java/Lavalink.jar
# launcher.service
[Unit]
After=lavalink.service
Requires=lavalink.service

[Service]
ExecStartPre=/bin/sleep 10
ExecStart=/usr/bin/python3 /home/launcher.py

[Install]
WantedBy=multi-user.target

I don't normally like sleep because on a slow-day, your second service might start too early, and on a fast-day, your second service isn't starting as soon as possible.

A better solution would be if Lavalink.jar implemented the watchdog. Then you could use Type=watchdog in lavalink.service. That would cause launcher.service to start only after the watchdog starts receiving a heartbaeat from lavalink.service. This would be a nice replacement for ExecStartPre=/bin/sleep.

2
  • Hello! Thanks for the response. "launcher.py" does not require the lavalink virtual server, but the bot itself does. That's why the Java server (Lavalink.jar) needs to start before the actual bot. Commented Jun 15, 2021 at 16:28
  • Great. That's even easier. The 2-service technique still works, but you don't need any of those Requires=, After= or ExecStartPre= lines. But you will want the [Install] section for both services. Commented Jun 15, 2021 at 16:32
0

I don't know why python script does not start but you have to use the command: /usr/bin/java -jar path/to/jar/file to execute the .jar files.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.