Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 104 additions & 18 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,110 +1,196 @@
COMPOSE_PROJECT_NAME=<NAME:-os2display>
COMPOSE_SERVER_DOMAIN=<DOMAIN:-os2display.local.itkdev.dk>
COMPOSE_FILES=<COMPOSE_FILES:-docker-compose.yml,docker-compose.mariadb.yml>
# =============================================================================
# Example .env file for os2display-docker-server
# Cantains environment variables that needs local configuration.
# Run task env:build to create .env and and prompt you for values that must be changed.
# You can also copy this file to .env and manually adjust the values as needed for your setup.
# Lines starting with # are comments.
# =============================================================================


# Domain name where the server will be accessible
COMPOSE_SERVER_DOMAIN=<DOMAIN:-os2display.mydomain.dk>

# Version of the OS2display Docker images (applies to all services)
# Find all version here: https://github.com/itk-dev/os2display-api-service/pkgs/container/os2display-api-service
COMPOSE_IMAGE_VERSION=<IMAGE_VERSION:-3.0.0>

# Which infrastructure services to include is controlled by the `COMPOSE_FILES` variable in `.env`.
# It is a comma-separated list of Docker Compose files to load.
COMPOSE_FILES=docker-compose.yml,docker-compose.mariadb.yml,docker-compose.traefik.yml

# Docker Compose project name (used for container prefixes)
COMPOSE_PROJECT_NAME=os2display

COMPOSE_IMAGE_VERSION=latest

###
# PHP
###
# Maximum time in seconds a PHP script is allowed to run before being terminated
PHP_MAX_EXECUTION_TIME=30
# Maximum amount of memory a PHP script can allocate
PHP_MEMORY_LIMIT=128M
# Maximum size of POST data that PHP will accept
PHP_POST_MAX_SIZE=140M
# Maximum size of an uploaded file
PHP_UPLOAD_MAX_FILESIZE=128M

###
# APPLICATION
####
###
# Application environment (prod, dev, test)
APP_ENV=prod
# Secret key used for encryption and security-related operations (MUST BE CHANGED)
APP_SECRET=<APP_SECRET:-CHANGE_ME>
# Comma-separated list of trusted proxy IPs for handling X-Forwarded headers
APP_TRUSTED_PROXIES=127.0.0.1,REMOTE_ADDR
APP_DATABASE_URL=<DATABASE_URL:-mysql://db:db@mariadb:3306/db?serverVersion=mariadb-10.5.13>
# Database connection string for MariaDB/MySQL
APP_DATABASE_URL=mysql://os2display:<MARIADB_PASSWORD:-CHANGE_ME>@mariadb:3306/os2display?serverVersion=mariadb-10.5.13
# Regular expression defining allowed origins for CORS requests
APP_CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'

# Default date format for API responses (ISO 8601 with milliseconds)
APP_DEFAULT_DATE_FORMAT='Y-m-d\TH:i:s.v\Z'
# Source for key vault configuration (ENVIRONMENT, FILE, etc.)
APP_KEY_VAULT_SOURCE=ENVIRONMENT
# JSON configuration for key vault when using ENVIRONMENT source
APP_KEY_VAULT_JSON="{}"
# Time interval for activation code expiration (ISO 8601 duration format, P2D = 2 days)
APP_ACTIVATION_CODE_EXPIRE_INTERVAL=P2D
# Enable tracking of screen information and statistics
APP_TRACK_SCREEN_INFO=false
# Interval in seconds between screen info updates
APP_TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS=300

# JWT
# Path to JWT private key file for signing tokens
APP_JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
# Path to JWT public key file for verifying tokens
APP_JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
# Passphrase for JWT private key (MUST BE CHANGED)
APP_JWT_PASSPHRASE=<JWT_PASSPHRASE:-CHANGE_ME>
# Time-to-live in seconds for JWT access tokens (3600 = 1 hour)
APP_JWT_TOKEN_TTL=3600
# Time-to-live in seconds for screen JWT tokens (1296000 = 15 days)
APP_JWT_SCREEN_TOKEN_TTL=1296000
# Time-to-live in seconds for JWT refresh tokens (2592000 = 30 days)
APP_JWT_REFRESH_TOKEN_TTL=2592000
# Time-to-live in seconds for screen JWT refresh tokens (2592000 = 30 days)
APP_JWT_SCREEN_REFRESH_TOKEN_TTL=2592000

