Installation
Torqvoice is designed to be self-hosted. Choose the setup that fits your needs:
- Quick Start — Get running locally in minutes with Docker Compose
- Production with SSL — Deploy with automatic HTTPS using Nginx or Caddy
- Manual Setup — Run directly with Node.js without Docker
- Development — Contribute to Torqvoice using Dev Containers
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended), VPS, or local machine
- Docker installed
- At least 1 GB of RAM and 2 GB of disk space
Quick Start
This is the fastest way to get Torqvoice up and running.
1. Create your project directory
mkdir torqvoice && cd torqvoice
2. Create .env
This generates a secure auth secret and writes the .env file in one step:
echo "BETTER_AUTH_SECRET=$(openssl rand -hex 32)" > .env
echo 'NEXT_PUBLIC_APP_URL=http://localhost:3000' >> .env
If you are deploying on a remote server, replace localhost with your server's IP address or domain name (e.g. http://192.168.1.100:3000).
3. Create docker-compose.yml
services:
app:
container_name: torqvoice
image: ghcr.io/torqvoice/torqvoice:latest
restart: unless-stopped
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://torqvoice:torqvoice@db:5432/torqvoice
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
volumes:
- uploads:/app/data/uploads
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
container_name: torqvoice-db
restart: unless-stopped
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_USER: torqvoice
POSTGRES_PASSWORD: torqvoice
POSTGRES_DB: torqvoice
healthcheck:
test: ["CMD-SHELL", "pg_isready -U torqvoice"]
interval: 5s
timeout: 5s
retries: 5
volumes:
postgres-data:
uploads:
5. Start and visit
docker compose up -d
Visit http://localhost:3000 and create your first admin account.
Production with SSL
For production deployments you need a reverse proxy in front of Torqvoice to handle HTTPS. Pick either Nginx or Caddy — both provide automatic Let's Encrypt certificates.
A domain name pointed at your server is required for SSL to work.
Nginx + acme-companion
Uses nginx-proxy and acme-companion for automatic certificate provisioning and renewal.
Create a .env file:
echo "BETTER_AUTH_SECRET=$(openssl rand -hex 32)" > .env
Create a docker-compose.yml:
services:
nginx-proxy:
image: nginxproxy/nginx-proxy
container_name: nginx-proxy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- certs:/etc/nginx/certs
- html:/usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
- TRUST_DOWNSTREAM_PROXY=false
acme-companion:
image: nginxproxy/acme-companion
container_name: acme-companion
restart: unless-stopped
volumes_from:
- nginx-proxy
volumes:
- acme:/etc/acme.sh
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- DEFAULT_EMAIL=your-email@example.com
app:
container_name: torqvoice
image: ghcr.io/torqvoice/torqvoice:latest
restart: unless-stopped
expose:
- "3000"
environment:
- DATABASE_URL=postgresql://torqvoice:torqvoice@db:5432/torqvoice
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- NEXT_PUBLIC_APP_URL=https://torqvoice.example.com
- VIRTUAL_HOST=torqvoice.example.com
- VIRTUAL_PORT=3000
- LETSENCRYPT_HOST=torqvoice.example.com
volumes:
- uploads:/app/data/uploads
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
container_name: torqvoice-db
restart: unless-stopped
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_USER: torqvoice
POSTGRES_PASSWORD: torqvoice
POSTGRES_DB: torqvoice
healthcheck:
test: ["CMD-SHELL", "pg_isready -U torqvoice"]
interval: 5s
timeout: 5s
retries: 5
volumes:
certs:
html:
acme:
postgres-data:
uploads:
Replace torqvoice.example.com with your domain and your-email@example.com with your email for Let's Encrypt notifications. The nginx-proxy container automatically discovers the Torqvoice container via the VIRTUAL_HOST variable, and acme-companion handles certificate provisioning and renewal.
Caddy
Caddy provides automatic HTTPS with zero configuration.
Create a .env file:
echo "BETTER_AUTH_SECRET=$(openssl rand -hex 32)" > .env
Create a Caddyfile:
torqvoice.example.com {
reverse_proxy app:3000
}
Create a docker-compose.yml:
services:
caddy:
image: caddy:2-alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy-data:/data
- caddy-config:/config
app:
container_name: torqvoice
image: ghcr.io/torqvoice/torqvoice:latest
restart: unless-stopped
expose:
- "3000"
environment:
- DATABASE_URL=postgresql://torqvoice:torqvoice@db:5432/torqvoice
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- NEXT_PUBLIC_APP_URL=https://torqvoice.example.com
volumes:
- uploads:/app/data/uploads
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
container_name: torqvoice-db
restart: unless-stopped
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
POSTGRES_USER: torqvoice
POSTGRES_PASSWORD: torqvoice
POSTGRES_DB: torqvoice
healthcheck:
test: ["CMD-SHELL", "pg_isready -U torqvoice"]
interval: 5s
timeout: 5s
retries: 5
volumes:
caddy-data:
caddy-config:
postgres-data:
uploads:
Replace torqvoice.example.com with your domain in both the Caddyfile and docker-compose.yml. Caddy will automatically obtain and renew SSL certificates.
Docker without Compose
If you already have a PostgreSQL database running, you can run the Torqvoice container directly:
docker run -d \
--name torqvoice \
-p 3000:3000 \
-e DATABASE_URL="postgresql://user:pass@your-db-host:5432/torqvoice" \
-e BETTER_AUTH_SECRET="your-secret-here" \
-e NEXT_PUBLIC_APP_URL="http://localhost:3000" \
-v torqvoice-uploads:/app/public/uploads \
ghcr.io/torqvoice/torqvoice:latest
Manual Setup
Run Torqvoice directly with Node.js — useful for custom deployments without Docker.
Requirements: Node.js 20+ with npm, PostgreSQL 15+
git clone https://github.com/Torqvoice/torqvoice.git
cd torqvoice
npm install
cp .env.example .env
# Edit .env with your database URL and secrets
npx prisma generate
npx prisma db push
npm run build
npm start
The application will be available at http://localhost:3000.
Development
The recommended way to develop Torqvoice is to open the project in a Dev Container. The repository includes a .devcontainer configuration that sets up the full development environment with PostgreSQL and all required tooling, ensuring proper linting and consistent editor settings out of the box.
In VS Code, install the Dev Containers extension, then open the command palette and select Dev Containers: Reopen in Container. The container will build automatically and start the database alongside the development server.
Updating
docker compose pull
docker compose up -d
Your data is stored in Docker volumes and will persist across updates.
Environment Variables
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Yes | PostgreSQL connection string |
BETTER_AUTH_SECRET | Yes | Auth secret (generate with openssl rand -hex 32) |
NEXT_PUBLIC_APP_URL | Yes | Public URL of your Torqvoice instance |
Next Steps
After installation, head to the Configuration guide to set up email notifications, payment integrations, and other settings.