Set up chromium kiosk autostart on a Linux panel

6 min read · Published November 4, 2026

Start the browser from a systemd user service with --kiosk and --app so the dashboard fills the screen with nothing to click away. Delete console=tty1 from cmdline.txt so no boot text prints. Set the brightness PWM output's default to 0 in the controller's I/O tool so the panel stays dark until the dashboard paints, and have the dashboard raise the duty on load.

A dashboard that operators actually use has to come up on its own, fill the screen, and leave nothing else to touch. On a Linux panel that is three settings. A systemd user service keeps launching the browser with the kiosk flags until the display manager's session is up, then holds it there. One word leaves the kernel command line, so no boot text ever prints. And the PWM output that drives the screen's brightness input gets 0 as its default in the controller's I/O configuration tool, so the panel shows nothing at all until the dashboard paints. Do all three and a cold power-up gives you dark glass for half a minute, then the dashboard, and nothing in between. The walkthrough below uses a browser GUI, a Node-RED dashboard in Chromium, and the same order works for any program GUI.

What you need

  • The panel with its Linux image, booted once and reachable over SSH with an admin account, so you are never locked to the screen.
  • The browser installed. Some images install it as chromium-browser, others as chromium; type the name in a terminal and see which one comes back.
  • The dashboard URL, tested once in the browser on your laptop.
  • The controller's I/O configuration tool, when the screen's brightness input is a PWM output driven by the controller. Without a PWM input, skip that layer; the other two still apply.

Bring the dashboard up as a kiosk

  1. Test the flags from a terminal inside the desktop session:

    chromium-browser --kiosk --app=http://10.0.4.21:8080/dashboard
    

    The URL is this article's example; use the one your dashboard serves. --app opens the address as a bare app window with no tabs, no address bar and no buttons. --kiosk puts that window across the whole screen with no frame. With both flags set, the dashboard is the only thing on the glass.

  2. Save the same command line as a user unit at ~/.config/systemd/user/chromium-kiosk.service, with the binary path your image installs:

    [Unit]
    Description=Kiosk dashboard
    
    [Service]
    ExecStart=/usr/bin/chromium-browser --kiosk --app=http://10.0.4.21:8080/dashboard
    Restart=on-failure
    RestartSec=5
    
    [Install]
    WantedBy=default.target
    

    The browser exits while no session is up yet, Restart=on-failure brings it back every 5 s, and the first launch after the display manager brings the session up is the one that holds. That retry is the ordering, because a user service manager has no display-manager target of its own to wait for.

  3. Enable the unit as the kiosk user:

    loginctl enable-linger kiosk
    systemctl --user enable --now chromium-kiosk.service
    

    Lingering starts the user's service manager at boot, so no login is needed. If the image already logs that user in automatically, the session start brings the unit up with it and lingering is optional. If the image does not run user services cleanly, the session's autostart folder runs the same command line after login; on a Wayfire desktop the autostart entry goes in wayfire.ini. Where that entry lives changed with recent desktop releases, and fixing kiosk autostart after a desktop release update lists the places to check. The unit-file fields and the enable steps also appear step by step in a systemd autostart walkthrough.

  4. Power cycle once and watch: a few failed launches, then the dashboard, full screen, with nothing else.

Hide the boot text

  1. Find cmdline.txt on the boot partition. Current images keep the boot files under /boot/firmware/; older ones keep them at the partition root.

  2. Delete one token from the single long line in that file: console=tty1. Keep everything else exactly as it is, and keep the original line in your notes so the edit reverses in one paste.

  3. Reboot. From then on the kernel and the system start silently on the screen, because their messages have no console to print to.

The vendor logo or splash that some boards paint before the kernel is a separate layer with its own settings. Show only a splash screen on an embedded Linux kiosk boot covers that layer start to finish.

Keep the panel dark until the dashboard paints

  1. In the controller's I/O configuration tool, set the default value of the output that drives the screen's brightness input to 0. The tool applies that default on every boot, so the panel stays dark from power-up and nothing that loads before the dashboard is ever painted.

  2. From a terminal, write your working duty to that output once, 70% in the example below, and confirm the panel lights.

  3. Make that write the dashboard's first action on load, so the duty comes up with the first paint.

One floor note: a dark panel reads as a dead panel to an operator walking past. Keep the dark window short and label the frame with what the screen does at power-up.

Example: a Node-RED dashboard on a 15.6-inch panel

