Custom Deployment

This page describes how to deploy MOSAIC-Server using Docker Compose.

MOSAIC-Server consists of three services:

Service Image Port Role
mosaic-be mosaic-be:latest 9001 Spring WebFlux backend
mosaic-fe mosaic-fe:latest 8080 React frontend (Nginx)
mosaic-db postgres:17 internal PostgreSQL database

Prerequisites

  • Docker Engine 24+
  • Docker Compose v2

1. Clone the Repository

git clone https://github.com/ACSL-MOSAIC/MOSAIC-Server.git
cd MOSAIC-Server

2. Build the Images

Backend (Spring WebFlux — multi-stage build with Azul Zulu JDK 21):

docker build -t mosaic-be:latest ./backend

Frontend (React → Nginx):

docker build -t mosaic-fe:latest ./frontend

3. Configure Environment Variables

cp deploy/prod/.env-template deploy/prod/.env

Edit deploy/prod/.env:

POSTGRES_USER=mosaic
POSTGRES_PASSWORD=your-strong-password
POSTGRES_DB=mosaic
MOSAIC_SECURITY_ENCRYPTION_KEY=your-base64-encoded-aes256-key
Variable Description
POSTGRES_USER PostgreSQL username
POSTGRES_PASSWORD PostgreSQL password
POSTGRES_DB Database name (default: mosaic)
MOSAIC_SECURITY_ENCRYPTION_KEY AES-256 key for encrypting robot auth tokens (Base64-encoded)

Generating the Encryption Key

A utility test AESKeyGeneratorTest is provided in the repository. Run it from your IDE or via CLI to generate the key:

# From the repository root
cd backend
./gradlew :test --tests "com.gistacsl.mosaic.cryptor.AESKeyGeneratorTest.generateAESKey" --info

The generated key is printed to the console:

================================================================================
Generated AES-256 Encryption Key:
================================================================================
<your-base64-encoded-key>
================================================================================

Copy the printed key and set it as MOSAIC_SECURITY_ENCRYPTION_KEY in your .env file.


4. Run

docker compose -f deploy/prod/docker-compose.yaml up -d

Database schema migrations (Flyway) run automatically on backend startup. No manual migration step is required.

Verify

docker compose -f deploy/prod/docker-compose.yaml ps
NAME         STATUS    PORTS
mosaic-be    running   0.0.0.0:9001->9001/tcp
mosaic-fe    running   0.0.0.0:8080->80/tcp
mosaic-db    running

5. Nginx Reverse Proxy (Production)

In production, place an Nginx reverse proxy in front to handle TLS and route traffic:

  • api-mosaic.your-domain.com → backend (localhost:9001)
  • mosaic.your-domain.com → frontend (localhost:8080)

WebSocket routes (/ws/*) must forward the Upgrade header:

location /ws {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 86400;
    proxy_send_timeout 86400;
}

See deploy/prod/nginx.conf for the full reference configuration.


Useful Commands

# Follow logs
docker compose -f deploy/prod/docker-compose.yaml logs -f

# Restart a specific service
docker compose -f deploy/prod/docker-compose.yaml restart mosaic-be

# Stop all services
docker compose -f deploy/prod/docker-compose.yaml down

# Stop and wipe the database volume
docker compose -f deploy/prod/docker-compose.yaml down -v

This site uses Just the Docs, a documentation theme for Jekyll.