Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 93 additions & 69 deletions docs/guides/quick-answers/linux/start-service-at-boot/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description: The systemd daemon allows you to control Linux system services. Thi
authors: ["Linode"]
contributors: ["Linode"]
published: 2018-05-01
modified: 2025-03-27
keywords: ["systemd","service","enable service","Linux system service"]
license: '[CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0)'
external_resources:
Expand All @@ -25,118 +26,141 @@ It is simple to create a custom systemd service that will run any script or proc

1. Create a script or executable that the service will manage. This guide uses a simple Bash script as an example:

{{< file "test_service.sh" bash >}}
DATE=`date '+%Y-%m-%d %H:%M:%S'`
echo "Example service started at ${DATE}" | systemd-cat -p info
```file {title="test_service.sh" lang="bash"}
DATE=`date '+%Y-%m-%d %H:%M:%S'`
echo "Example service started at ${DATE}" | systemd-cat -p info

while :
do
echo "Looping...";
sleep 30;
done
{{< /file >}}
while :
do
echo "Looping...";
sleep 30;
done
```

This script will log the time at which it is initialized, then loop infinitely to keep the service running.

2. Copy the script to `/usr/bin` and make it executable:

sudo cp test_service.sh /usr/bin/test_service.sh
sudo chmod +x /usr/bin/test_service.sh
```command
sudo cp test_service.sh /usr/bin/test_service.sh
sudo chmod +x /usr/bin/test_service.sh
```

3. Create a **Unit file** to define a systemd service:
3. Create a **Unit file** to define a systemd service in your application, where `/opt/myapp/` is the path to your application directory.

{{< file "/lib/systemd/system/myservice.service" conf >}}
[Unit]
Description=Example systemd service.
```file {title="/opt/myapp/myservice.service"}
[Unit]
Description=Example systemd service.

[Service]
Type=simple
ExecStart=/bin/bash /usr/bin/test_service.sh
[Service]
Type=simple
ExecStart=/bin/bash /usr/bin/test_service.sh

[Install]
WantedBy=multi-user.target
{{< /file >}}
[Install]
WantedBy=multi-user.target
```

This defines a simple service. The critical part is the `ExecStart` directive, which specifies the command that will be run to start the service.
* This defines a simple service that runs `/usr/bin/test_service.sh` through Bash.
* The `ExecStart` directive specifies the command to run.
* The `[Install]` section allows the service to be enabled at boot.

4. Copy the unit file to `/etc/systemd/system` and give it permissions:
4. Link the unit file from your application directory. This approach can streamline deployments by keeping the service definition with your codebase:

sudo cp myservice.service /etc/systemd/system/myservice.service
sudo chmod 644 /etc/systemd/system/myservice.service
```command
sudo systemctl enable /opt/myapp/myservice.service
```

If the `[Install]` section is present, this creates the necessary symlinks in `/etc/systemd/system/`.

Alternatively, copy the unit file to `/etc/systemd/system/`, and adjust the permissions:

```command
sudo cp myservice.service /etc/systemd/system/myservice.service
sudo chmod 644 /etc/systemd/system/myservice.service
```

