Environment Variables
TaskView is configured through environment variables set in the .env.taskview file (or passed directly to the Docker container). This page documents every available variable.
Database
These must match your PostgreSQL setup.
| Variable | Required | Default | Description |
|---|---|---|---|
DB_HOST | Yes | - | Database hostname. Use db when running in Docker Compose. |
DB_USER | Yes | - | Database username |
DB_PASSWORD | Yes | - | Database password |
DB_NAME | Yes | - | Database name |
DB_PORT | No | 5432 | Database port |
DB_POOL_MAX | No | 20 | Maximum Postgres connections per API worker (each worker opens its own pool) |
Connection budget: the total number of Postgres connections is roughly PM2_INSTANCES × DB_POOL_MAX. Keep it below the max_connections of your PostgreSQL (default 100), leaving ~10 connections of headroom for migrations and maintenance. The API logs a warning at startup when the estimate exceeds 80.
Application
| Variable | Required | Default | Description |
|---|---|---|---|
APP_PORT | No | 1401 | Port the API server listens on |
PM2_INSTANCES | No | 2 | Number of API worker processes (PM2 cluster mode). Accepts a number or max (one worker per CPU core). When using max, set DB_POOL_MAX yourself so the connection budget above still fits. |
APP_URL | Yes | https://app.taskview.tech | Full URL of the web app (e.g. https://tasks.company.com). Used for OAuth redirects and email links. |
TRUST_PROXY | No | false | Set when running behind a reverse proxy so X-Forwarded-Proto/X-Forwarded-For are honoured (correct https URLs, real client IP). Use the number of proxies in front of the app (1 for a single Caddy/nginx), or an IP/subnet list (10.0.0.0/8, uniquelocal). Leave unset for direct access. Avoid true (trusts any hop, allows header spoofing). |
Web app
Unlike everything else on this page, this variable is set on the web app container (taskview-webapp), not in .env.taskview.
| Variable | Required | Default | Description |
|---|---|---|---|
TASKVIEW_API_URL | No | - | Pins the API server URL for the web app (e.g. https://api.company.com). When set, the "Select server" section disappears from the login page and the app always talks to this API. When unset, users pick the API server on the login page themselves. |
Authentication
| Variable | Required | Default | Description |
|---|---|---|---|
JWT_SIGN | Yes | - | Secret key for signing JWT tokens. Use a long random string. |
ACCESS_LIFE_TIME | No | 1d | How long access tokens are valid. Examples: 1h, 1d, 7d |
REFRESH_LIFE_TIME | No | 2d | How long refresh tokens are valid |
JWT_ALG | No | HS256 | JWT signing algorithm |
AUTH_LOGIN_METHODS | No | all enabled | Comma-separated list of login methods to offer: magic-link, password, sso, social. Disabled methods disappear from the login page and their API endpoints return 403. The API refuses to start if the list contains a typo or disables every method. |
PASSWORD_CHANGE_CONFIRMATION | No | email | How account password changes are confirmed: email — a confirmation code is sent to the user's email (requires SMTP); password — the user confirms with their current password (works without SMTP, recommended for installs without a mail server). |
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"SMTP (Email)
Required for password recovery, email confirmation, and invitation notifications. Without SMTP, these features won't work, but everything else functions normally.
| Variable | Required | Default | Description |
|---|---|---|---|
SMTP_HOST | No | - | SMTP server hostname |
SMTP_PORT | No | 465 | SMTP port |
SMTP_USERNAME | No | - | SMTP login |
SMTP_PASSWORD | No | - | SMTP password |
SMTP_ENCRYPTION | No | ssl | ssl or tls |
SMTP_FROM_NAME | No | TaskView | Sender name in emails |
SMTP_FROM_EMAIL | No | - | Sender email address |
Encryption
Required for SSO (SAML/OIDC) and GitHub/GitLab integrations. Secrets are encrypted at rest using AES-256-GCM.
| Variable | Required | Default | Description |
|---|---|---|---|
ENCRYPTION_KEY | Yes | - | 32-byte hex string (64 characters). Required for SSO and integrations. |
Generate a key:
openssl rand -hex 32
What is encrypted:
- SSO: SAML certificates, SAML signing keys, OIDC client secrets
- Integrations: GitHub/GitLab OAuth tokens, webhook secrets
GitHub Integration
For connecting GitHub repositories. See GitHub & GitLab Setup for a step-by-step guide.
| Variable | Required | Default | Description |
|---|---|---|---|
GITHUB_INTEGRATION_CLIENT_ID | No | - | OAuth App client ID |
GITHUB_INTEGRATION_CLIENT_SECRET | No | - | OAuth App client secret |
GITHUB_INTEGRATION_CALLBACK_URL | No | - | OAuth callback URL |
GITHUB_BASE_URL | No | https://github.com | Override for GitHub Enterprise |
GITHUB_API_URL | No | https://api.github.com | Override for GitHub Enterprise API |
GitLab Integration
For connecting GitLab repositories.
| Variable | Required | Default | Description |
|---|---|---|---|
GITLAB_INTEGRATION_CLIENT_ID | No | - | OAuth App client ID |
GITLAB_INTEGRATION_CLIENT_SECRET | No | - | OAuth App client secret |
GITLAB_INTEGRATION_CALLBACK_URL | No | - | OAuth callback URL |
GITLAB_BASE_URL | No | https://gitlab.com | Override for self-hosted GitLab |
GITLAB_API_URL | No | https://gitlab.com/api/v4 | Override for self-hosted GitLab API |
Messaging Integrations (Telegram / Slack)
For delivering task notifications to messengers. See Telegram & Slack Setup for a step-by-step guide.
| Variable | Required | Default | Description |
|---|---|---|---|
TELEGRAM_BOT_TOKEN | No | - | Bot token from @BotFather |
TELEGRAM_BOT_USERNAME | No | - | Bot username without @ (used to build deep-links) |
TELEGRAM_WEBHOOK_SECRET | No | - | Secret verified against Telegram's X-Telegram-Bot-Api-Secret-Token header on inbound updates |
SLACK_CLIENT_ID | No | - | Slack app client ID |
SLACK_CLIENT_SECRET | No | - | Slack app client secret |
SLACK_CALLBACK_URL | No | - | OAuth callback URL (must match the Slack app redirect URL) |
SLACK_SIGNING_SECRET | No | - | Slack request signing secret — verifies inbound slash commands / interactivity (/task, Done/Assign buttons) |
SLACK_API_BASE_URL | No | https://slack.com/api | Override the Slack Web API base (testing / enterprise proxy) |
SLACK_AUTHORIZE_URL | No | https://slack.com/oauth/v2/authorize | Override the Slack OAuth authorize URL |
SLACK_WEBHOOK_PREFIX | No | https://hooks.slack.com/ | Override the incoming-webhook URL prefix (used to detect legacy webhook connections) |
Notifications
Optional configuration for real-time and push notification delivery.
Centrifugo (real-time WebSocket notifications)
Required for in-app real-time notification delivery. Without Centrifugo, notifications are still saved to the database but will not appear instantly in the browser. Users will see them on the next page load.
| Variable | Required | Default | Description |
|---|---|---|---|
CENTRIFUGO_API_URL | No | - | Internal Centrifugo API URL (e.g. http://centrifugo:8000) |
CENTRIFUGO_API_KEY | No | - | Centrifugo API key for server-to-server communication. Must match http_api.key in Centrifugo config. |
CENTRIFUGO_TOKEN_SECRET | No | - | Secret for generating client connection tokens (HMAC). Must match client.token.hmac_secret_key in Centrifugo config. |
CENTRIFUGO_PUBLIC_URL | No | - | Full WebSocket URL for browser clients (e.g. wss://api.example.com/centrifugo/connection/websocket) |
Firebase Cloud Messaging (mobile push notifications)
Required for native push notifications on iOS and Android. Without Firebase, push notifications are silently skipped.
| Variable | Required | Default | Description |
|---|---|---|---|
FIREBASE_CREDENTIALS_PATH | No | - | Path to Firebase service account JSON file (e.g. ./firebase-credentials.json) |
Centrifugo configuration file
Centrifugo v6 uses a nested JSON config. Create centrifugo/config.json:
{
"client": {
"allowed_origins": ["https://app.example.com"],
"token": {
"hmac_secret_key": "your_centrifugo_token_secret"
}
},
"channel": {
"namespaces": [
{
"name": "personal",
"presence": false,
"join_leave": false,
"history_size": 0,
"history_ttl": "0s"
}
]
},
"http_api": {
"key": "your_centrifugo_api_key"
}
}
http_api.keymust matchCENTRIFUGO_API_KEYin.env.taskviewclient.token.hmac_secret_keymust matchCENTRIFUGO_TOKEN_SECRETin.env.taskviewclient.allowed_originsshould list your frontend domain(s). Use["*"]only for development.
Nginx WebSocket proxy
To serve Centrifugo through your existing HTTPS domain, add to your nginx server block:
location /centrifugo/ {
proxy_pass http://localhost:8000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Then set CENTRIFUGO_PUBLIC_URL=wss://api.example.com/centrifugo/connection/websocket.
Full example
Here's a complete .env.taskview file for a production deployment:
DB_HOST="db"
DB_USER="taskview_db_user"
DB_PASSWORD="password"
DB_NAME="taskview"
DB_PORT=5432
# Postgres connections per API worker (this is the default)
DB_POOL_MAX=20
APP_PORT=1401
# API worker processes (this is the default). Accepts a number or "max" (one worker per CPU core).
# Keep PM2_INSTANCES x DB_POOL_MAX below the Postgres max_connections limit (default 100).
PM2_INSTANCES=2
JWT_ALG="HS256"
JWT_SIGN="secret"
ACCESS_LIFE_TIME="3d"
REFRESH_LIFE_TIME="9d"
# Login methods offered on the login page (unset = all enabled)
#AUTH_LOGIN_METHODS="magic-link,password,sso,social"
# Password change confirmation: "email" (code by email, needs SMTP) or "password" (no SMTP needed)
#PASSWORD_CHANGE_CONFIRMATION="email"
SMTP_HOST=smtp
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_ENCRYPTION=tls
SMTP_FROM_NAME=TaskView
SMTP_FROM_EMAIL=
# Your domain
APP_URL="https://app.taskview.tech"
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
#You domain
GOOGLE_CALLBACK_URL="https://api.taskview.tech/module/auth/provider/google/callback"
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
GITHUB_CALLBACK_URL="https://api.taskview.tech/module/auth/provider/github/callback"
APPLE_CLIENT_ID=""
APPLE_TEAM_ID=""
APPLE_KEY_ID=""
APPLE_KEY_LOCATION="/usr/src/app/AuthKey.p8"
# Your domain
APPLE_CALLBACK_URL="https://api.taskview.tech/module/auth/provider/apple/callback"
#integrations
GITHUB_INTEGRATION_CLIENT_ID=
GITHUB_INTEGRATION_CLIENT_SECRET=
GITHUB_INTEGRATION_CALLBACK_URL=https://api.taskview.tech/module/integrations/oauth/github/callback
GITLAB_INTEGRATION_CLIENT_ID=
GITLAB_INTEGRATION_CLIENT_SECRET=
GITLAB_INTEGRATION_CALLBACK_URL=https://api.taskview.tech/module/integrations/oauth/github/callback
ENCRYPTION_KEY=
# Messaging integrations
TELEGRAM_BOT_TOKEN=
TELEGRAM_BOT_USERNAME=
TELEGRAM_WEBHOOK_SECRET=
# SLACK_CLIENT_ID=
# SLACK_CLIENT_SECRET=
# SLACK_SIGNING_SECRET=
# Notifications (optional)
# FIREBASE_CREDENTIALS_PATH=./firebase-credentials.json
# CENTRIFUGO_API_URL=http://centrifugo:8000
# CENTRIFUGO_API_KEY=your_centrifugo_api_key
# CENTRIFUGO_TOKEN_SECRET=your_centrifugo_token_secret
# CENTRIFUGO_PUBLIC_URL=wss://api.example.com/centrifugo/connection/websocket
Telegram & Slack Setup
Connect Telegram and Slack to TaskView to receive task notifications. Personal direct messages and project-wide group channels, with instance-level bot credentials, OAuth, signed inbound webhooks, and SHA-256 hashed binding tokens.
Authentication
Configure authentication in TaskView - email/password, email/code, OAuth with GitHub, Google, and Apple Sign In. JWT session management, password recovery, and account deletion for your self-hosted instance.
