Docker Compose Setup
This folder contains the Docker Compose definitions for Pulse Signage, including the public stack and the remote player stack.
Files
- docker-compose.yml - full public stack with web, player, player bridge, and MySQL.
- .env.example - sample environment values for the public stack.
- docker-compose.remote.yml - remote player-only stack using a published player image.
- .env.remote.example - sample environment values for the remote stack.
Stack Overview
Public stack
The main compose stack is the most complete setup. It runs:
web- the dashboard and admin app.player- the local screen player.player-bridge- the bridge service that proxies dashboard commands and player communication.mysql- the database used by the web, player, and bridge services.
This is the stack to use when you want the full app running on one machine.
Remote player
The remote stack runs only the player service.
Use it when the player is installed on a remote device and connects back through the player bridge instead of running the full app separately.
Services
web
The dashboard and admin application.
Responsibilities:
- serves the web UI on port
8080 - reads and writes application data from MySQL
- forwards player actions through the configured bridge base URL
- renders connected clients, dashboard pages, and admin workflows
Key configuration:
DB_HOST,DB_PORT,DB_NAME,DB_USER,DB_PASSWORDPULSE_SIGNAGE_SHARED_SECRETDEFAULT_ADMIN_USERNAMEDEFAULT_ADMIN_NAMEDEFAULT_ADMIN_PASSWORD
player
The screen runtime that renders playlists and receives commands.
Responsibilities:
- serves the player UI on port
8081 - connects to MySQL in the public stack
- connects to the bridge in remote mode through
BRIDGE_PUBLIC_URL - registers live connections and accepts control commands
Key configuration:
PLAYER_INTERNAL_URLPLAYER_IDENTIFIERBRIDGE_PUBLIC_URLin remote modePULSE_SIGNAGE_SHARED_SECRET- database settings in local mode
player-bridge
The bridge layer that connects the dashboard to the player network.
Responsibilities:
- serves the bridge API on port
8090 - forwards authenticated dashboard commands to registered players
- exposes screen connection snapshots and player registration data
- proxies command traffic between the web app and remote players
Key configuration:
PULSE_SIGNAGE_SHARED_SECRETWEB_INTERNAL_URLfor the bridge when it should call the web app directly instead of inferring from request headersDB_HOST,DB_PORT,DB_NAME,DB_USER,DB_PASSWORD
mysql
The MySQL 8.4 database used by the public stack.
Responsibilities:
- stores application data, screen state, onboarding state, and registry records
- provides persistent storage through
mysql_data
Key configuration:
MYSQL_DATABASEMYSQL_USERMYSQL_PASSWORDMYSQL_ROOT_PASSWORD
Environment Files
.env.example
Use this file as a starting point for the public compose stack.
Important values:
PULSE_SIGNAGE_WEB_IMAGE- image to run for the web app and bridge services, typically.../pulse-signage-web:latestPULSE_SIGNAGE_PLAYER_IMAGE- image to run for the player services, typically.../pulse-signage-player:latestPULSE_SIGNAGE_SHARED_SECRET- long random secret shared by the web, player, and bridge services for authenticated requestsDB_*- MySQL credentials and database name for the stackMYSQL_ROOT_PASSWORD- root password for the local MySQL containerWEB_PUBLIC_URL- public URL of the web applicationWEB_INTERNAL_URL- internal URL the bridge uses to call the web app directlyPLAYER_IDENTIFIER- unique local player identifierPLAYER_INTERNAL_URL- internal URL the web app uses for local player callsBRIDGE_INTERNAL_URL- bridge URL the web app uses for player snapshot and command forwardingDEFAULT_ADMIN_*- bootstrap admin account values
.env.remote.example
Use this file on a remote player device.
Important values:
PULSE_SIGNAGE_PLAYER_IMAGE- image to run on the device, typically.../pulse-signage-player:latestPULSE_SIGNAGE_SHARED_SECRET- must match the public stack and should be the same long random value used everywhere in the deploymentPLAYER_IDENTIFIER- unique remote player identifierBRIDGE_PUBLIC_URL- bridge URL the player connects back toPLAYER_AGENT_RECONNECT_DELAY_MS- reconnect delay for the player agent
PULSE_SIGNAGE_SHARED_SECRET
This secret is the shared signing key for requests between the services. Use a single value for every service that needs to talk to the same stack, including the web app, player, bridge, and any remote player that connects back to that bridge.
Recommended shape:
- at least 32 random bytes
- ideally 64 hex characters, or another equally long cryptographically random string
- not a password, phrase, or anything human-readable
If you want a quick local value, generate one with a password manager or a command such as openssl rand -hex 32.
Leave it blank only if you intentionally want to run without request signing in a throwaway local setup.
Main Configuration Variables
| Variable | Used By | Purpose |
|---|---|---|
PULSE_SIGNAGE_WEB_IMAGE |
web, bridge | Docker image to run for the web app and bridge services. |
PULSE_SIGNAGE_PLAYER_IMAGE |
player, remote player | Docker image to run for the player services. |
PULSE_SIGNAGE_SHARED_SECRET |
web, player, bridge, remote player | Shared secret for authenticated requests between services. |
DB_HOST |
web, player, bridge | Database host name. |
DB_PORT |
web, player, bridge | Database port. |
DB_NAME |
web, player, bridge, mysql | Database name. |
DB_USER |
web, player, bridge, mysql | Database user. |
DB_PASSWORD |
web, player, bridge, mysql | Database password. |
MYSQL_ROOT_PASSWORD |
mysql | Root password for the local MySQL container. |
MYSQL_DATABASE |
mysql | Database name used by the local MySQL container. |
MYSQL_USER |
mysql | Database user used by the local MySQL container. |
MYSQL_PASSWORD |
mysql | Database password used by the local MySQL container. |
WEB_PUBLIC_URL |
web, player-bridge | Public URL of the web application. |
WEB_INTERNAL_URL |
player-bridge | Internal web URL used by the bridge to call the dashboard app directly. |
PLAYER_IDENTIFIER |
player | Stable player identifier. |
PLAYER_INTERNAL_URL |
web, player | Internal player URL used by the dashboard and player runtime. |
BRIDGE_INTERNAL_URL |
web | Bridge URL used by the web app for player snapshot and command forwarding. |
DEFAULT_ADMIN_USERNAME |
web | Bootstrap admin username. |
DEFAULT_ADMIN_NAME |
web | Bootstrap admin display name. |
DEFAULT_ADMIN_PASSWORD |
web | Bootstrap admin password. |
BRIDGE_PUBLIC_URL |
remote player | URL of the bridge service. |
PLAYER_AGENT_RECONNECT_DELAY_MS |
remote player | Delay before reconnecting to the bridge. |
Ports
Public stack ports:
8080- web dashboard8081- player8090- player bridge3306- MySQL
Remote stack ports:
8081- player only
Volumes
Public stack
mysql_data- persistent MySQL data.pulse-signage- shared media and cache volume for the app services.
Remote stack
pulse-signage- shared media and cache volume for the remote player.
Networks
Each compose file creates its own named network:
pulse-signagefor the public stackpulse-signage-remotefor the remote player deployment.
Notes
- The public stack expects the app services and MySQL to share the same
PULSE_SIGNAGE_SHARED_SECRET. - A remote player must use the same
PULSE_SIGNAGE_SHARED_SECRETas the bridge it connects to. - The bridge service is the dashboard-facing command path for connected remote players.
- The remote player should point
BRIDGE_PUBLIC_URLat the bridge, not at the public web endpoint. - The
PULSE_SIGNAGE_WEB_IMAGEandPULSE_SIGNAGE_PLAYER_IMAGEtags default to the publishedpulse-signage-webandpulse-signage-playerrepositories withlatesttags, but they can be overridden for custom releases.
Recommended Setup
- Copy
.env.exampleto a local.envfile for the public stack. - Copy
.env.remote.exampleto a device-specific.envfile for the remote player. - Make sure
PULSE_SIGNAGE_SHARED_SECRETmatches everywhere. - Start the public stack first, then start the remote player after the bridge is reachable.
- Verify that the player appears in Connected clients before testing screen commands.