Autostart your MagicMirror²
The methods below describe ways to automatically start your MagicMirror² on boot, and even ways to keep it running in case of a failure.
Using PM2
PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks. In this case we will use it to keep a shell script running.
Install PM2
Install PM2 using NPM:
sudo npm install -g pm2Starting PM2 on Boot
To make sure PM2 can do its job when (re)booting your operating system, it needs to be started on boot. Luckily, PM2 has a handy helper for this.
pm2 startupPM2 will now show you a command you need to execute.
Make a MagicMirror² start script
To use PM2 in combination with MagicMirror², we need to make a simple shell script. Preferable, we put this script outside the MagicMirror² folder to make sure it won't give us any issues if we want to upgrade the mirror.
cd ~
nano mm.shAdd the following lines:
cd ./MagicMirror
DISPLAY=:0 node --run startSave and close, using the commands CTRL-O and CTRL-X. Now make sure the shell script is executable by performing the following command:
chmod +x mm.shYou are now ready to the MagicMirror² using this script using PM2.
Starting your MagicMirror² with PM2
Simply start your mirror with the following command:
pm2 start mm.shYou mirror should now boot up and appear on your screen after a few seconds.
Enable restarting of the MagicMirror² script
To make sure the MagicMirror² restarts after rebooting, you need to save the current state of all scripts running via PM2. To do this, execute the following command
pm2 saveAnd that's all there is! Your MagicMirror² should now reboot after start, and restart after any failure.
Controlling your MagicMirror² via PM2
With your MagicMirror running via PM2, you have some handy tools at hand:
Restarting your MagicMirror²
pm2 restart mmStopping your MagicMirror²
pm2 stop mmShow the MagicMirror² logs
pm2 logs mmShow the MagicMirror² process information
pm2 show mmUsing systemd/systemctl
Systemctl is a control interface for systemd, a powerful service manager often found in full Linux systems. This approach works for both headless (serveronly) and full Electron UI modes.
The examples below assume:
- MagicMirror is installed in "/home/server/MagicMirror/"
- Node.js is located at "/usr/bin/node" (Run
which nodeif you're unsure.) - Systemd requires absolute paths for all binaries and directories.
- Also, the examples use a user named "server" - replace it with your actual username.
- Avoid running as "root" unless absolutely necessary - it increases security risks.
Full Electron UI Mode (Recommended for Desktop Auto-Login)
Note This section is tailored for Raspberry Pi OS Desktop. Users
on other Linux distributions may need to adapt the configuration. :::
For systems with graphical auto-login (e.g. Raspberry Pi OS Desktop), it's best to use a user systemd service. It starts automatically after the user session is fully initialized.
Create service file
mkdir -p ~/.config/systemd/user
nano ~/.config/systemd/user/magicmirror.serviceNote: Why "~/.config/systemd/user/"? User services run in the context of your desktop session, giving them access to DISPLAY (or WAYLAND_DISPLAY), sound, and other GUI resources.
Paste the following configuration (adjust paths as needed)
[Unit]
Description=MagicMirror
After=graphical-session.target
[Service]
Type=simple
Restart=always
RestartSec=15
WorkingDirectory=%h/MagicMirror
ExecStart=/usr/bin/node --run start
# Uncomment below lines only for debugging. Persistent logging wears out SD cards.
#StandardOutput=file:%h/MagicMirror/magicmirror.log
#StandardError=file:%h/MagicMirror/magicmirror.log
[Install]
WantedBy=default.targetNotes:
- %h is a systemd placeholder for the user’s home directory (e.g., /home/server). It’s safer than hardcoding paths.
- Logging note: By default, this service does not write logs to disk to avoid excessive writes on SD cards. If you need logs for debugging, uncomment the StandardOutput and StandardError lines in the service file. Remember to disable them again after troubleshooting. The file is overwritten on every restart (due to
file:mode).
Enable and start the service
Run these commands as your regular user (not with sudo)
# Reload systemd user config
systemctl --user daemon-reload
# Start MagicMirror now
systemctl --user start magicmirror
# Enable auto-start on boot (after user login)
systemctl --user enable magicmirror
# Restart MagicMirror
systemctl --user restart magicmirror.service
# Stop MagicMirror
systemctl --user stop magicmirror.service
# Disable auto-start
systemctl --user disable magicmirror.serviceTip: You can omit .service - systemctl --user start magicmirror works just as well.
Ensure auto-login is enabled
For this to work on boot, your system must auto-login to the desktop (no password prompt). On Raspberry Pi OS, configure this via
sudo raspi-config → System Options → Boot / Auto Login → Desktop Autologin
Headless Mode (serveronly)
Use this if you run MagicMirror without a local GUI (e.g., serving to remote browsers or using a separate display device).
Create a system-wide service
sudo nano /etc/systemd/system/magicmirror.servicePaste the configuration
[Unit]
Description=MagicMirror
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=server
WorkingDirectory=/home/server/MagicMirror/
ExecStart=/usr/bin/node serveronly
[Install]
WantedBy=multi-user.targetThis runs as a background service - no GUI access. You’ll need a separate browser (on another device or locally) to view http://localhost:8080.
Control the service (requires sudo)
# Reload systemd config
sudo systemctl daemon-reload
# Start MagicMirror now
sudo systemctl start magicmirror
# Enable auto-start on boot
sudo systemctl enable magicmirror
# Restart MagicMirror
sudo systemctl restart magicmirror.service
# Stop MagicMirror
sudo systemctl stop magicmirror.service
# Disable auto-start
sudo systemctl disable magicmirror.serviceAuto-Starting a Browser (for serveronly mode)
If you still want a local display while using serveronly, auto-start Chromium in kiosk mode
Edit the LXDE autostart file
mkdir -p ~/.config/lxsession/LXDE-pi
nano ~/.config/lxsession/LXDE-pi/autostartAdd these lines
@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
@point-rpi
@sh /home/server/bin/start-chromium.shCreate the Chromium launcher script
mkdir -p ~/bin
nano ~/bin/start-chromium.shAdd the following contents
#!/bin/sh
set -e
CHROMIUM_TEMP=~/tmp/chromium
rm -Rf ~/.config/chromium/
rm -Rf $CHROMIUM_TEMP
mkdir -p $CHROMIUM_TEMP
chromium-browser \
--disable \
--disable-translate \
--disable-infobars \
--disable-suggestions-service \
--disable-save-password-bubble \
--disk-cache-dir=$CHROMIUM_TEMP/cache/ \
--user-data-dir=$CHROMIUM_TEMP/user_data/ \
--start-maximized \
--kiosk http://localhost:8080 &Make it executable
chmod +x ~/bin/start-chromium.shTroubleshooting
- Service won’t start? Check logs
journalctl --user -u magicmirror -f # for user service
sudo journalctl -u magicmirror -f # for system serviceAlso you may look into ~/MagicMirror/magicmirror.log.
- Blank screen? Verify DISPLAY=:0 and XAUTHORITY are set. Add lines below into your
~/.config/systemd/user/magicmirror.service
Environment=DISPLAY=:0
Environment=XAUTHORITY=%h/.Xauthority- Permission denied? Never run Electron as root.
