Skip to content

Development Setup

The dev environment runs entirely inside a Dev Container, giving everyone the same tools and services out of the box with no local installs.

Prerequisites

Getting started

  1. Clone the repository
  2. Open the repo folder in VS Code
  3. When prompted, click Reopen in Container — or run CMD+Shift+PDev Containers: Reopen in Container

On the first run, VS Code builds the container image (takes a few minutes) and automatically runs postCreateCommand, which:

  • Downloads Go modules (go mod download)
  • Installs web dependencies (npm ci)
  • Creates backend/tmp/data/ and backend/logs/

Subsequent opens reuse the cached image and named volumes, so startup is fast.

What's included

Container tools

Tool Version
Go 1.25
Node.js 22
protoc 29.3
golangci-lint 2.10.1
just 1.42.0
air 1.62.0
sqlc 1.30.0
goose 3.26.0
atlas 1.1.0
gotestsum 1.13.0
vault CLI 1.20.4
nats CLI latest
k6 0.55.0

The shell is zsh with starship prompt, fzf, syntax highlighting, autosuggestions, and eza (a modern ls replacement). See .devcontainer/.zshrc for all aliases.

Backing services

Service Host (inside container) Port
PostgreSQL db 5432
TimescaleDB timescaledb 5432
Vault vault 8200
NATS nats 4222
Redis redis 6379
Mailpit SMTP mailpit 1025
Mailpit UI mailpit 8025
Garage S3 garage 3900
Gotenberg gotenberg 3000
NATS UI 31311

All services start with just up. Data is persisted in named Docker volumes.

Forwarded ports

VS Code auto-forwards all service ports to your host machine. You'll get a notification when Angular (4200) or the backend HTTP servers (8080, 8081, 8083, 8999) are available. All other ports forward silently.

Git config

If user.name or user.email aren't set in the container, the startup script will print a reminder. Configure them once:

git config --global user.name "Your Name"
git config --global user.email "you@example.com"

Repository layout

At the root of the repo is a justfile which contains most day-to-day commands. Run just (or jl) to get a list. just can be run from anywhere in the repository.

backend/

Go monorepo with a single go.mod. Individual apps live in apps/.

  • Run an app: just run <app>
  • List apps: just apps

web/

Nx monorepo with Angular apps and libraries.

  • Run an app: just web <app>
  • List apps: just web-apps

Service setup

Create backend/config/ and add a config file per service you want to run. All credentials below are the defaults pre-configured in the compose stack.

Solaris

backend/config/solaris.yml:

env: "local"
log:
  level: -1
  path: "./logs"
server:
  port: 8080
  grpc_port: 50051
database:
  host: "db"
  port: 5432
  database: "solaris"
  vault_mount: "database"
  vault_role: "stream-app"
mother_vault:
  address: "http://vault:8200"
  role_id: "solaris-role-id"
  secret_id: "solaris-secret-id"
  kv_mount: "secret"
cluster_vault:
  address: "http://vault:8200"
mail_pit:
  base_url: http://mailpit:8025
sentinel:
  host: localhost
  port: 50053
assume_org: <filled in later step>
nats:
  url: nats://nats:4222
  username: nats
  password: nats
  scope: local
  private_prefix: private

To finish setting up Solaris:

  1. just run solaris
  2. just web admin-ui
  3. Sign into Admin UI using Authentik (user provided by Fabian)
  4. Create an Organization and copy its ID from the network tab
  5. Paste the ID into assume_org in the config, then restart Solaris
  6. Create a global user for yourself (can sign into any org)
  7. just web customer-ui — sign in with your global user

Nexus

backend/config/nexus.yml:

log:
  level: -1
server:
  grpc:
    port: 50052
  http:
    port: 8081
solaris:
  host: "localhost"
  port: 50051
vault:
  address: "http://vault:8200"
  role_id: "nexus-role-id"
  secret_id: "nexus-secret-id"
  kv_mount: "secret"
nats:
  url: nats://nats:4222
  username: nats
  password: nats
  scope: local
  private_prefix: private
cache:
  identity:
    type: redis
  nonce:
    type: redis
  session:
    type: redis

just run nexus

Sentinel

backend/config/sentinel.yml:

log:
  level: -1
server:
  grpc:
    port: 50053
  http:
    port: 8083
db:
  url: postgres://sentinel:sentinel@timescaledb:5432/sentinel?sslmode=disable
nats:
  url: nats://nats:4222
  username: nats
  password: nats
  scope: local
  private_prefix: private

just run sentinel