IMPORTANT
Notivae is in early-stage development. No features are fully implemented yet.
Installation
Notivae can run on your own computer or server using Docker, a tool that bundles everything it needs. No need to install each part separately.
We’ll use a tool called docker-compose
to launch all components – the app, its backend, and the database – all with one command.
Prerequisites
Make sure these are ready on your system:
Setup Files
To run Notivae, you'll need two files:
docker-compose.yml
– defines the services (frontend, backend, database), ports, and volumes..env
– contains configuration settings like database passwords, ports, and secrets.
Copy the following files to your local machine or server. We recommend placing them under /srv/notivae-stack
.
- The
docker-compose.yml
file works as-is but can be customized to your environment or use case. - The
.env
file must be reviewed and adjusted. Each variable has a comment or description in the sample. For a deeper explanation, see Configuration.
Your folder structure should look like this:
📁 /srv/notivae-stack
┣ 📄 docker-compose.yml
┗ 📄 .env
WARNING
These configuration files are currently in draft status and are not fully functional. Use them as a reference or base for manual setup until stable versions are released.
services:
server:
image: ghcr.io/notivae/server
restart: unless-stopped
ports:
- "127.0.0.1:8765:80"
env_file: .env
environment:
DATABASE_URL: ${DATABASE_URL:-postgresql+asyncpg://notivae:devpass@postgres/notivae}
REDIS_URL: redis://redis
volumes:
- nvdata:/data
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
web:
image: ghcr.io/notivae/web
restart: unless-stopped
ports:
- "127.0.0.1:8766:80"
postgres:
image: postgres:alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-notivae}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-devpass}
POSTGRES_DB: ${POSTGRES_DB:-notivae}
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U \"${POSTGRES_USER:-notivae}\""]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:alpine
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
volumes:
nvdata:
pgdata:
# ----------------------------------------
# Backend Debugging & Logging
# ----------------------------------------
# Enables debug mode across the app.
# Should be False in production to avoid exposing sensitive details.
#DEBUG=False
# Minimum severity level of log messages to be output.
# Options:
# DEBUG - Most verbose, shows everything (useful for local dev).
# INFO - General runtime information (default for production).
# WARNING - Things that might be problems in the future.
# ERROR - Runtime errors that should be investigated.
# CRITICAL - Application or system-wide failures.
# Use DEBUG for local development, INFO or WARNING for production.
#LOGGING_LEVEL=INFO
# Format used for application logs.
# console - Human-readable format, ideal for terminal output.
# json - Structured logs, preferred for log ingestion (e.g., ELK, Loki).
#LOGGING_FORMAT=console
# If enabled, logs will also be written to the database in addition to stdout.
# Useful for persistent audit logs or advanced querying.
#LOG_TO_DB=True
# ----------------------------------------
# Backend Server Configuration
# ----------------------------------------
# The IP address the backend server will bind to.
# Common values:
# 0.0.0.0 - Bind to all network interfaces (use in Docker or remote envs).
# 127.0.0.1 - Bind to localhost only (useful for local testing).
#SERVER_HOST=0.0.0.0
# The port the backend server will listen on.
# Must be an integer between 1 and 65534.
#SERVER_PORT=8765
# ----------------------------------------
# Database Configuration
# ----------------------------------------
# The full database connection URL used by the backend service to connect
# to PostgreSQL. This should follow the format:
# dialect+driver://username:password@host:port/database
# e.g. postgresql+asyncpg://notivae:devpass@postgres/notivae
# If you are using Docker Compose, this should typically point to the
# internal Docker service name (e.g., `postgres`) instead of `localhost`.
DATABASE_URL=postgresql+asyncpg://notivae:devpass@localhost:5432/notivae
# The number of persistent database connections maintained per application worker.
# Increase this value for high-throughput systems with lots of concurrent queries.
#DATABASE_POOL_SIZE=5
# The number of temporary connections that can exceed the pool size during peak usage.
# These "overflow" connections are not persistent and will be discarded after use.
#DATABASE_POOL_MAX_OVERFLOW=10
# Maximum time (in seconds) to wait for a database connection before failing.
# Prevents application hangs under connection saturation or DB outage.
#DATABASE_POOL_TIMEOUT=30
# Time (in seconds) after which idle database connections will be recycled.
# Helps prevent stale or broken connections in long-lived environments.
#DATABASE_POOL_RECYCLE=1800
# ----------------------------------------
# PostgreSQL Container Configuration (Docker Compose)
# ----------------------------------------
# The username that will be created in the Postgres container.
# This must match the user part of DATABASE_URL.
POSTGRES_USER=notivae
# The password assigned to POSTGRES_USER.
# Used for authenticating from the backend or any external tool.
# This must match the password part of DATABASE_URL.
POSTGRES_PASSWORD=devpass
# The name of the default database that will be created in the container.
# This must match the database name in DATABASE_URL.
POSTGRES_DB=notivae
# ----------------------------------------
# OpenID Connect Identity Provider Config
# ----------------------------------------
# The client ID issued by your OpenID Connect provider (e.g. Auth0, Keycloak, etc.).
# This must match the client configured in the identity provider dashboard.
#OIDC_CLIENT_ID=your-client-id
# The client secret corresponding to the OIDC client.
# Keep this value secret and never commit it to version control.
#OIDC_CLIENT_SECRET=your-client-secret
# URI where users are redirected to authorize the application.
#OIDC_AUTH_URI=https://example.com/oauth2/authorize
# URI used to exchange the authorization code for tokens.
#OIDC_TOKEN_URI=https://example.com/oauth2/token
# URI used to fetch authenticated user information.
#OIDC_USERINFO_URI=https://example.com/oauth2/userinfo
# URI to redirect users after logout (optional for some providers).
#OIDC_LOGOUT_URI=https://example.com/oauth2/logout
# Name shown in the UI for this login option (e.g. "Authentik", "My Company SSO").
#OIDC_DISPLAY_NAME=OpenID
# Scopes to request during authentication.
# Adjust depending on the level of access your app needs.
#OIDC_SCOPES="openid profile email"
# ----------------------------------------
# GZip Compression Configuration
# ----------------------------------------
# Minimum size in bytes a response must reach before gzip compression is applied.
# This helps avoid wasting CPU cycles compressing small payloads that won't benefit.
#GZIP_COMPRESSION_MINIMUM_SIZE=1000
# Compression level to use when gzip is enabled.
# 1 = Fastest, lowest compression ratio.
# 9 = Slowest, highest compression ratio.
# 6 is the recommended default for balanced performance.
#GZIP_COMPRESSION_LEVEL=6
Start the Stack
From within the /srv/notivae-stack
directory, run:
docker compose up -d
This command will:
- Start the database and cache (for storage)
- Start the backend (the engine)
- Start the frontend (the user interface)
Docker will automatically download any required images on the first run. This may take a while, depending on your internet connection.
Verify
After a few seconds, run this command in your terminal:
curl http://localhost:8765/healtz
You should see a simple response like:
{"status":"ok"}
If you see this message, it means the backend is running successfully and responding to requests.
However, you won’t be able to access the web interface yet. The frontend and backend are exposed on different ports and cannot communicate directly in this setup.
INFO
🛠️ To continue, you need to configure a reverse proxy or another solution that connects the frontend to the backend under a unified address.
This is required before opening the web UI in your browser.
Connect Frontend and Backend
Notivae’s frontend expects to reach the backend at /api
on the same domain and port — for example:
https://notivae.example.com → frontend
https://notivae.example.com/api → backend
However, in the current setup, the backend and frontend are exposed on different ports:
http://localhost:8766 → Frontend
http://localhost:8765 → Backend
This means they can’t communicate properly until you combine them under a unified domain or port.
The solution is a reverse proxy. A reverse proxy acts as a gateway that:
- Routes browser requests to the correct service (frontend or backend)
- Handles HTTPS (SSL) if needed
- Rewrites paths like
/api/*
to target the backend
This setup is required even if you're running Notivae locally.
Popular reverse proxy options:
- Caddy — simple, automatic HTTPS
- Traefik — Docker-native, dynamic
- Nginx — widely supported, configurable
Need help setting it up?
See the Reverse Proxy Guide for setup examples and config snippets.
TIP
Hosting Notivae behind a home network? You may need a tunnel like Cloudflare Tunnel or Ngrok to make it accessible from the internet.
This is also covered in the Reverse Proxy Guide.
Finalizing your instance
Notivae's web-ui has a built-in wizard to help you configure the final parts or your hosted instance. To start the setup wizard open the following page in your browser.
https://<your-domain-or-ip>/#/init
e.g. https://notivae.example.com/#/init
Updating
To update Notivae to the latest version:
docker-compose pull
docker-compose up -d
This will:
- Pull the latest image versions
- Restart the containers using the updated versions
WARNING
This command works only if you are omitting or using floating tags like :latest
or :dev
in your docker-compose.yml
. If you pin versions explicitly in docker-compose.yml
, you need to update the tags manually before running pull.
Stopping the Stack
To shut everything down:
docker-compose down
Your data (e.g., database files) will be preserved unless you remove the Docker volumes explicitly.