Build Your Own Aurora Deck
Run Aurora Deck on a dedicated display, self-host it on your own hardware, or just point any device at auroradeck.com. Pick the path that suits you.
Already subscribed or on a free trial? Skip hosting entirely. Just point your browser, tablet, or dedicated display at auroradeck.com and follow the device setup guide.
Jump to device setup →Run Aurora Deck on your own infrastructure with Docker. No subscription, no data leaving your home. Set up hosting first, then configure your display device.
Jump to Docker Compose →Docker Compose
If you plan to use Google Calendar sync or the Google Photos screensaver, complete the Google Integration section below before deploying — those environment variables must be set for those features to work.
Start
Stop
# Aurora Deck — Self-Hosted Docker Compose
#
# Quick start:
# 1. Copy this file to your server
# 2. Review and update any Environment Variables you see fit
# 3. Run: docker compose -f aurora-deck-docker-compose.yaml up -d
#
# Full setup guide: https://auroradeck.com/build-your-own
services:
# ── Local photo storage (fake GCS) ───────────────────────────────────────────
# Provides a local GCS-compatible bucket for screensaver photo uploads.
# Comment out this service (and GCS_BUCKET / GCS_ENDPOINT below) if you want
# to use a real Google Cloud Storage bucket instead.
fake-gcs-server:
image: fsouza/fake-gcs-server
container_name: aurora-deck-fake-gcs
ports:
- "4443:4443"
command: ["-scheme", "http", "-port", "4443", "-backend", "filesystem", "-filesystem-root", "/storage"]
volumes:
- gcs-data:/storage
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:4443/storage/v1/b"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
postgres:
image: postgres:17-alpine
container_name: aurora-deck-postgres
environment:
POSTGRES_DB: aurora_deck_db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres # must match DB_PASSWORD in the aurora-deck service below
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
aurora-deck:
image: us-east1-docker.pkg.dev/aurora-deck-483804/aurora-deck/aurora-deck:latest
container_name: aurora-deck
ports:
- "8080:8080"
environment:
# ── Database ─────────────────────────────────────────────────────────────
# Aurora Deck connects to the postgres service defined above.
# DB_HOST must match the service name ("postgres").
DB_HOST: postgres
DB_PORT: 5432
DB_NAME: aurora_deck_db
DB_USERNAME: postgres
DB_PASSWORD: postgres # same value as POSTGRES_PASSWORD above
# ── Application URLs ─────────────────────────────────────────────────────
# The address where Aurora Deck is reachable from a browser.
# For a home server use your LAN IP, e.g. http://192.168.1.100:8080
APP_BASE_URL: http://localhost:8080 # URL of this server, used for OAuth redirects and API links
APP_FRONTEND_URL: http://localhost:8080 # URL the browser uses to reach the app (usually same as APP_BASE_URL)
# ── Security ─────────────────────────────────────────────────────────────
# JWT_SECRET signs authentication tokens. Use a long random string (min 32 chars).
# Generate one with: openssl rand -hex 32
JWT_SECRET: f28559313e4523279dda7163807667c331632132f9eb481dd6480b64902c0433
# OAUTH_STATE_SECRET_KEY protects the OAuth state parameter against CSRF.
# Generate one with: openssl rand -hex 16
OAUTH_STATE_SECRET_KEY: b59fff3fa51d0e582a42acf6fd22970ddc7221e5393036528ff1677d59d3d46c
# ── Local Auth ───────────────────────────────────────────────────────────
# Enables email/password login so you don't need a Google Cloud project.
# Set to false only if you are using Google OAuth as the sole sign-in method.
LOCAL_AUTH_ENABLED: "true"
# VITE_LOCAL_AUTH_ENABLED is a frontend build-time flag that was embedded in
# this image at build time (already set to true). It skips the marketing
# landing page and sends unauthenticated visitors straight to /login.
# If you build your own image, pass this at build time: --build-arg VITE_LOCAL_AUTH_ENABLED=true
VITE_LOCAL_AUTH_ENABLED: "true"
# ── Local Photo Storage (fake GCS) ───────────────────────────────────────
# Points Aurora Deck at the local fake-gcs-server for photo uploads.
# Comment these out if you remove the fake-gcs-server service above and
# want to use a real GCS bucket instead.
GCS_BUCKET: aurora-deck-local
GCS_ENDPOINT: http://fake-gcs-server:4443
# ── Local Network Photos (Samba / CIFS) ──────────────────────────────────
# Enables SMB/CIFS network shares as a screensaver photo source.
# Requires a Samba server on your local network (e.g. NAS, Windows share).
LOCAL_NETWORK_PHOTOS_ENABLED: "true"
# ── Optional: Weather ────────────────────────────────────────────────────
# Sign up at https://openweathermap.org/api to get a free API key.
# Leave blank to disable the weather widget.
# OPENWEATHERMAP_API_KEY: <your-key>
# ── Optional: Stock Ticker ───────────────────────────────────────────────
# Sign up at https://finnhub.io to get a free API key.
# Leave blank to disable the stock ticker widget.
# FINNHUB_API_KEY: <your-key>
# ── Optional: News Feed ──────────────────────────────────────────────────
# Sign up at https://newsapi.org to get a free API key.
# Leave blank to disable the news overlay.
# NEWS_API_KEY: <your-key>
# ── Optional: Google Integration (Calendar & Photos) ─────────────────────
# Required only if you want Google Sign-In, Google Calendar sync, or
# Google Photos as a screensaver source. See the Google Integration section
# on the self-hosting page for step-by-step setup instructions.
# GOOGLE_CLIENT_ID: <your-client-id>.apps.googleusercontent.com
# GOOGLE_CLIENT_SECRET: <your-client-secret>
# CALENDAR_TOKEN_KEY: <random-32-char-string> # encrypts stored calendar tokens; generate with: openssl rand -hex 16
# PHOTOS_TOKEN_KEY: <random-32-char-string> # encrypts stored photos tokens; generate with: openssl rand -hex 16
depends_on:
postgres:
condition: service_healthy
fake-gcs-server:
condition: service_healthy
restart: unless-stopped
volumes:
postgres-data:
gcs-data:Build Your Own Aurora Deck
Aurora Deck runs in any modern browser no special app required. Point a smartphone, tablet, laptop, or dedicated wall display at your self-hosted instance (or auroradeck.com) and you're up and running. The experience scales to whatever hardware you have available.
Full experience — gesture scroll, on-screen keyboard, and tap navigation. Works in both landscape and portrait. A screen 15″ or larger gives the best readability as a wall display.
Open Chrome or any browser, navigate to your Aurora Deck URL, and add it to your home screen. Works locally or via the internet — no app install needed.
Aurora Deck includes a Static Shareable Dashboard URL — perfect for devices with no touchscreen and no input devices. Any device with a web browser can display the dashboard without any interaction.
Setups I've personally tried
A dedicated smart display designed for the home. I run Aurora Deck on one at home full-time — it's a great fit. See the hearth-hacking guide on GitHub for setup details.
All three models work. The 3B+ is usable but sluggish — the Pi 4 or 5 gives a much smoother experience. The config files below are specific to this hardware; your setup may differ.
Raspberry Pi 3B+ / 4 / 5 Setup
This is my personal experiment — the scripts and config files are specific to the hardware listed below. If your display, touchscreen, or compositor differs, you'll likely need to adapt them.
Parts list
Minimum viable option. Works but expect some sluggishness — good if you already have one on hand.
Recommended. Noticeably smoother than the 3B+ — the 1GB model is sufficient for Aurora Deck.
Best performance. Overkill for Aurora Deck but very snappy. Worth it if you plan to use the display for anything else too.
32 GB is plenty for Raspberry Pi OS, Docker, and the Aurora Deck images with room to spare.
Driver-free MIPI DSI interface — plug straight into the Pi's display connector, no HDMI adapter needed.
Flash Raspberry Pi OS with Imager
Download and open Raspberry Pi Imager. Choose Raspberry Pi OS (64-bit) — the Desktop edition, which includes Chromium pre-installed.
Before flashing, click the OS Customisation button (pencil icon) to configure everything in one place:
- Set hostname to
aurora-deck - Set a username (e.g.
pi) and password - Enter your Wi-Fi SSID and password — or skip this if using Ethernet
- Under Services, enable SSH with password authentication
Flash to your SD card, then eject and insert it into the Pi.
Boot and SSH into the Pi
Connect the Pi to power and your network, then wait about 60 seconds for the first boot to complete. SSH in from another machine using the hostname you set:
Use the password you set in the Imager. If aurora-deck.local doesn't resolve, find the Pi's IP address in your router's DHCP client list and connect to that directly.
Configure Chromium, touch, and the on-screen keyboard
Raspberry Pi OS Bookworm uses the labwc Wayland compositor. The script below installs maliit-keyboard — a Wayland-native OSK that integrates with Chromium via the text-input protocol, so the keyboard appears automatically whenever you tap a text field. Run the script to configure everything in one shot, or follow the manual steps below.
The script prompts for your Aurora Deck URL, installs maliit-keyboard, disables autotouch, and writes the autostart. Reboot when done.
Or configure manually:
1. Disable autotouch
Raspberry Pi OS ships a script called /usr/bin/autotouch that runs at every login and overwrites rc.xml with mouseEmulation="yes", which converts touch drags into mouse events and breaks native scrolling. Disable it with a user-level XDG override:
mkdir -p ~/.config/autostart cat > ~/.config/autostart/autotouch.desktop << 'EOF' [Desktop Entry] Hidden=true EOF
2. Autostart — touch, window rules, keyboard, and Chromium
The autostart uses libinput to detect the exact touch device name and active display output on every boot, then writes rc.xml fresh with mouseEmulation="no" for native scroll and maximizedDecoration=none to hide the title bar. maliit-server provides the on-screen keyboard via the Wayland text-input protocol — it appears automatically when a text field is tapped. The --enable-wayland-ime flag wires Chromium into it:
cat > ~/.config/labwc/autostart << 'EOF'
TOUCH=$(libinput list-devices | tr '\n' @ | sed 's/@@/\n/g' | grep "Capabilities:.*touch" | sed 's/Device:[ \t]*//' | cut -d @ -f 1)
DISPLAY_OUT=$(wlr-randr | grep '^\S' | cut -d ' ' -f 1)
if [ -n "$TOUCH" ] && [ -n "$DISPLAY_OUT" ]; then
mkdir -p ~/.config/labwc
cat > ~/.config/labwc/rc.xml << RCEOF
<?xml version="1.0"?>
<openbox_config xmlns="http://openbox.org/3.4/rc">
<theme>
<maximizedDecoration>none</maximizedDecoration>
<keepBorder>no</keepBorder>
</theme>
<touch deviceName="$TOUCH"
mapToOutput="$DISPLAY_OUT"
mouseEmulation="no"/>
<windowRules>
<windowRule identifier="chromium"
matchType="identifier"
serverDecoration="yes">
<action name="Maximize"/>
</windowRule>
</windowRules>
</openbox_config>
RCEOF
labwc --reconfigure
fi
maliit-server &
chromium --app=https://your-aurora-deck-url \
--start-maximized \
--noerrdialogs --disable-infobars \
--disable-session-crashed-bubble --no-first-run \
--hide-scrollbars --touch-events=enabled \
--ozone-platform=wayland --password-store=basic \
--enable-wayland-ime &
EOFRun the Aurora Deck setup script
Download the setup script to the Pi, make it executable, and run it. It will install Docker, download the docker-compose file, generate your secret keys, and register Aurora Deck as a systemd service that starts on every boot.
The script pauses before rebooting so you can optionally open ~/aurora-deck/docker-compose.yaml and add Google credentials if you need Calendar or Photos integration.
Pi reboots into Aurora Deck
After the reboot, the desktop loads and Chromium launches automatically in full-screen app mode pointing to your Aurora Deck URL. Aurora Deck and its database start via the systemd service before the browser opens. The first boot may take 30–60 seconds while Docker pulls images.
Setup script
#!/usr/bin/env bash
# Aurora Deck — Raspberry Pi Setup Script
#
# Installs Docker, downloads the Aurora Deck docker-compose file, generates
# secret keys, and registers a systemd service so Aurora Deck starts
# automatically on every boot.
#
# Run this on your Raspberry Pi after completing the initial setup steps:
# bash setup-aurora-deck-pi.sh
set -euo pipefail
AURORA_DIR="$HOME/aurora-deck"
SERVICE_USER="${USER:-pi}"
COMPOSE_URL="https://auroradeck.com/aurora-deck-docker-compose.yaml"
# ── Helper ────────────────────────────────────────────────────────────────────
info() { echo "[aurora] $*"; }
warn() { echo "[aurora] WARNING: $*" >&2; }
abort() { echo "[aurora] ERROR: $*" >&2; exit 1; }
# ── Require root access ───────────────────────────────────────────────────────
if ! sudo -n true 2>/dev/null; then
info "This script needs sudo for Docker installation and systemd setup."
sudo -v
fi
# ── 1. Install Docker ─────────────────────────────────────────────────────────
if command -v docker &>/dev/null; then
info "Docker is already installed ($(docker --version))."
else
info "Installing Docker..."
curl -fsSL https://get.docker.com | sh
info "Adding $SERVICE_USER to the docker group..."
sudo usermod -aG docker "$SERVICE_USER"
fi
# ── 2. Create aurora-deck directory ──────────────────────────────────────────
info "Creating $AURORA_DIR..."
mkdir -p "$AURORA_DIR"
cd "$AURORA_DIR"
# ── 3. Download docker-compose file ──────────────────────────────────────────
if [ -f docker-compose.yaml ]; then
warn "docker-compose.yaml already exists — skipping download."
else
info "Downloading docker-compose.yaml..."
curl -fsSL "$COMPOSE_URL" -o docker-compose.yaml
fi
# ── 4. Generate secrets ───────────────────────────────────────────────────────
JWT_SECRET="$(openssl rand -hex 32)"
OAUTH_SECRET="$(openssl rand -hex 16)"
info "Generated secrets — updating docker-compose.yaml..."
# Replace the commented-out placeholders with real values
sed -i \
"s|# JWT_SECRET: <CHANGE_ME>|JWT_SECRET: $JWT_SECRET|" \
docker-compose.yaml
sed -i \
"s|# OAUTH_STATE_SECRET_KEY: <CHANGE_ME>|OAUTH_STATE_SECRET_KEY: $OAUTH_SECRET|" \
docker-compose.yaml
echo ""
echo " JWT_SECRET and OAUTH_STATE_SECRET_KEY have been set automatically."
echo " If you need Google Calendar or Photos, open the file and fill in:"
echo " GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, CALENDAR_TOKEN_KEY, PHOTOS_TOKEN_KEY"
echo ""
echo " File location: $AURORA_DIR/docker-compose.yaml"
echo ""
read -rp "Press Enter to continue (or Ctrl-C to edit the file first)..."
# ── 5. Register systemd service ───────────────────────────────────────────────
info "Registering aurora-deck systemd service..."
sudo tee /etc/systemd/system/aurora-deck.service > /dev/null << EOF
[Unit]
Description=Aurora Deck
Documentation=https://auroradeck.com/self-hosting
After=docker.service network-online.target
Requires=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=$AURORA_DIR
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
User=$SERVICE_USER
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# ── 6. Enable and start ───────────────────────────────────────────────────────
info "Enabling aurora-deck service..."
sudo systemctl daemon-reload
sudo systemctl enable aurora-deck
info "Pulling Docker images (this may take a few minutes)..."
docker compose -f "$AURORA_DIR/docker-compose.yaml" pull
info "Starting Aurora Deck..."
sudo systemctl start aurora-deck
echo ""
echo " Aurora Deck is running at http://localhost:8080"
echo " It will start automatically on every boot."
echo ""
echo " Rebooting in 10 seconds to apply Docker group membership..."
echo " (Press Ctrl-C to skip the reboot and reboot manually later.)"
echo ""
sleep 10
sudo reboot
License
Aurora Deck is distributed under the Polyform Shield License 1.0.0. Free to self-host for personal use. Commercial redistribution or building a competing service is prohibited without a commercial license.
© 2026 Aurora Deck. All Rights Reserved.