# Internal OIDC provider
# URL to OIDC provider's metadata/discovery endpoint
APP_INTERNAL_OIDC_METADATA_URL=
# Client ID registered with the OIDC provider
APP_INTERNAL_OIDC_CLIENT_ID=
# Client secret for authentication with the OIDC provider
APP_INTERNAL_OIDC_CLIENT_SECRET=
# Redirect URI for OIDC callback after authentication
APP_INTERNAL_OIDC_REDIRECT_URI=
# Leeway time in seconds for token validation clock skew tolerance
APP_INTERNAL_OIDC_LEEWAY=30
# Name of the claim containing user's name
APP_INTERNAL_OIDC_CLAIM_NAME=navn
# Name of the claim containing user's email
APP_INTERNAL_OIDC_CLAIM_EMAIL=email
# Name of the claim containing user's group memberships
APP_INTERNAL_OIDC_CLAIM_GROUPS=groups

# External OIDC provider
# URL to external OIDC provider's metadata/discovery endpoint
APP_EXTERNAL_OIDC_METADATA_URL=
# Client ID registered with the external OIDC provider
APP_EXTERNAL_OIDC_CLIENT_ID=
# Client secret for authentication with the external OIDC provider
APP_EXTERNAL_OIDC_CLIENT_SECRET=
# Redirect URI for external OIDC callback after authentication
APP_EXTERNAL_OIDC_REDIRECT_URI=
# Leeway time in seconds for external token validation clock skew tolerance
APP_EXTERNAL_OIDC_LEEWAY=30
# Salt used for hashing external OIDC user identifiers
APP_EXTERNAL_OIDC_HASH_SALT=
# Name of the claim containing user's sign-in identifier
APP_EXTERNAL_OIDC_CLAIM_ID=signinname

# Redirect URI for CLI-based OIDC authentication flow
APP_OIDC_CLI_REDIRECT=


# Prefix for Redis cache keys to avoid collisions
APP_REDIS_CACHE_PREFIX=display
# Connection string for Redis cache server
APP_REDIS_CACHE_DSN=redis://redis:6379/0

# API endpoint for calendar location data
APP_CALENDAR_API_FEED_SOURCE_LOCATION_ENDPOINT=
# API endpoint for calendar resource data
APP_CALENDAR_API_FEED_SOURCE_RESOURCE_ENDPOINT=
# API endpoint for calendar event data
APP_CALENDAR_API_FEED_SOURCE_EVENT_ENDPOINT=
# JSON object for custom field mappings in calendar feeds
APP_CALENDAR_API_FEED_SOURCE_CUSTOM_MAPPINGS='{}'
# JSON object for modifying calendar event data
APP_CALENDAR_API_FEED_SOURCE_EVENT_MODIFIERS='{}'
# Date format used by the calendar API source
APP_CALENDAR_API_FEED_SOURCE_DATE_FORMAT=
# Timezone used by the calendar API source
APP_CALENDAR_API_FEED_SOURCE_DATE_TIMEZONE=
# Cache expiration time in seconds for calendar feed data
APP_CALENDAR_API_FEED_SOURCE_CACHE_EXPIRE_SECONDS=300

# Cache expiration time in seconds for event database API v2 responses
APP_EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS=300

###
# Admin configuration
# ADMIN CONFIGURATION
###
# API key for Rejseplanen (Danish journey planner) integration
APP_ADMIN_REJSEPLANEN_APIKEY=
# Enable display of screen online/offline status in admin interface
APP_ADMIN_SHOW_SCREEN_STATUS=false
# Enable touch button regions feature in admin interface
APP_ADMIN_TOUCH_BUTTON_REGIONS=false
# JSON array defining available login methods for admin interface
APP_ADMIN_LOGIN_METHODS='[{"type":"username-password","enabled":true,"provider":"username-password","label":""}]'
# Enable enhanced preview mode with additional features
APP_ADMIN_ENHANCED_PREVIEW=false


