Flask Digital Signage (simple)
Lightweight digital signage platform using Flask + SQLite.
Features
- Central admin can manage companies, users, displays.
- Admin can impersonate any company user (no password).
- Company users can:
- Create playlists
- Add slides (image/video/webpage)
- Assign playlists to displays
- Displays are public 16:9 player webpages suitable for kiosk browsers.
Quickstart (Windows)
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
set FLASK_APP=app
flask init-db --admin-email beheer@alphen.cloud --admin-pass admin
flask run --debug
If Flask can't discover the app automatically, use:
set FLASK_APP=app:create_app
flask run --debug
Notes
- SQLite DB is stored at
instance/signage.sqlite. - Uploaded files go to
app/static/uploads/.
Display player
Open:
http://<host>/display/<token>for live playback (counts towards the concurrent display limit)http://<host>/display/<token>?preview=1for preview (does not count towards the concurrent display limit)
Live updates
The player keeps itself up-to-date automatically:
- It listens to
GET /api/display/<token>/events(Server-Sent Events) and reloads the playlist immediately when it changes. - It also does a fallback playlist refresh every 5 minutes for networks/proxies that block SSE.
SMTP / Forgot password
This project includes a simple forgot password flow. SMTP configuration is read from environment variables.
You can also configure SMTP settings from the UI: Admin → Settings. Environment variables still take precedence over the database settings.
Public domain for emails
If your app runs behind a reverse proxy (or the internal hostname differs from the public hostname),
set Admin → Settings → Public domain to e.g. signage.example.com so links in password reset
emails point to the correct address.
Recommended: put these in a local .env file in the repo root. Flask (via python-dotenv) will auto-load it on startup. .env is already gitignored.
You can start from .env.example:
copy .env.example .env
Example
REM Option A: set env vars in the same terminal where you run `flask run`
set SMTP_HOST=smtp.strato.de
set SMTP_PORT=587
set SMTP_USERNAME=beheer@alphen.cloud
set SMTP_PASSWORD=***
set SMTP_FROM=beheer@alphen.cloud
set SMTP_STARTTLS=1
set SMTP_DEBUG=1
REM Option B: put the same keys/values in a .env file instead
Security note: do not commit SMTP passwords to the repo. Prefer secrets management and rotate leaked credentials.
Note on the "From" address: some SMTP providers enforce that the authenticated mailbox
(SMTP_USERNAME) is used as the actual sender (envelope-from), even if a different
SMTP_FROM is provided. In that case the app sets a Reply-To header so replies still
go to SMTP_FROM, but the provider may still show the username address as the sender.
Troubleshooting mail delivery
If the reset email is not received:
- Set
SMTP_DEBUG=1and request a reset again. - Watch the Flask console output for SMTP responses / errors.
- Verify:
SMTP_USERNAMEandSMTP_FROMare allowed by your provider.- You are using STARTTLS (port 587).
- The recipient mailbox isn’t filtering it (spam/quarantine).