Skip to content
Vitaly Sazanovich edited this page Nov 5, 2025 · 4 revisions

The installation consists of 3 components:

  1. application (written in Golang with embedded UI written in TypeScript Angular)
  2. database (PostgreSQL)
  3. converter (Java Spring application with MuseScore 3.6.2 used for conversion through the command line)

The recommended way is to use Docker. Below is an example docker compose file. You will need to adjust base urls and set STMP API keys if you are going to use a sendmail service. Currently Brevo and Amazon SES are supported.

You can also check out the source code, build it and start the components without Docker. This is what I do to develop the application and to test it locally.

Example docker-compose.yml:

  octavian-converter:
    image: "geniot/octavian-converter:latest"
    container_name: octavian-converter
    networks:
      - plumbum
    restart: unless-stopped
    cap_add:
      - SYS_ADMIN
    devices:
      - /dev/fuse
    security_opt:
      - 'apparmor:unconfined'

  octavian:
    image: "geniot/octavian:latest"
    container_name: octavian
    networks:
      - plumbum
    restart: unless-stopped
    environment:
      - DATABASE_URL=postgres://octavian:octavian@octavian-pg:5432/octavian
      - SERVER_HOST=0.0.0.0
      - SERVER_PORT=8333
      - BASE_API_URL=https://demo.octavian.app/api
      - BASE_UI_URL=https://demo.octavian.app
      - CONVERT_URL=https://converter.octavian.app/convert
      - SMTP_PROVIDER=none # possible values: brevo|ses|none
      - BREVO_API_KEY=
      - AWS_SES_USERNAME=
      - AWS_SES_PASSWORD=
    depends_on:
      - octavian-pg

  octavian-pg:
    image: postgres:14-alpine3.21
    container_name: octavian-pg
    networks:
      - plumbum
    restart: always
    environment:
      - POSTGRES_PASSWORD=octavian
      - POSTGRES_USER=octavian
      - POSTGRES_DB=octavian
      - PG_DATA=/var/lib/postgresql/data
    volumes:
      - octavian_pg_data:/var/lib/postgresql/data
      - octavian_pg_lib:/var/lib/postgresql
    ports:
      - "10004:5432"

volumes:
  octavian_pg_data:
    external: true
  octavian_pg_lib:
    external: true
  octavian_test_pg_data:
    external: true
  octavian_test_pg_lib:
    external: true

networks:
  plumbum:
    external: true
    name: plumbum

Example up.sh:

#!/bin/bash

#stops the execution of a script if a command or pipeline has an error
set -e -o pipefail

declare -a volumeNames=(
                    "octavian_pg_lib"
                    "octavian_pg_data"
                    )

declare -a targets=(
                    "/var/lib/postgresql"
                    "/var/lib/postgresql/data"
                    )

for i in "${!volumeNames[@]}"; do
  docker volume create "${volumeNames[i]}"
done

#restore volumes
for i in "${!volumeNames[@]}"; do
  if [ -f "$(pwd)"/"${volumeNames[i]}".tar.gz ]; then
     docker run --rm --mount source="${volumeNames[i]}",target="${targets[i]}" \
       -v "$(pwd)":/backup busybox tar -xzvf /backup/"${volumeNames[i]}".tar.gz -C /
  fi
done

docker-compose -f docker-compose.yml up -d

Example down.sh:

#!/bin/bash

#stops the execution of a script if a command or pipeline has an error
set -e -o pipefail

declare -a volumeNames=(
                    "octavian_pg_lib"
                    "octavian_pg_data"
                    )

declare -a targets=(
                    "/var/lib/postgresql"
                    "/var/lib/postgresql/data"
                    )

#stop and remove containers
docker-compose -f docker-compose.yml down

#backup volumes
for i in "${!volumeNames[@]}"; do
  docker run --rm --mount source="${volumeNames[i]}",target="${targets[i]}" \
    -v "$(pwd)":/backup busybox tar -czvf /backup/"${volumeNames[i]}".tar.gz "${targets[i]}"
done

#remove volumes
for i in "${!volumeNames[@]}"; do
  docker volume rm "${volumeNames[i]}"
done
Clone this wiki locally