###
# Client configuration
# CLIENT CONFIGURATION
###
# Timeout in milliseconds for checking login status
APP_CLIENT_LOGIN_CHECK_TIMEOUT=20000
# Timeout in milliseconds before attempting to refresh authentication token (300000 = 5 minutes)
APP_CLIENT_REFRESH_TOKEN_TIMEOUT=300000
# Interval in milliseconds for checking release timestamp updates (600000 = 10 minutes)
APP_CLIENT_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT=600000
# Interval in milliseconds for running the content scheduling checks (60000 = 1 minute)
APP_CLIENT_SCHEDULING_INTERVAL=60000
# Interval in milliseconds for pulling new content from server (90000 = 1.5 minutes)
APP_CLIENT_PULL_STRATEGY_INTERVAL=90000
# JSON configuration for client color scheme with location coordinates
APP_CLIENT_COLOR_SCHEME='{"type":"library","lat":56.0,"lng":10.0}'
# Enable debug mode for client-side logging and diagnostics
APP_CLIENT_DEBUG=false


# Maximum upload size allowed by Nginx for PHP-FPM requests
NGINX_FPM_UPLOAD_MAX=140M
# Ensure corret IP's gets send to logs, should be the docker network (e.g. 172.16.0.0/16)
NGINX_SET_REAL_IP_FROM='0.0.0.0'


# Note: When updating the database connection details, ensure that the following MariaDB variables
# are also updated to match the connection string above. These variables are used by the Docker
# Compose setup to configure the built-in MariaDB service.
MARIADB_USER=db
MARIADB_PASSWORD=db
MARIADB_ROOT_PASSWORD=dbrootpassword
MARIADB_DATABASE=db
###
# DATABASE CONFIGURATION
###
# These variables are used by the Docker Compose setup to configure the built-in MariaDB service.
# Note: When updating the database connection details, ensure that the MariaDB variables
# are also updated to match the connection string above.

# MariaDB username for the application database
MARIADB_USER=os2display
# Password for the MariaDB application user (MUST BE CHANGED)
MARIADB_PASSWORD=<MARIADB_PASSWORD:-CHANGE_ME>
# Password for the MariaDB root user (MUST BE CHANGED)
MARIADB_ROOT_PASSWORD=<MARIADB_ROOT_PASSWORD:-CHANGE_ME>
# Name of the MariaDB database for the application
MARIADB_DATABASE=os2display
# Hostname of the MariaDB database server (Docker service name)
DB_HOST=mariadb
110 changes: 15 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,105 +36,35 @@ sudo usermod -aG docker deploy

## HTTPS Requirement

This project can only run in secure mode using HTTPS (port 443). You must provide a valid domain name and an SSL certificate.
This project can only run in secure mode using HTTPS (port 443).

1. Use a fully qualified domain name (FQDN) that resolves to your server's IP address.
2. Place the certificate file (`docker.crt`) and private key file (`docker.key`) in the `traefik/ssl` directory.
3. Set the domain name in `.env` via the `COMPOSE_SERVER_DOMAIN` variable.
You can configure an external reverse proxy til handle SSL termination or you can go with the default
installation options, that sets up Traefik as an integrated reverse proxy.

## Configuration

Before running `task install`, generate the configuration file using one of these methods:

**Option A** — Interactive prompt (recommended):

```bash
task _env:build
```

This reads `.env.example`, prompts for each placeholder value, and writes `.env`.

**Option B** — Manual copy and edit:

```bash
cp .env.example .env
```

Edit `.env` with your local settings. The key variables are described below.

### Domain, Name and Version
If you go with internal Traefik service, you must provide the SSL certificate file (`docker.crt`) and private file (`docker.key`) in the `traefik/ssl` directory.

| Variable | Description | Default |
|----------|-------------|---------|
| `COMPOSE_PROJECT_NAME` | Docker Compose project name (used for container prefixes) | `os2display` |
| `COMPOSE_SERVER_DOMAIN` | Domain name where the server will be accessible | `os2display.local.itkdev.dk` |
| `COMPOSE_IMAGE_VERSION` | Version of the os2display Docker images (applies to all services) | `latest` |

### Infrastructure Options

Which infrastructure services to include is controlled by the `COMPOSE_FILES` variable in `.env`. It is a comma-separated list of Docker Compose files to load.

