Installation
Polyphony is distributed as a set of Docker images orchestrated with Docker Compose.
The recommended way to run it in production is with docker-compose.yml.
Prerequisites
- Docker 24+
- Docker Compose v2 (bundled with Docker Desktop)
1. Get the source
git clone <repository-url>
cd polyphony
2. Configure the environment
Copy the environment template and edit it:
cp .env.example .env
Open .env and set at minimum:
| Variable | Description | Default |
|---|---|---|
SECRET_KEY | JWT signing key — must be changed in production | change-me-in-production |
NGINX_PORT | Host port nginx listens on | 80 |
Email / SMTP
| Variable | Description | Default |
|---|---|---|
EMAIL_NOTIFICATIONS_ENABLED | Master switch for all outgoing email | true |
SMTP_HOST | SMTP server hostname (e.g. smtp.gmail.com) | (empty — email disabled) |
SMTP_PORT | SMTP port | 587 |
SMTP_USER | SMTP login username / email address | (empty) |
SMTP_PASSWORD | SMTP password or app-specific password | (empty) |
SMTP_FROM | From address in outgoing emails (defaults to SMTP_USER if blank) | (empty) |
SMTP_USE_TLS | Use STARTTLS (port 587 style) | true |
SMTP_USE_SSL | Use SSL wrapper (port 465 style) — disables STARTTLS | false |
APP_BASE_URL | Public base URL of the app, used in email links | http://localhost |
Email is sent synchronously during request handling. If the SMTP server is unreachable, the request still succeeds and the failure is logged.
LLM API keys (OpenAI, Google Gemini) are configured per user inside the web UI,
not in .env.
3. Start the stack
docker compose up --build
This builds and starts four services:
| Service | Role |
|---|---|
nginx | Reverse proxy — serves the frontend and routes /api to the backend |
backend | FastAPI application |
frontend | Pre-built React app (served as static files) |
db | PostgreSQL 16 database |
The backend waits for the database health check before starting.
The first --build compiles the frontend bundle; subsequent runs can omit it.
4. Apply database migrations
On first start (or after an upgrade) run Alembic to create or update the schema:
docker compose exec backend alembic upgrade head
5. Create the first admin user
docker compose exec -it backend python cli.py users add-admin
The command prompts for a name, email address, and password, then creates the account with admin, researcher, and annotator roles assigned.
6. Access the application
Open http://localhost (or http://localhost:<NGINX_PORT> if you changed the
port). Log in with the account you just created.
Services and ports
| Service | Internal port | Exposed |
|---|---|---|
| nginx | 80 | NGINX_PORT (default 80) |
| PostgreSQL | 5432 | 5432 (host-accessible for tools like psql) |
The backend and frontend containers are only reachable through nginx on the external network; they are not directly exposed.
Plugins
The plugins/ directory at the project root is mounted read-only at /plugins
inside the backend container. Place plugin folders there and install them from the
admin panel under Admin → Plugins → Local Plugins.
Upgrading
git pull
docker compose up --build
docker compose exec backend alembic upgrade head
Stopping
# Stop containers (data preserved)
docker compose down
# Stop and delete the PostgreSQL volume (all data lost)
docker compose down -v