Docker Deployment

Firmiana includes a multi-stage Dockerfile and docker-compose configuration for containerised deployment.

Quick Start

docker compose up -d

This builds the image and starts the server on port 8899.

Dockerfile

The Dockerfile uses a multi-stage build:

Stage 1 — Build: Maven 3.9 with GraalVM JDK 21 compiles the project.

Stage 2 — Runtime: GraalVM JDK 21 runtime runs the application as a non-root user.

# Stage 1: Build
FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests -B

# Stage 2: Runtime
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
RUN addgroup -S firmiana && adduser -S firmiana -G firmiana
COPY --from=build /app/target/matrix-client-0.0.1.jar app.jar
RUN mkdir -p /app/data && chown -R firmiana:firmiana /app
USER firmiana
VOLUME /app/data
EXPOSE 8899
ENTRYPOINT ["java", "-jar", "app.jar"]

Docker Compose

version: '3.8'
services:
  firmiana:
    build: .
    container_name: firmiana
    ports:
      - "8899:8899"
    volumes:
      - firmiana-data:/app/data
    environment:
      - JWT_SECRET=${JWT_SECRET:-...}
      - JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET:-...}
      - DB_URL=${DB_URL:-jdbc:h2:./data/matrix;DB_CLOSE_DELAY=-1}
      - DB_USERNAME=${DB_USERNAME:-sa}
      - DB_PASSWORD=${DB_PASSWORD:-}
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:8899/_matrix/client/versions"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  firmiana-data:

Environment Variables

VariableDefaultDescription
JWT_SECRET(dev default)Secret key for JWT signing
JWT_REFRESH_SECRET(dev default)Secret key for refresh token signing
DB_URLjdbc:h2:./data/matrix;DB_CLOSE_DELAY=-1JDBC connection URL
DB_USERNAMEsaDatabase username
DB_PASSWORD(empty)Database password

Operations

docker compose up -d        # Build and start
docker compose down          # Stop
docker compose logs -f       # Follow logs
docker compose ps            # Check status
docker compose restart       # Restart

Data Persistence

The H2 database file is stored in a Docker volume (firmiana-data) mounted at /app/data. This ensures data survives container restarts and rebuilds.

Health Check

The compose file includes a health check that pings /_matrix/client/versions. Check status with:

docker inspect --format='{{.State.Health.Status}}' firmiana