| Value | Purpose |
|-------|---------|
| `docker-compose.yml` | **Required.** Core services (os2display API, nginx, redis) |
| `docker-compose.mariadb.yml` | Built-in MariaDB database. Omit if using an external database |
| `docker-compose.traefik.yml` | Built-in Traefik reverse proxy. Omit if using an external proxy |

Default: `docker-compose.yml,docker-compose.mariadb.yml`

### Database

| Variable | Description | Default |
|----------|-------------|---------|
| `APP_DATABASE_URL` | Doctrine database connection URL | `mysql://db:db@mariadb:3306/db?serverVersion=mariadb-10.5.13` |
| `MARIADB_USER` | MariaDB user (only when using built-in MariaDB) | `db` |
| `MARIADB_PASSWORD` | MariaDB password (only when using built-in MariaDB) | `db` |
| `MARIADB_ROOT_PASSWORD` | MariaDB root password (only when using built-in MariaDB) | `dbrootpassword` |
| `MARIADB_DATABASE` | MariaDB database name (only when using built-in MariaDB) | `db` |

### Secrets

| Variable | Description | Default |
|----------|-------------|---------|
| `APP_SECRET` | Symfony application secret | `CHANGE_ME` |
| `APP_JWT_PASSPHRASE` | JWT key pair passphrase | `CHANGE_ME` |
| `APP_ADMIN_LOGIN_METHODS` | JSON array configuring admin login methods (required) | `[{"type":"username-password","enabled":true,...}]` |

**NOTE:** Change both `APP_SECRET` and `APP_JWT_PASSPHRASE` to secure values before running in production.

### OIDC (OpenID Connect)

**Internal provider**:
## Configuration
You need to create a `.env` with your local settings. The installation package provides an example configuration file (`.env.example`) for you to copy.

| Variable | Description |
|----------|-------------|
| `APP_INTERNAL_OIDC_METADATA_URL` | OIDC metadata URL provided by the IdP |
| `APP_INTERNAL_OIDC_CLIENT_ID` | OIDC client ID |
| `APP_INTERNAL_OIDC_CLIENT_SECRET` | OIDC client secret |
| `APP_INTERNAL_OIDC_REDIRECT_URI` | OIDC redirect URI |
If you run `task install` with no `.env` present, the installer will interactively prompt you for the most important settings and create `.env` for you.

**External provider**:
See [.env.example](.env.example) for descriptions of all configurable variables.

| Variable | Description |
|----------|-------------|
| `APP_EXTERNAL_OIDC_METADATA_URL` | OIDC metadata URL provided by the IdP |
| `APP_EXTERNAL_OIDC_CLIENT_ID` | OIDC client ID |
| `APP_EXTERNAL_OIDC_CLIENT_SECRET` | OIDC client secret |
| `APP_EXTERNAL_OIDC_REDIRECT_URI` | OIDC redirect URI |

## Installation

1. Generate or edit `.env` with your chosen settings.
2. Place your SSL certificate files (`docker.crt` and `docker.key`) in the `traefik/ssl` directory.
3. Run the install task:
You install by executing the install task:

```bash
task install
```

The install process will:
With default installation options the install process will:
- Create the external `frontend` Docker network (if it doesn't exist)
- Pull Docker images
- Create and populate `.env` if it does not exists
- Check that the installer version matches the OS2Display version
- Check that the SSL certificate and key is present
- Pull Docker images (OS2display, MariaDB, Traefik)
- Start all containers
- Generate JWT key pair
- Run `app:update` (database migrations and other setup tasks)
Expand All @@ -150,19 +80,9 @@ After installation, the application is available at:
For a full list of tasks, run:

```bash
task --list
task
```

| Task | Description |
|------|-------------|
| `task install` | Install the project (pull images, start containers, generate JWT keys, add tenant/user) |
| `task purge` | Remove all containers. Use `-- --volumes` to also delete volumes, `-- --network` to remove the frontend network |
| `task db:backup` | Perform a database dump (only when using the built-in MariaDB). Saves to the `db_backups/` directory |
| `task compose -- <args>` | Run `docker compose` with the correct `-f` flags derived from `COMPOSE_FILES` in `.env` |
| `task console -- <cmd>` | Run a Symfony console command inside the os2display container |
| `task open:admin` | Open the admin interface in the default browser |
| `task open:client` | Open the client interface in the default browser |

### Common compose commands via task

```bash
Expand Down
Loading