Pillarbox Demo Backend is a Kotlin-based service designed to act as the lightweight backbone for media management within the Pillarbox ecosystem.
Prerequisites and Requirements
- JDK 24 or higher
- Node.js 24 or higher
- Docker & Docker Compose: Required for running the local environment. On Linux, follow these
post-installation steps to allow your user to run Docker commands without
relying on
sudo.
This project includes an .nvmrc file that specifies the recommended Node.js version.
If you use nvm, you can automatically switch to the correct Node version by running: nvm use
If the required version is not installed yet, run: nvm install. This will install the Node.js
version defined in .nvmrc and switch your shell to use it.
For more details on installing and using the .nvmrc file see the official
.nvmrc documentation.
Use the convenience script to orchestrate the local environment. This script starts the Docker containers, launches the background compiler for hot-reloading, and runs the Ktor application.
# Standard start (cleans up Docker on exit)
./start
# Keep Docker containers running after exiting the app
./start --keepIf you prefer to manage the infrastructure and application lifecycles independently, you can execute the steps separately:
| Step | Action | Command |
|---|---|---|
| 1 | Start Infrastructure | docker compose up -d --wait |
| 2 | Start Application | ./gradlew run |
| 3 | Cleanup | docker compose down |
To run the full stack as Docker containers only (e.g. for integration testing or CI), use the
full profile, which additionally starts the backend service:
export NODE_VERSION=$(cat .nvmrc)
docker compose --profile full up --build --waitNote
By default, docker compose up only starts the infrastructure services (PostgreSQL and
Keycloak). The full profile is intended for scenarios where you want to validate the
containerized application without running it locally via Gradle.
The application supports externalized configuration via a .env file. This allows you to override database credentials or point to remote environments without modifying the source code:
- Initialize the env file:
cp .env.example .env - Customize: Edit
.envto match your local or remote setup.
Tip
Check the .env.example for all the supported variables.
Use these commands for standard development lifecycle tasks.
| Goal | Command |
|---|---|
| Build | ./gradlew build |
| Run Tests | ./gradlew test |
| Linting | ./gradlew ktlintCheck detekt |
| Format Code | ./gradlew ktlintFormat |
To get started with the console and API, please refer to the Development & API Usage Guide.
This project is a Kotlin-based application built with Ktor and Koin, using Exposed and Flyway to manage data persistence in a PostgreSQL database.
The service bridges the gap between media management and player consumption through versioned endpoints:
- Management API: A CRUD interface to publish and organize media metadata using a rich domain model.
- Player API: A specialized endpoint that serves media in a format optimized for Pillarbox players. This API implements selection logic for streams and DRM based on client preferences.
All player-facing responses are strictly validated against the Pillarbox Standard Metadata Schema.
The following diagram illustrates how the Management and Player APIs interact with the persistence layer:
sequenceDiagram
participant Admin as Management Client
participant App as Pillarbox Backend
participant DB as Database
participant Player as Pillarbox Player
Note over Admin, DB: Media Publication
Admin ->> App: Publish Media
App ->> DB: Persist Domain Model
DB -->> App: Success
App -->> Admin: Created
Note over Player, DB: Media Consumption
Player ->> App: Request Playback
App ->> DB: Fetch Domain Model
DB -->> App: Data retrieved
App ->> App: Adapt to Player Format
App -->> Player: Return Optimized Media
This project automates its own development workflow using GitHub Actions:
-
Quality Check for Pull Requests Triggered on every pull request to the
mainbranch, this workflow ensures the code passes static analysis and unit tests. -
Release Workflow When changes are pushed to
main, this workflow handles versioning and releases withsemantic-release. It automatically bumps the version, generates release notes, creates a tag, and publishes a Docker image to Amazon ECR
Contributions are welcome! If you'd like to contribute, please follow the project's code style and linting rules. Here are some commands to help you get started:
Check your code style:
./gradlew ktlintCheckYou can try an automatically apply the style by running:
./gradlew ktlintFormatDetect potential issues:
./gradlew detektAll commits must follow the Conventional Commits format to ensure compatibility with our automated release system. A pre-commit hook is available to validate commit messages.
You can set up hook to automate these checks before commiting and pushing your changes, to do so update the Git hooks path:
git config core.hooksPath .githooks/Refer to our Contribution Guide for more detailed information.
Contributions are welcome! Please follow the project's code style and linting rules before submitting.
| Tool | Check | Fix |
|---|---|---|
| ktlint | ./gradlew ktlintCheck |
./gradlew ktlintFormat |
| detekt | ./gradlew detekt |
— |
| eslint | npm run eslint |
npm run eslint:fix |
| stylelint | npm run stylelint |
npm run stylelint:fix |
All commits must follow the Conventional Commits format to ensure compatibility with our automated release system.
To automate these checks via a pre-commit hook, update the Git hooks path:
git config core.hooksPath .githooks/Refer to our Contribution Guide for more detailed information.
This project is licensed under the MIT License.
