Make a Raspberry Pi 3 program start on boot

Let’s say you have developed a super program running on your Raspberry Pi 3 board. But here’s the problem: to start it you always have to power on the board, log in (with a screen and keyboard or via ssh), and start your program. How could you make your Raspberry Pi 3 program start on boot?

Fortunately, there are some solutions to your problem. The most complete one is systemd. Systemd is simply a standard Linux process to control which program should start when the operating system boots. Good news, it’s already installed for you if you use Raspbian/Noobs/Ubuntu for RPi.

In this tutorial I’ll show you step by step how to use systemd to make your Raspberry Pi 3 program start on boot.

Ready? Let’s go!

Create the Raspberry Pi 3 program which will start on boot

To be able to start a program, you first need to have one. Let’s create a simple Python program in your home repository. Note that I’ll use “/home/pi” as the home repository during all the tutorial, so you’ll have to replace “pi” with your username if you changed it from the default one.

Let’s say we want to make sure a given file exists when we boot the Raspberry Pi 3.

In your home directory, create a Python file and make it executable.

$ cd ~
$ touch ensure-file-exists.py 
$ chmod +x ensure-file-exists.py

Now, edit the file with whatever text editor you prefer (Nano, Vim, Emacs, etc). Here’s the content of the script:

#!/usr/bin/env python3

if __name__ == '__main__':
    with open("/home/pi/required_file", "w") as f:
        f.write("OK\n")

It’s pretty basic. We just create a file with the write mode, and write “OK” inside. If the file doesn’t exist, it will be created. Note that by using with, we don’t need to write the code to close the file.

Now, save and exit. Let’s run the program to check if it’s working correctly (it should!):

$ ls
Desktop  Documents  Downloads  ensure-file-exists.py  MagPi  Music  Pictures  Public  Templates  Videos
$ python3 ensure-file-exists.py 
$ ls
Desktop  Documents  Downloads  ensure-file-exists.py  MagPi  Music  Pictures  Public  required_file  Templates  Videos
$ cat required_file 
OK

Don’t forget to remove the file that was created by your script.

pi@raspberrypi:~ $ rm required_file

Add a systemd service

Now that we have a script, and we know it’s working correctly, let’s create a new systemd service.

$ cd /lib/systemd/system
$ sudo touch ensure-file-exists.service

All services will be located in the “/lib/systemd/system” folder. On boot, systemd will look after all enabled services and start them.

Now, edit this file (with sudo) and write the following:

[Unit]
Description=Ensure file exists on boot
After=multi-user.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/ensure-file-exists.py
User=pi

[Install]
WantedBy=multi-user.target

This is a very basic template for writing a systemd service. Here’s what each field means:

  • Description: not important, just write anything you want here.
  • After: this controls when the service should be triggered. Basically, “multi-user.target” means that the service will be triggered once the multi-user environment is available. Note that this will not wait until the login or desktop screen appears.
  • ExecStart: the actual command line to execute. Here we start the Python script that we’ve created in the home repository. Note that it’s important to use an absolute path for the script path.
  • User: if we don’t specify the user, then the program will be executed as root user. What could be the problem here? Well, the Python script we execute is creating a file. If the root user launches the Python script, then the file will be created by the root user, not by the “pi” user. So, the “pi” user might encounter permission issues when trying to modify/remove this script.
  • WantedBy: as we specified “multi-user.target” before, we need to also write it here.

The service is now complete! You can now save and exit.

Enable the systemd service

If you don’t do anything else, well… Nothing will happen. You need to enable the service so systemd will run it on boot.

$ sudo systemctl daemon-reload
$ sudo systemctl enable ensure-file-exists.service 
Created symlink /etc/systemd/system/multi-user.target.wants/ensure-file-exists.service -> /lib/systemd/system/ensure-file-exists.service.

Once done, your service will be started on every Raspberry Pi boot!

To check if your service is enabled, use this command:

$ sudo systemctl list-unit-files | grep ensure-file-exists
ensure-file-exists.service             enabled

This tells you that 1. The “ensure-file-exists” service exists, and 2. it is enabled.

If you want to disable the service, simply do:

$ sudo systemctl disable ensure-file-exists.service 
Removed /etc/systemd/system/multi-user.target.wants/ensure-file-exists.service.

Test the service to make the Raspberry Pi 3 program start on boot

To test the service, simply reboot your Raspberry Pi 3, and check if the “required_file” was created in your home repository.

There is also another way to test the correct execution of the service. As you saw before, you can enable/disable a service with systemctl enable and systemctl disable. Well, you can start (and stop, if your program runs indefinitely) the service with systemctl start and systemctl stop.

$ sudo systemctl start ensure-file-exists.service

This will start your newly created service just as when the Raspberry Pi boots. Very handy for testing without having to reboot every time. Also, if you want to always start a program on boot and stop it manually when you want to, the systemctl stop function is perfect for that.

When to use systemd with Raspberry Pi?

Note that systemd is much more complex than that, I just showed you here a very basic example – though it’s all that you need to know in order to make any Raspberry Pi 3 program start on boot.

But, what are some good examples of when you’ll have to use this?

  • Web server: once you have developed the program, you can make a headless server accessible whenever you boot your Raspberry Pi.
  • Robot: a Raspberry Pi board is really small and perfect for being embedded on a robot. With systemd you can make your robot start directly when you power it on.

Any cool Raspberry Pi program you’ve made that automatically starts on boot? Share your project in the comment section below!

Leave a Comment