How to Set Up a Kiosk System on Linux

How to Set Up a Kiosk System on Linux (with any app you want)

Kiosks aren’t just for airports and DMV lines anymore. Whether you’re building a self-service app for a trade show, launching a digital signage display, or setting up a Chrome-based info terminal for a business, a kiosk system can give your application a polished, plug-and-play user experience. In this guide, I’ll show you how to build a kiosk system using any Linux app—whether it’s a browser in kiosk mode, a custom Python GUI, or something completely off the wall.

What is a Kiosk System?

A “kiosk” system is a minimal setup that boots directly into a single-purpose application. It usually runs on a locked-down Linux box with no desktop distractions, no password prompts, and no escape routes for the average user.

Think:

  • Digital signage at a mall or conference
  • Check-in terminals at a co-working space
  • Interactive product demos in stores
  • Streamlined, distraction-free workstations for focus
Image of Kiosk System in airport

Word of Warning

This guide is designed specifically for Ubuntu Server, not Ubuntu Desktop. The desktop edition comes preloaded with a window manager that can conflict with our custom setup. If you’re trying this on Desktop, expect strange behavior like overlapping sessions or graphical errors.

Prerequisites

Before we dive in, here’s what you need:

Hardware

  • A computer, Raspberry Pi, or thin client that can run Ubuntu Server
  • A keyboard, monitor, and USB drive for installation/setup (you can remove these later)

Software & Packages

  • Ubuntu Server (22.04 or newer) installed
  • Internet access for installing packages
  • The following packages are installed:
sudo apt update && sudo apt install --no-install-recommends \
  xorg openbox xinit

If you want a browser-based kiosk, make sure to install the Chromium browser:

sudo apt install chromium-browser

If chromium-browser doesn’t install, try chromium or snap install chromium depending on your Ubuntu version.

Step 1: Create the Kiosk User

Before anything else, make sure you’re logged in as an administrator (non-kiosk) user. We don’t want to run these setup commands from the kiosk user directly.

We’ll create a dedicated user called kiosk, which will own the session and run the app in isolation. This keeps the system clean and makes resetting or wiping the session super easy.

sudo adduser kiosk --disabled-password --gecos ""

This creates a new user without a password or login prompt. We’ll set it up to log in automatically in the next steps.

Step 2: Set Up Auto Login on TTY1

To make your system boot directly into the kiosk user session, you’ll configure auto-login for the first virtual terminal.

Create this file:

sudo mkdir -p /etc/systemd/system/getty@tty1.service.d
sudo nano /etc/systemd/system/getty@tty1.service.d/override.conf

Paste in:

[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin kiosk --noclear %I $TERM

Now reload systemd:

sudo systemctl daemon-reexec
sudo systemctl restart getty@tty1

Step 3: Make the App Launch on Boot

There are multiple ways to do this, but here’s a method that works for almost any X11-compatible app and will automatically restart it if it crashes.

First, switch into the kiosk user’s home directory:

cd /home/kiosk

Inside the kiosk user’s home directory, open the .bash_profile file:

nano ~/.bash_profile

Paste in:

if [[ -z $DISPLAY ]] && [[ $(tty) = /dev/tty1 ]]; then
  while true; do
    startx
    echo "X server exited. Restarting..."
  done
fi

This .bash_profile file is what loads the X server automatically when the kiosk user logs into the first terminal (tty1). This will keep restarting the graphical app if it crashes or closes.

Make sure to change ownership:

chown kiosk:kiosk ~/.bash_profile
chmod 755 ~/.bash_profile

Step 4: Set Up the Graphical Session

Install a lightweight window manager like openbox, then create the .xinitrc file:

nano ~/.xinitrc

This .xinitrc file defines what runs when startx is executed. It initializes the X session, launches openbox (the minimal window manager of choice), and finally starts your app in full screen mode.

If your app is a locally installed binary or script, paste in the following:

#!/bin/bash
xset -dpms
xset s off
xset s noblank
openbox-session &
sleep 1
exec /path/to/your/app

If your “app” is a website, you can launch Chromium in full-screen kiosk mode like this:

#!/bin/bash
xset -dpms
xset s off
xset s noblank
openbox-session &
sleep 1
chromium-browser --kiosk https://your-kiosk-url.com --incognito 

Change ownership and make sure it’s executable:

chown kiosk:kiosk ~./xinitrc
chmod +x ~/.xinitrc

Step 5: Hide Boot Text (Optional but Clean)

If you want to suppress system messages during boot, edit your GRUB config:

sudo nano /etc/default/grub

Find or add this line and save:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

Then update grub:

sudo update-grub

Step 6: Give X Permissions to the Kiosk User

Add a small bit of config so the kiosk user can access X without sudo:

echo 'xhost +SI:localuser:kiosk' >> /home/kiosk/.xprofile
chmod +x /home/kiosk/.xprofile
chown kiosk:kiosk /home/kiosk/.xprofile

Why This Approach is Fairly Secure

  • User Isolation: Your app runs in a dedicated user environment with no sensitive access to the rest of the system.
  • No Escape Hatches: There’s no GUI login screen or desktop environment to switch users or run other apps.
  • Restart Logic: If the app crashes, it restarts automatically. This is especially useful for public-facing terminals.
  • Boot Cleanliness: Users don’t see scary logs or system output—just a polished boot into your app.

Additional Security Measures

If you want to go from “fairly secure” to “locked down like Fort Knox,” here are a few upgrades to consider:

  • Physically secure the system: Lock BIOS, disable USB boot, hide the tower, and fill unused ports.
  • Input control: Disable unused keyboard keys (especially Ctrl, Alt, Super, F1–F12) and right-clicks.
  • Network security: Disable SSH, or restrict it to key-based auth with a custom port and fail2ban in place.
  • Browser sandboxing: Use AppArmor or Firejail to restrict what the browser (or your app) can access.

Wrapping Up

Now you’ve got a reliable, repeatable way to deploy any application as a kiosk system. Whether it’s a touchscreen catalog at a farmer’s market or a digital art display in a gallery, this setup gives you full control over how your app boots, looks, and behaves.

Let me know what you end up using this for—I’d love to see your kiosks in action!

Leave a Reply