Local Docker setup
Spin up the server locally with one script. The setup brings up two containers — pia-server and a PostgreSQL database — and exposes the API at http://localhost:8080.
Prerequisites
Section titled “Prerequisites”- Docker Desktop with WSL integration enabled
- Git Bash or a WSL terminal
| File | Purpose |
|---|---|
docker-compose.local.yml |
Compose config for local deployment (server + PostgreSQL) |
.env.example |
Template for the required environment variables |
docker-local.sh |
Wrapper script for build / start / stop / logs / db |
Required configuration
Section titled “Required configuration”Two values must be present in .env. Without them the server refuses to start.
| Variable | What it is | How to generate |
|---|---|---|
JWT_SECRET_KEY |
Signs auth tokens, any string ≥ 32 chars | openssl rand -hex 32 |
ENCRYPTION_MASTER_KEY |
Encrypts stored API keys, exactly 64 hex chars | openssl rand -hex 32 |
POSTGRES_PASSWORD is auto-generated on first run if not set.
Optional AI configuration
Section titled “Optional AI configuration”The AI proxy needs at least one upstream provider to be useful.
| Variable | Example |
|---|---|
AI_API_KEY |
sk-proj-... |
AI_PROVIDER |
openai or azure |
AI_MODEL |
gpt-4o-mini |
AI_ENDPOINT |
https://api.openai.com |
You can also configure separate providers per client mode (Optimize / Assistant / Research). The client sends the active mode via the X-Pia-Mode header; if no per-mode override is set the default provider above is used.
| Variable | Purpose |
|---|---|
AI_ASSISTANT_PROVIDER / _API_KEY / _MODEL / _ENDPOINT |
Override for Assistant mode |
AI_RESEARCH_PROVIDER / _API_KEY / _MODEL / _ENDPOINT |
Override for Research mode |
Optional: the Mesh operator runtime
Section titled “Optional: the Mesh operator runtime”docker-compose.local.yml already wires a temporal dev-server service, but the
operator runtime is off until you enable it:
| Variable | Default | Purpose |
|---|---|---|
OPERATORS_ENABLED |
false |
Master switch — restart-only |
TEMPORAL_ADDRESS |
temporal:7233 |
Where the embedded worker connects |
TEMPORAL_NAMESPACE |
pia |
|
TEMPORAL_TASKQUEUE |
pia-operators |
Every OPERATORS_* cap (MAXSTEPS, RETENTIONDAYS, and the rest) has a working default — see
Configuration. Enabling this without a
reachable Temporal is not a crash: the worker logs a warning and idles, and /health stays green.
Connector pods need no configuration here at all — they are catalog rows, created from Admin → Connectors once the server is up.
Optional OAuth
Section titled “Optional OAuth”To enable Google or Microsoft sign-in locally:
| Variable | What it is |
|---|---|
OAUTH_GOOGLE_CLIENT_ID / OAUTH_GOOGLE_CLIENT_SECRET |
Google OAuth credentials |
OAUTH_MICROSOFT_CLIENT_ID / OAUTH_MICROSOFT_CLIENT_SECRET |
Microsoft / Entra credentials |
Step-by-step
Section titled “Step-by-step”-
Create
.envfrom the templateTerminal window cd /c/projects/Piacp .env.example .env -
Generate and paste the keys
Terminal window openssl rand -hex 32 # → JWT_SECRET_KEYopenssl rand -hex 32 # → ENCRYPTION_MASTER_KEYOpen
.envand paste the values. AddAI_API_KEYif you want the AI proxy to work. -
Start everything
Terminal window ./docker-local.shThe script builds the image, starts PostgreSQL, waits for it to be healthy, then starts
pia-server. The API binds tolocalhost:8080; PostgreSQL tolocalhost:5432. -
Verify
Terminal window curl http://localhost:8080/health# → {"status":"healthy","timestamp":"..."}
Connect the desktop client
Section titled “Connect the desktop client”In Pia, open Settings → Account and set:
| Setting | Value |
|---|---|
| Server URL | http://localhost:8080 |
Then choose Pia Cloud as your AI provider. The client will route to the server for /api/ai/optimize, /api/sync/push, and /api/sync/pull.
OAuth login buttons in the client only appear when the corresponding OAUTH_* credentials are set in .env.
Script reference
Section titled “Script reference”./docker-local.sh # Build and start./docker-local.sh stop # Stop./docker-local.sh restart # Restart./docker-local.sh logs # Tail logs./docker-local.sh db # psql shell into the local database./docker-local.sh clean # Stop and delete the PostgreSQL data volumeTroubleshooting
Section titled “Troubleshooting”- Server won’t start: read
./docker-local.sh logs. Most oftenJWT_SECRET_KEYorENCRYPTION_MASTER_KEYis missing or the wrong length. - PostgreSQL connection errors: run
./docker-local.sh dbto confirm Postgres is reachable. If you switched from SQLite, run./docker-local.sh cleanto drop the old volume. - AI proxy returns 503:
AI_API_KEYis missing. CheckGET /api/ai/status. - OAuth not working: confirm the OAuth redirect URI
http://localhost:8080/auth/callback(or/signin-microsoftfor Entra) is registered with the provider, and that client ID + secret are in.env.