{"id":264,"date":"2022-08-07T16:17:45","date_gmt":"2022-08-07T21:17:45","guid":{"rendered":"https:\/\/www.jaysonbrush.com\/?p=264"},"modified":"2026-02-04T21:21:16","modified_gmt":"2026-02-05T02:21:16","slug":"raspberry-pi-digital-signage","status":"publish","type":"post","link":"https:\/\/www.jaysonbrush.com\/index.php\/2022\/08\/07\/raspberry-pi-digital-signage\/","title":{"rendered":"Building a Low-Cost Digital Signage Display with Raspberry Pi"},"content":{"rendered":"\n<p class=\"lead\">A step-by-step guide to transforming a Raspberry Pi Zero W into a dedicated digital signage kiosk\u2014perfect for displaying dynamic content like movie posters, dashboards, or informational displays.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Problem<\/h2>\n\n\n\n<p>I wanted a digital display in my home theater that would showcase movie posters from my Plex media server. Commercial digital signage solutions are expensive, and repurposing an old tablet felt wasteful and unreliable for 24\/7 operation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Solution<\/h2>\n\n\n\n<p>A Raspberry Pi Zero W ($15) configured as a dedicated kiosk. It boots directly into a fullscreen Chromium browser displaying content from any URL\u2014no desktop environment, no distractions, just the content.<\/p>\n\n\n\n<p>For my setup, I used <a href=\"https:\/\/www.mattsshack.com\/plex-movie-poster-display-v3\/\">Matt&#8217;s Plex Movie Poster Display<\/a> running on a local VM, but this kiosk can display any web-based content: dashboards, calendars, weather displays, or custom signage.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Requirements<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Raspberry Pi Zero W (or any Raspberry Pi)<\/li>\n<li>MicroSD card (8GB minimum)<\/li>\n<li>Display with HDMI input<\/li>\n<li>Raspbian Buster installed<\/li>\n<li>Network connectivity (WiFi or Ethernet)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Instructions<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Initial Configuration<\/h3>\n\n\n\n<p>Boot your Pi and log in with the default credentials (<code>pi<\/code> \/ <code>raspberry<\/code>), then run the configuration utility:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo raspi-config<\/code><\/pre>\n\n\n\n<p>Configure the following settings:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Change the default password<\/li>\n<li>Set your hostname<\/li>\n<li>Configure WiFi (SSID and password)<\/li>\n<li>Set your timezone<\/li>\n<li>Enable SSH under Interface Options<\/li>\n<li>Set Boot Options \u2192 Desktop \/ CLI \u2192 Console Autologin<\/li>\n<\/ul>\n\n\n\n<p>Finish and reboot. From this point forward, you can work remotely via SSH.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Update the System<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get update && sudo apt-get upgrade -y<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Install Minimal Display Environment<\/h3>\n\n\n\n<p>Install only what&#8217;s needed for kiosk mode\u2014no full desktop environment:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get install --no-install-recommends xserver-xorg x11-xserver-utils xinit openbox chromium-browser -y<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Configure Openbox Autostart<\/h3>\n\n\n\n<p>Edit the Openbox autostart configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nano \/etc\/xdg\/openbox\/autostart<\/code><\/pre>\n\n\n\n<p>Add the following content:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Disable screen saver and power management\nxset s off\nxset s noblank\nxset -dpms\n\n# Allow quitting X server with CTRL-ALT-Backspace\nsetxkbmap -option terminate:ctrl_alt_bksp\n\n# Clear Chromium crash flags and launch in kiosk mode\nsed -i 's\/\"exited_cleanly\":false\/\"exited_cleanly\":true\/' ~\/.config\/chromium\/'Local State'\nsed -i 's\/\"exited_cleanly\":false\/\"exited_cleanly\":true\/; s\/\"exit_type\":\"[^\"]\\+\"\/\"exit_type\":\"Normal\"\/' ~\/.config\/chromium\/Default\/Preferences\nchromium-browser --disable-infobars --noerrdialogs --incognito --kiosk 'https:\/\/YOUR-URL-HERE'<\/code><\/pre>\n\n\n\n<p>Replace <code>https:\/\/YOUR-URL-HERE<\/code> with the URL you want to display.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Auto-Start on Boot<\/h3>\n\n\n\n<p>Configure X to start automatically when the Pi boots:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nano ~\/.profile<\/code><\/pre>\n\n\n\n<p>Add this line at the end:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && startx -- -nocursor<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Optional: Clean Boot Experience<\/h3>\n\n\n\n<p>For a cleaner boot sequence, edit <code>\/boot\/config.txt<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nano \/boot\/config.txt<\/code><\/pre>\n\n\n\n<p>Add these lines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Disable rainbow splash screen\ndisable_splash=1\n\n# Rotate display (if needed for vertical orientation)\n# display_rotate=3<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Result<\/h2>\n\n\n\n<p>After a reboot, your Pi will boot directly into a fullscreen browser displaying your content. No login prompts, no desktop, no cursor\u2014just clean digital signage running 24\/7 on minimal hardware.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>I wanted to setup a digital signage in my house for use with my home theater. I used https:\/\/www.mattsshack.com\/plex-movie-poster-display-v3\/ and built a VM to host the site displaying movie posters from my Plex Server. I then used a Raspberry Pi Zero W to view the poster site on the digital display.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_links_to":"","_links_to_target":""},"categories":[30],"tags":[],"class_list":["post-264","post","type-post","status-publish","format-standard","hentry","category-projects"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/posts\/264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/comments?post=264"}],"version-history":[{"count":10,"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/posts\/264\/revisions"}],"predecessor-version":[{"id":335,"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/posts\/264\/revisions\/335"}],"wp:attachment":[{"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/media?parent=264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/categories?post=264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jaysonbrush.com\/index.php\/wp-json\/wp\/v2\/tags?post=264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}