Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ee05083
Auto-merge master back to develop
actions-user Jan 1, 2026
37809fe
Auto-merge master back to develop
actions-user Jan 11, 2026
7424892
docs: improve autostart guide with user systemd service for full Elec…
vectorman115 Jan 13, 2026
616b1a0
Auto-merge master back to develop
actions-user Jan 19, 2026
3f8b47c
Auto-merge master back to develop
actions-user Jan 25, 2026
8e0f54b
style: set carbon ads background color to inherit (#350)
KristjanESPERANTO Jan 26, 2026
c822d50
Auto-merge master back to develop
actions-user Jan 26, 2026
3211005
location of default modules changed (#353)
khassel Jan 27, 2026
893a46c
move custom.css from css to config (#354)
khassel Jan 28, 2026
8db08c4
Merge branch 'mm_master' into mm_develop
Feb 2, 2026
7b7016e
Auto-merge master back to develop
actions-user Feb 6, 2026
3656c95
update variables in config
khassel Feb 8, 2026
56e69dc
add secrets.md
khassel Feb 8, 2026
d50bdff
fix typo
KristjanESPERANTO Feb 14, 2026
7efbaa4
add missing "
KristjanESPERANTO Feb 14, 2026
091c5db
node_modules/vitepress/types/default-theme.d.ts
KristjanESPERANTO Feb 14, 2026
2ee98de
apply Prettier formatting
KristjanESPERANTO Feb 14, 2026
6a1097b
handle cspell issues
KristjanESPERANTO Feb 14, 2026
2b9042e
Merge pull request #358 from khassel/config
sdetweil Feb 15, 2026
b0a33ac
add weatherapi options to weather module configuration (#359)
angeldeejay Feb 22, 2026
db11193
docs(compliments): clarify remoteFile path resolution and limitations…
KristjanESPERANTO Feb 23, 2026
5f844c7
docs: correct loaded() - server-side only, not a client-side hook (#361)
KristjanESPERANTO Feb 24, 2026
d5ddebe
docs: clarify that public folder requires node_helper.js (#362)
KristjanESPERANTO Feb 26, 2026
47dc1f1
Auto-merge master back to develop
actions-user Mar 1, 2026
9a14928
docs: explain physical concept and hardware scope on landing page (#365)
KristjanESPERANTO Mar 5, 2026
34f7962
add weather templates (#366)
khassel Mar 9, 2026
6d8f81d
weather: add themes example
khassel Mar 13, 2026
179bcc0
Merge pull request #367 from khassel/develop
sdetweil Mar 13, 2026
3cb1a77
calendar: align showEnd and dateEndFormat defaults (#368)
KristjanESPERANTO Mar 16, 2026
e5a6e05
Auto-merge master back to develop
actions-user Mar 21, 2026
0ae8203
Auto-merge master back to develop
actions-user Mar 26, 2026
1cd5ff0
fix failing tests
khassel Apr 1, 2026
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
1 change: 1 addition & 0 deletions .vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export default defineConfig({
collapsed: true,
items: [
{ text: "Introduction", link: "/configuration/introduction" },
{ text: "Secrets", link: "/configuration/secrets" },
{
text: "Autostart your MagicMirror²",
link: "/configuration/autostart",
Expand Down
2 changes: 2 additions & 0 deletions .vitepress/theme/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
--vp-c-danger-2: var(--vp-c-red-2);
--vp-c-danger-3: var(--vp-c-red-3);
--vp-c-danger-soft: var(--vp-c-red-soft);

--vp-carbon-ads-bg-color: inherit;
}

/**
Expand Down
207 changes: 161 additions & 46 deletions configuration/autostart.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,29 +109,117 @@ pm2 show mm

## Using systemd/systemctl

Note: Systemctl is a control interface for systemd, a powerful service manager
often found in full Linux systems. This approach is most like only applicable
for those using the "server only" setup running on a linux server.
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.

### Create service file
The examples below assume:

To start, you'll need to create a config file via your editor of choice (nano
used in these examples):
- MagicMirror is installed in "/home/server/MagicMirror/"
- Node.js is located at "/usr/bin/node" (Run `which node` if 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)

::: warning 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

```shell
mkdir -p ~/.config/systemd/user
nano ~/.config/systemd/user/magicmirror.service
```

Note: 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)

```ini
[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.target
```

Notes:

- %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)

```shell
# 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.service
```

Tip: 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

```shell
sudo nano /etc/systemd/system/magicmirror.service
```

Place the below text into your new file, modify as needed (see notes below) then
save & exit. Notes: The example assumes MagicMirror is installed in the
"WorkingDirectory" of "/home/server/MagicMirror/" and your node install is
located at "/usr/bin/node" (run `which node` if you're unsure where to find
node) this means your full manual start command would be "/usr/bin/node
/home/server/MagicMirror/serveronly". While you almost certainly don't type this
all out when you run manually, systemctl requires full paths. This example also
assumes you have an existing Linux user of "server", but any user will do.
"root" will certainly work but has the potential to do more damage, so you
should avoid it if possible.
#### Paste the configuration

```ini
[Unit]
Expand All @@ -151,51 +239,44 @@ ExecStart=/usr/bin/node serveronly
WantedBy=multi-user.target
```

### Control MM with systemctl
This runs as a background service - no GUI access. You’ll need a separate
browser (on another device or locally) to view http://localhost:8080.

Now try starting MM with the commands below. If start is successful work, use
the 'enable' command below to automatically start when MM fails or is rebooted.
If MM does not start, use the "status" command below to see most recent errors.
#### Control the service (requires sudo)

Note: For any of the below commands 'magicmirror.service' can be replaced with
`magicmirror` as systemd will automatically look for `\*.service`
```shell
# Reload systemd config
sudo systemctl daemon-reload

#### Start MM with systemctl
# Start MagicMirror now
sudo systemctl start magicmirror

```shell
sudo systemctl start magicmirror.service
```
# Enable auto-start on boot
sudo systemctl enable magicmirror

#### Stop MM with systemctl
# Restart MagicMirror
sudo systemctl restart magicmirror.service

```shell
# Stop MagicMirror
sudo systemctl stop magicmirror.service
```

#### To check the status of MagicMirror²

```shell
sudo systemctl status magicmirror.service
# Disable auto-start
sudo systemctl disable magicmirror.service
```

#### Allow autostart MagicMirror² on boot

Note: does not start immediately, need to run start command or reboot
### Auto-Starting a Browser (for serveronly mode)

```shell
sudo systemctl enable magicmirror.service
```
If you still want a local display while using serveronly, auto-start Chromium in
kiosk mode

#### Disable autostart of MagicMirror²
#### Edit the LXDE autostart file

```shell
sudo systemctl disable magicmirror.service
mkdir -p ~/.config/lxsession/LXDE-pi
nano ~/.config/lxsession/LXDE-pi/autostart
```

### Autostart browser for server mode

Create file `/home/server/.config/lxsession/LXDE-pi/autostart` with the
following contents:
#### Add these lines

```shell
@lxpanel --profile LXDE-pi
Expand All @@ -205,7 +286,14 @@ following contents:
@sh /home/server/bin/start-chromium.sh
```

Create file `/home/server/bin/start-chromium.sh` with the following contents:
#### Create the Chromium launcher script

```shell
mkdir -p ~/bin
nano ~/bin/start-chromium.sh
```

#### Add the following contents

```shell
#!/bin/sh
Expand All @@ -228,3 +316,30 @@ chromium-browser \
--start-maximized \
--kiosk http://localhost:8080 &
```

#### Make it executable

```shell
chmod +x ~/bin/start-chromium.sh
```

### Troubleshooting

- **Service won’t start? Check logs**

```shell
journalctl --user -u magicmirror -f # for user service
sudo journalctl -u magicmirror -f # for system service
```

Also 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`

```shell
Environment=DISPLAY=:0
Environment=XAUTHORITY=%h/.Xauthority
```

- **Permission denied?** Never run Electron as root.
41 changes: 19 additions & 22 deletions configuration/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ The following properties can be configured, place them above the modules item:
| `units` | The units that will be used in the default weather modules. Possible values are `metric` or `imperial`. | `metric` |
| `electronOptions` | An optional array of Electron (browser) options. This allows configuration of e.g. the browser screen size and position (example: `electronOptions: { fullscreen: false, width: 800, height: 600 }`). Kiosk mode can be enabled by setting `kiosk: true`, `autoHideMenuBar: false` and `fullscreen: false`. More options can be found [here](https://github.com/electron/electron/blob/master/docs/api/browser-window). This will most likely be used in advanced installations, below. | [] |
| `electronSwitches` | An optional array of Electron switches. This allows configuration of electron app itself. <br> This properties will not affect the `serveronly` mode. Usually normal `MM` users don't need this property, but if you are a hard-core hacker, you might need this to handle Electron itself over `MagicMirror` provides. More options can be found [here](https://www.electronjs.org/docs/latest/api/command-line-switches) (Not all available switches are described there.)<br>example:`electronSwitches:["enable-transparent-visuals", "disable-gpu"];` | [] |
| `customCss` | The path of the `custom.css` stylesheet. The default is `css/custom.css`. | `css/custom.css` |
| `watchTargets` | An optional array of file paths to monitor when using `node --run server:watch`. When any of these files change, the server automatically restarts and connected browsers reload. Particularly useful when frequently modifying `config.js`, `custom.css`, or module files during development or setup. Example: `watchTargets: ["config/config.js", "css/custom.css", "modules/MMM-MyModule/MMM-MyModule.js"]`. See [Development Mode](/core-development/debugging#watch-mode-with-auto-reload) for more details. | `undefined` |
| `customCss` | The path of the `custom.css` stylesheet. The default is `config/custom.css`. | `config/custom.css` |
| `watchTargets` | An optional array of file paths to monitor when using `node --run server:watch`. When any of these files change, the server automatically restarts and connected browsers reload. Particularly useful when frequently modifying `config.js`, `custom.css`, or module files during development or setup. Example: `watchTargets: ["config/config.js", "config/custom.css", "modules/MMM-MyModule/MMM-MyModule.js"]`. See [Development Mode](/core-development/debugging#watch-mode-with-auto-reload) for more details. | `undefined` |

After the above options, you will then add modules. See
[module configuration](/modules/configuration) for more information.
Expand All @@ -71,11 +71,11 @@ After the above options, you will then add modules. See
There are two environment variables that override part or all of config.js. They
are:

| Environment Variable Name | Use |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| MM_CONFIG_FILE | This specifies an alternate configuration file for the system. This is useful when running multiple mirrors on the same device. This does not work with the template option below. NOTE: this file **_MUST_** be located in a directory within the MagicMirror directory. Ideally, place any config file in the config subdirectory. |
| MM_PORT | This specifies an alternate TCP/IP port, overriding "port" item within the config file. This is useful for testing to see if the product will run using another port. |
| mmFetchTimeout | time in milliseconds for fetch timeout. default (30000) <br><br>this value can be used to adjust the nodejs fetch function timeout value for all node_helper modules that use fetch() |
| Environment Variable Name | Use |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MM_CONFIG_FILE | This specifies an alternate configuration file for the system. This is useful when running multiple mirrors on the same device. NOTE: this file **_MUST_** be located in a directory within the MagicMirror directory. Ideally, place any config file in the config subdirectory. |
| MM_PORT | This specifies an alternate TCP/IP port, overriding "port" item within the config file. This is useful for testing to see if the product will run using another port. |
| mmFetchTimeout | time in milliseconds for fetch timeout. default (30000) <br><br>this value can be used to adjust the nodejs fetch function timeout value for all node_helper modules that use fetch() |

#### Examples of use

Expand Down Expand Up @@ -117,18 +117,17 @@ node --run config:check
[26.12.2023 18:13.13.062] [INFO] Your configuration file doesn't contain syntax errors :)
```

### Configuration Template system
### Environment variables inside the configuration file

`config.js.template` can be used instead of `config.js`. This allows you to use
variables to replace hardcoded options. When starting MagicMirror² a `config.js`
is created from `config.js.template` and the variables are resolved. This is
most useful for tech support provided on the
Since MagicMirror² version `v2.35.0` curly braced bash environment variable are
allowed inside the `config.js` file. This allows you to use variables to replace
hardcoded options. When starting MagicMirror² the variables are resolved. This
is most useful for tech support provided on the
[forums](http://forum.magicmirror.builders) and sharing your configuration.
Note: You cannot use this with MM_CONFIG_FILE above at this time.

Variables must be inserted as `${MY_VARIABLE}`, examples:

`config.js.template`:
`config.js`:

```js
let config = {
Expand All @@ -140,9 +139,7 @@ let config = {
if (typeof module !== "undefined") {module.exports = config;}
```

would become

`config.js`:
would be translated to

```js
let config = {
Expand All @@ -163,8 +160,8 @@ variable is defined in both ways the linux environment variable is used.

#### Using a `config.env` file

This file must be in the same folder as the `config.js.template` and contains
the variables, using the example from above:
This file must be in the same folder as the `config.js` and contains the
variables, using the example from above:

File content of `config.env`:

Expand All @@ -176,7 +173,7 @@ MY_HTTPS=false

#### Using linux environment variables

define them before you start MagicMirror², in a bash script, for example:
Define them before you start MagicMirror², in a bash script, for example:

```bash
cd ~/MagicMirror
Expand Down Expand Up @@ -272,14 +269,14 @@ if (typeof module !== "undefined") {
}
```

#### config.js.template example
#### config.js with variables

User likes to help German language users in the forums. As such, he wants to be
able to paste bits of his config.js into the forums to show as an example, but
don't want to share his private data, and has a hard time remembering to remove
them from the config.js file.

`config.js.template`:
`config.js`:

```js
let config = {
Expand Down
Loading