277 lines
10 KiB
Markdown
277 lines
10 KiB
Markdown
# Docker Compose Setup
|
|
|
|
This folder contains the Docker Compose definitions for Pulse Signage, including the public stack and the remote player stack.
|
|
|
|
## Contents
|
|
|
|
- [Files](#files)
|
|
- [Stack Overview](#stack-overview)
|
|
- [Services](#services)
|
|
- [Environment Files](#environment-files)
|
|
- [Public Stack Setup](#public-stack-setup)
|
|
- [Remote Player Setup](#remote-player-setup)
|
|
- [Shared Secret](#shared-secret)
|
|
- [Ports](#ports)
|
|
- [Volumes](#volumes)
|
|
- [Networks](#networks)
|
|
- [Notes](#notes)
|
|
- [Deployment Checklist](#deployment-checklist)
|
|
|
|
## Files
|
|
|
|
- [docker-compose.yml](docker-compose.yml) - full public stack with web, player, player bridge, and MySQL.
|
|
- [.env.example](.env.example) - sample environment values for the public stack.
|
|
- [docker-compose.remote.yml](docker-compose.remote.yml) - remote player-only stack using a published player image.
|
|
- [.env.remote.example](.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_PASSWORD`
|
|
- `PULSE_SIGNAGE_SHARED_SECRET`
|
|
- `WEB_PUBLIC_URL`
|
|
- `BRIDGE_INTERNAL_URL`
|
|
- `DEFAULT_ADMIN_USERNAME`
|
|
- `DEFAULT_ADMIN_NAME`
|
|
- `DEFAULT_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_PUBLIC_URL`
|
|
- `PLAYER_INTERNAL_URL`
|
|
- `PLAYER_IDENTIFIER`
|
|
- `BRIDGE_PUBLIC_URL` in remote mode
|
|
- `PULSE_SIGNAGE_SHARED_SECRET`
|
|
- `WEB_PUBLIC_URL`
|
|
- `DB_HOST`, `DB_PORT`, `DB_NAME`, `DB_USER`, `DB_PASSWORD` 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_SECRET`
|
|
- `WEB_INTERNAL_URL` for the bridge when it should call the web app directly instead of inferring from request headers
|
|
- `DB_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:
|
|
|
|
- `DB_NAME`
|
|
- `DB_USER`
|
|
- `DB_PASSWORD`
|
|
- `MYSQL_ROOT_PASSWORD`
|
|
|
|
## Environment Files
|
|
|
|
| File | Used by | How it is loaded |
|
|
| --- | --- | --- |
|
|
| `.env.example` | Public stack | Copy to `.env`; Compose loads it automatically, or pass it with `--env-file`. |
|
|
| `.env.remote.example` | Published remote player | Copy to `.env.remote`; pass it with `--env-file .env.remote`. |
|
|
|
|
The example files are templates. Copy the appropriate file, review its defaults, and replace secrets or placeholder URLs before deploying.
|
|
|
|
### Public stack: `.env.example`
|
|
|
|
Use this file as a starting point for the public Compose stack.
|
|
|
|
Important values:
|
|
|
|
| Variable | Purpose | Default |
|
|
| --- | --- | --- |
|
|
| `PULSE_SIGNAGE_WEB_IMAGE` | Image for the web app and bridge services. | `git.lzstealth.com/lzstealth/pulse-signage-web:latest` |
|
|
| `PULSE_SIGNAGE_PLAYER_IMAGE` | Image for the player services. | `git.lzstealth.com/lzstealth/pulse-signage-player:latest` |
|
|
| `PULSE_SIGNAGE_SHARED_SECRET` | Shared request-signing secret. | Blank; set this for a secured deployment. |
|
|
| `DB_HOST` | MySQL host name. | `mysql` |
|
|
| `DB_PORT` | MySQL port. | `3306` |
|
|
| `DB_NAME` | MySQL database name. | `pulse-signage` |
|
|
| `DB_USER` | MySQL user name. | `pulse-signage` |
|
|
| `DB_PASSWORD` | MySQL user password. | `signage_password` |
|
|
| `MYSQL_ROOT_PASSWORD` | Local MySQL root password. | `root_password` |
|
|
| `WEB_PUBLIC_URL` | Public URL of the web application. | `http://localhost:8080` |
|
|
| `WEB_INTERNAL_URL` | Internal URL the bridge uses to call the web app. | `http://web:8080` |
|
|
| `PLAYER_IDENTIFIER` | Unique local player identifier. | `player-local` |
|
|
| `PLAYER_PUBLIC_URL` | URL used by the kiosk launcher and direct player access. | `http://localhost:8081` |
|
|
| `PLAYER_INTERNAL_URL` | Internal URL used for local player calls. | `http://player:8081` |
|
|
| `BRIDGE_INTERNAL_URL` | Bridge URL used for snapshots and command forwarding. | `http://player-bridge:8090` |
|
|
| `DEFAULT_ADMIN_USERNAME` | Bootstrap admin username. | `admin` |
|
|
| `DEFAULT_ADMIN_NAME` | Bootstrap admin display name. | `Admin` |
|
|
| `DEFAULT_ADMIN_PASSWORD` | Bootstrap admin password. | `password123!` |
|
|
|
|
### Remote player: `.env.remote.example`
|
|
|
|
Use this file as the starting point for a remote player device. The production remote Compose file reads values from Compose's environment, so pass the copied file explicitly with `--env-file`.
|
|
|
|
Important values:
|
|
|
|
| Variable | Purpose | Default |
|
|
| --- | --- | --- |
|
|
| `PULSE_SIGNAGE_PLAYER_IMAGE` | Image to run on the device. | `git.lzstealth.com/lzstealth/pulse-signage-player:latest` |
|
|
| `PULSE_SIGNAGE_SHARED_SECRET` | Shared request-signing secret; must match the public stack. | Blank; set it to the public stack's secret. |
|
|
| `PLAYER_IDENTIFIER` | Unique remote player identifier. | `player-remote` |
|
|
| `PLAYER_PUBLIC_URL` | Optional URL for direct player access. | `http://remote-player.example.com:8081` |
|
|
| `BRIDGE_PUBLIC_URL` | Bridge URL the player connects back to. | `http://player-bridge.example.com:8090`; replace this placeholder. |
|
|
| `PLAYER_AGENT_RECONNECT_DELAY_MS` | Delay before reconnecting to the bridge. | `5000` |
|
|
|
|
## Public Stack Setup
|
|
|
|
Install Docker Engine with Docker Compose, then run the public stack from this directory:
|
|
|
|
```sh
|
|
cp .env.example .env
|
|
docker compose -f docker-compose.yml up -d
|
|
```
|
|
|
|
The command pulls the published images, creates the network and volumes, and starts the web app, local player, player bridge, and MySQL services. Check the installation with:
|
|
|
|
```sh
|
|
docker compose -f docker-compose.yml ps
|
|
docker compose -f docker-compose.yml logs -f web
|
|
```
|
|
|
|
## Remote Player Setup
|
|
|
|
A remote deployment has two parts:
|
|
|
|
- the public stack runs the web app, database, and player bridge
|
|
- each remote device runs only the player and connects back to the bridge
|
|
|
|
The remote player does not need database credentials. Set `BRIDGE_PUBLIC_URL` to the externally reachable bridge URL, including its port when required. It must point to the bridge service, not the web dashboard URL. The bridge must be reachable from the device and allow both HTTP requests and the player websocket connection at `/ws/players`.
|
|
|
|
### Published remote player
|
|
|
|
On the remote device:
|
|
|
|
```sh
|
|
cp .env.remote.example .env.remote
|
|
docker compose --env-file .env.remote -f docker-compose.remote.yml up -d
|
|
```
|
|
|
|
The published remote stack exposes the player on host port `8081`. Check its connection and startup output with:
|
|
|
|
```sh
|
|
docker compose --env-file .env.remote -f docker-compose.remote.yml ps
|
|
docker compose --env-file .env.remote -f docker-compose.remote.yml logs -f player
|
|
```
|
|
|
|
Start the public stack and confirm that its bridge is reachable before starting the remote player. Once the player connects, it should appear in the dashboard's Connected clients view. If it does not, verify the bridge URL, shared secret, firewall or reverse-proxy websocket support, and the player logs.
|
|
|
|
## 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.
|
|
|
|
## Ports
|
|
|
|
Public stack ports:
|
|
|
|
- `8080` - web dashboard
|
|
- `8081` - player
|
|
- `8090` - player bridge
|
|
- `3306` - 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-signage` for the public stack
|
|
- `pulse-signage-remote` for the remote player deployment.
|
|
|
|
## Notes
|
|
|
|
- The public stack expects the web, player, and bridge services to share the same `PULSE_SIGNAGE_SHARED_SECRET`.
|
|
- A remote player must use the same `PULSE_SIGNAGE_SHARED_SECRET` as 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_URL` at the bridge, not at the public web endpoint.
|
|
- The `PULSE_SIGNAGE_WEB_IMAGE` and `PULSE_SIGNAGE_PLAYER_IMAGE` tags default to the published `pulse-signage-web` and `pulse-signage-player` repositories with `latest` tags, but they can be overridden for custom releases.
|
|
|
|
## Deployment Checklist
|
|
|
|
1. Follow [Public Stack Setup](#public-stack-setup) to start the public stack with Docker Compose.
|
|
2. Set the same `PULSE_SIGNAGE_SHARED_SECRET` in the public and remote environments.
|
|
3. Set `BRIDGE_PUBLIC_URL` to the externally reachable bridge URL.
|
|
4. Start the published remote player with the workflow above.
|
|
5. Verify that the player appears in Connected clients before testing screen commands.
|