For more information about the unit file and its available configuration options, see the [systemd documentation](https://www.freedesktop.org/wiki/Software/systemd/).

## Start and Enable the Service

1. Once you have a unit file, you are ready to test the service:

sudo systemctl start myservice

```command
sudo systemctl start myservice
```

2. Check the status of the service:

sudo systemctl status myservice
```command
sudo systemctl status myservice
```

If the service is running correctly, the output should resemble the following:

{{< output >}}
● myservice.service - Example systemd service.
Loaded: loaded (/lib/systemd/system/myservice.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2018-05-01 18:17:14 UTC; 4s ago
Main PID: 16266 (bash)
Tasks: 2
Memory: 748.0K
CPU: 4ms
CGroup: /system.slice/myservice.service
├─16266 /bin/bash /usr/bin/test_service.sh
└─16270 sleep 30

May 01 18:17:14 localhost systemd[1]: Started Example systemd service..
May 01 18:17:14 localhost cat[16269]: Example service started at 2018-05-01 18:17:14
May 01 18:17:14 localhost bash[16266]: Looping...
{{< /output >}}
```output
● myservice.service - Example systemd service.
Loaded: loaded (/lib/systemd/system/myservice.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2018-05-01 18:17:14 UTC; 4s ago
Main PID: 16266 (bash)
Tasks: 2
Memory: 748.0K
CPU: 4ms
CGroup: /system.slice/myservice.service
├─16266 /bin/bash /usr/bin/test_service.sh
└─16270 sleep 30

May 01 18:17:14 localhost systemd[1]: Started Example systemd service..
May 01 18:17:14 localhost cat[16269]: Example service started at 2018-05-01 18:17:14
May 01 18:17:14 localhost bash[16266]: Looping...
```

3. The service can be stopped or restarted using standard systemd commands:

sudo systemctl stop myservice
sudo systemctl restart myservice
```command
sudo systemctl stop myservice
sudo systemctl restart myservice
```

4. Finally, use the `enable` command to ensure that the service starts whenever the system boots:

sudo systemctl enable myservice
```command
sudo systemctl enable myservice
```

{{< output >}}
Created symlink from /etc/systemd/system/multi-user.target.wants/myservice.service to /lib/systemd/system/myservice.service.
{{< /output >}}
```output
Created symlink from /etc/systemd/system/multi-user.target.wants/myservice.service to /lib/systemd/system/myservice.service.
```

5. Reboot your Linode from the Linode Manager and check the status of the service:

sudo systemctl status myservice
```command
sudo systemctl status myservice
```

You should see that the service logged its start time immediately after booting:

{{< output >}}
● myservice.service - Example systemd service.
Loaded: loaded (/usr/lib/systemd/system/myservice.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2018-05-02 15:03:07 UTC; 48s ago
Main PID: 2973 (bash)
CGroup: /system.slice/myservice.service
├─2973 /bin/bash /usr/bin/test_service.sh
└─3371 sleep 30

May 02 15:03:07 localhost systemd[1]: Started Example systemd service..
May 02 15:03:07 localhost systemd[1]: Starting Example systemd service....
May 02 15:03:07 localhost bash[2973]: Looping...
May 02 15:03:37 localhost bash[2973]: Looping...
{{< /output >}}
```output
● myservice.service - Example systemd service.
Loaded: loaded (/usr/lib/systemd/system/myservice.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2018-05-02 15:03:07 UTC; 48s ago
Main PID: 2973 (bash)
CGroup: /system.slice/myservice.service
├─2973 /bin/bash /usr/bin/test_service.sh
└─3371 sleep 30

For more information about using `systemctl` commands, see the [systemctl guide](/docs/guides/introduction-to-systemctl).
May 02 15:03:07 localhost systemd[1]: Started Example systemd service..
May 02 15:03:07 localhost systemd[1]: Starting Example systemd service....
May 02 15:03:07 localhost bash[2973]: Looping...
May 02 15:03:37 localhost bash[2973]: Looping...
```

For more information about using `systemctl` commands, see the [systemctl guide](/docs/guides/introduction-to-systemctl).

## Troubleshooting

- "Example service started at ..." line does not appear in the output of the status command. The `systemd-cat` output is not reliable because of a race condition. As a workaround update the `test_service.sh` file as follows:
{{< file "test_service.sh" bash >}}
If the `Example service started at ...` line does not appear in the output of the status command, the `systemd-cat` output may not be reliable because of a race condition. As a workaround, you can update the `test_service.sh` file as follows:

```file {title="test_service.sh" lang="bash"}
info=/tmp/myservice-systemd-cat-pipe-info
mkfifo "$info"
trap "exec 3>&-; rm $info" EXIT
Expand All @@ -151,4 +175,4 @@ do
echo "Looping...";
sleep 30;
done
{{< /file >}}
```