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