The numbers below are this example's inputs. Measure your panel once and keep your own.

Input This example
Panel 15.6-inch touch, 1920 x 1080
Dashboard URL http://10.0.4.21:8080/dashboard
Service RestartSec=5, attempts at 2 s and every 5 s after
PWM default 0, working duty 70%

Power on at 0 s. The kernel runs silently and the panel is dark at 0% duty. The session comes up at 19 s, so the attempts at 2, 7, 12 and 17 s fail and the attempt at 22 s lands. The browser paints at 26 s, that is 22 s plus 4 s to first paint, and the dashboard writes 70% duty at 27 s. The operator sees 27 s of black glass and then the dashboard.

Without the PWM default, the same boot would have shown console text from 2 s to 19 s, 19 - 2 = 17 s of scrolling messages, and a desktop from 19 s to 26 s, 26 - 19 = 7 s of it. With the default at 0, nothing but black appears before first paint. Touch input lands in the app window; there is no frame to drag, no tab to close and no button that leaves.

Trim the dead time

The dark window is boot time plus the retry gap, and both shrink. systemd-analyze blame lists start-up jobs with their times; disable the services the panel does not use, a print service or a long network wait among them. In the example, a session up at 13 s instead of 19 s fails the attempts at 2, 7 and 12 s, lands the attempt at 17 s, paints at 21 s and lights the panel at 22 s, which is 5 s sooner than 27 s. RAM and storage speed move the 4 s paint time the most, because the browser's first paint is the heaviest single step on a small panel.

Check it worked

Pull the power, wait a moment, and power up cold, because that is what the floor does. Then check four things:

  • The screen stays black from power-up: no text, no logo, no desktop at any point.
  • The dashboard appears once and fills the panel edge to edge at its native 1920 x 1080 with no scrollbars. If it underfills or scrolls, diagnosing kiosk browser sizing in an HMI window walks the size checks.
  • Touch works inside the dashboard and nowhere else: nothing closes the window and nothing switches away from it.
  • A second cold power-up gives the same result.

When the panel should not be the dashboard

Kiosk mode fits one GUI, one station, touch as the only input. If the same panel is the machine's HMI, leave the HMI its screen and put the operator dashboard somewhere else. If the wall next to the machine needs a status board that plays on its own, shift targets, safety notices and shift summaries, a small Android signage unit does that offline: it plays images and video from a card or stick with no network and no subscription, and the player brings the show up full screen at power-on. That job lives in our offline player; the startup discipline on those units is Android signage app startup for a single-purpose display; and the choice between a live dashboard and a played board gets its own answer in live factory data display: signage or dashboard?.

Recommendation: Run the browser from a systemd user service with --kiosk and --app, delete console=tty1 from the kernel command line, and set the brightness output's default to 0 with the dashboard writing the working duty on load, when the panel serves one dashboard to operators whose only input is touch. Keep the desktop session and skip the kiosk setup when your own team needs other tools on the same panel, and leave the machine's HMI screen alone when the dashboard can live on a second screen.

Questions

Do I need both --kiosk and --app?

--app opens the address as a bare app window with no tabs, address bar or buttons; --kiosk adds full screen with no window frame. On recent browser builds either flag alone gets close, and together they give the largest possible GUI with nothing left to click. Flags are read at launch only, so test the exact line you put in the service from a terminal before you enable the unit.

How do I service the panel once the desktop is gone?

Keep SSH enabled. The kiosk setup changes what the screen shows; it does not need to change how you reach the machine. Connect from a laptop with an admin account, edit the unit file or the boot line, and restart the service or the panel. If a keyboard stays plugged in for emergencies, switching to a text console is the manual way in.

Can the unit start a Tkinter or other program GUI instead of a browser?

Yes. The unit runs one command, so point ExecStart at your GUI program's launcher and keep the retry behaviour that waits for the session. The kiosk flags belong to the browser; a windowing toolkit such as Tkinter draws its own full-screen window, so use the toolkit's full-screen option instead. The console line and the PWM default act on the screen and the boot text, so they work the same for any GUI.

Why does the screen stay black after the dashboard should be up?

The PWM default of 0 is still in force because nothing raised it. The unit runs and the browser paints at 0% duty, so the picture exists but stays invisible. Check that the dashboard actually writes the working duty on load: run that write once from a terminal to confirm the output moves, then let the dashboard do it on every start. Keep the terminal write command to hand so you can recover over SSH.

Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.

Keep reading

Build your signAsk for a quote