Skip to main content

Local setup

A walk-through for setting up a complete local development environment.

System requirements

ToolVersionWhy
Java21+Service runtime.
Maven3.9+Wrapper (./mvnw) is checked in but a system Maven works too.
Dockerany recentPostgres via docker compose.
ffmpeg4.4+Audio preprocessing; pipeline degrades gracefully if missing.
jqanyComfortable JSON exploration from curl.

Clone

git clone https://github.com/FluxonLabs/scryon-backend.git
cd scryon-backend

Profiles

Scryon ships four Spring profiles for different scenarios:

ProfileActivated byDBStorageTranscriptionSwaggerLog level
local@ActiveProfiles("local") in testsH2 in-memoryLocal FSSynconDEBUG
devSPRING_PROFILES_ACTIVE=devPostgres (docker-compose)Local FSSynconDEBUG
stagingRailway staging env varRailway PostgresS3/R2Async webhookonDEBUG
prodRailway prod env varRailway PostgresS3/R2Async webhookoffINFO

For local device testing, use the dev profile. It connects to Postgres via docker-compose and runs transcription synchronously — no public URL or HMAC secret needed.

The local profile (H2 + no Flyway) is for unit and integration tests only.

Running locally (dev profile)

Quickest way — dev.sh

./dev.sh # without pyannote (Lemonfox built-in diarization)
./dev.sh --pyannote # with pyannote (precise speaker separation, requires PYANNOTE_API_KEY)

The script handles everything: starts Postgres if not running, prints the Mac's Wi-Fi IP for local.properties, and launches the backend with SPRING_PROFILES_ACTIVE=dev.

One-time setup — create .env.local (gitignored, never commit):

# scryon-backend/.env.local
export LEMONFOX_API_KEY=your-key
export LLM_API_KEY=your-key
# export PYANNOTE_API_KEY=your-key # only needed for --pyannote

dev.sh sources this automatically every time.

Diarization modes

CommandDiarizationWhen to use
./dev.shLemonfox built-inQuick testing, no extra key needed
./dev.sh --pyannotepyannote.aiTesting speaker separation accuracy

Manual run (if you prefer explicit commands)

# Start Postgres
docker compose up postgres -d

# Start backend with dev profile
LEMONFOX_API_KEY=<key> LLM_API_KEY=<key> SPRING_PROFILES_ACTIVE=dev mvn spring-boot:run

# With pyannote
LEMONFOX_API_KEY=<key> LLM_API_KEY=<key> PYANNOTE_API_KEY=<key> PYANNOTE_ENABLED=true \
SPRING_PROFILES_ACTIVE=dev mvn spring-boot:run

On first start Flyway runs all migrations and creates all tables. See Database migrations.

Provider credentials

ProviderRequired forEnv var
LemonfoxTranscriptionLEMONFOX_API_KEY
pyannoteAIDiarization + voice profilesPYANNOTE_API_KEY, PYANNOTE_ENABLED=true
OpenAILLM analysisLLM_API_KEY
FirebaseAuth in staging/prodFIREBASE_PROJECT_ID (and optionally service-account credentials)

In dev, Firebase is disabled by default (FIREBASE_PROJECT_ID is empty) — a fixed Local Dev user is attached to every request so per-user scoping still works.

Object storage

The dev profile defaults to local filesystem (OBJECT_STORAGE_PROVIDER=local). Artifacts are written to ./var/storage-dev under the repo root, mirroring the S3 key layout. No credentials needed.

To test against real S3/R2 locally, set OBJECT_STORAGE_PROVIDER=s3 and fill in the bucket/endpoint/key variables from .env.example.

Connecting a physical Android device

The devDebug Android flavor points to DEV_BASE_URL in local.properties. Set this to your Mac's LAN IP:

ipconfig getifaddr en0 # e.g. 192.168.1.105

Then in Scryon/local.properties:

DEV_BASE_URL=http://192.168.1.105:8080/

The dev flavor's network_security_config.xml already permits cleartext HTTP, so no further Android config is needed.

Run tests

./mvnw test

Integration tests use the local profile (H2 in-memory) — no Docker required.

Useful endpoints during dev

URLPurpose
http://localhost:8080/swagger-ui.htmlOpenAPI explorer (dev + staging only)
http://localhost:8080/api/healthLiveness check
http://localhost:8080/api/debug/calls/{id}/eventsPipeline event log (dev + staging only)
http://localhost:8080/actuator/prometheusPrometheus scrape endpoint
http://localhost:8080/v3/api-docsRaw OpenAPI spec

What's next