Skip to main content

Deployment Overview

PUNT can be deployed in several ways depending on your needs.

Deployment Options

OptionBest ForDatabaseComplexity
RailwayQuick cloud deploymentPostgreSQLLow
Self-HostedFull controlPostgreSQLMedium
Demo ModeEvaluationlocalStorageMinimal

Requirements

Node.js

PUNT requires Node.js 20 or later (Next.js 16 requirement).

Check your version:

node --version
# Should output v20.x.x or higher

Package Manager

pnpm is recommended:

npm install -g pnpm

Environment Variables

All deployments need certain environment variables:

Required

VariableDescriptionExample
AUTH_SECRETNextAuth.js secret keyopenssl rand -base64 32
DATABASE_URLPostgreSQL connection stringpostgresql://user:password@localhost:5432/punt

Optional

VariableDescriptionDefault
AUTH_TRUST_HOSTTrust proxy headersfalse
TRUST_PROXYTrust X-Forwarded-Forfalse
NEXT_PUBLIC_DEMO_MODEEnable demo modefalse
NEXT_PUBLIC_BASE_PATHSubpath deployment (e.g., /punt)`` (root)
NEXT_PUBLIC_APP_URLPublic URL for email linkshttp://localhost:3000

Generating AUTH_SECRET

Generate a secure secret:

openssl rand -base64 32

Or use Node.js:

node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"

Guided Setup

The fastest way to configure PUNT for any deployment is the guided installer:

pnpm install
pnpm run setup

This interactively configures PostgreSQL, generates .env, pushes the database schema, and creates an admin user. It also offers a demo mode path that skips database setup entirely.

tip

pnpm setup is a built-in pnpm command. Always use pnpm run setup to run the PUNT installer.

Build Process

Production Build

# Install dependencies
pnpm install

# Generate Prisma client
pnpm db:generate

# Build the application
pnpm build

Start Production Server

pnpm start

The server starts on port 3000 by default.

Database Setup

PostgreSQL (Required)

PUNT requires PostgreSQL 16 or later. Set the DATABASE_URL environment variable to your PostgreSQL connection string:

DATABASE_URL=postgresql://user:password@localhost:5432/punt

Once configured, initialize the schema:

# Create database tables
pnpm db:push

File Storage

Uploaded files are stored in the uploads/ directory:

uploads/
├── avatars/ # User profile pictures
├── attachments/ # Ticket attachments
└── files/ # General uploads

Persistent Storage

Ensure the uploads directory is:

  1. Persistent (not ephemeral)
  2. Backed up regularly
  3. Has sufficient disk space

Reverse Proxy

When running behind a reverse proxy (nginx, Caddy, etc.):

Enable Trust Proxy

AUTH_TRUST_HOST=true
TRUST_PROXY=true

Nginx Configuration

server {
listen 80;
server_name punt.example.com;

location / {
proxy_pass http://localhost:3000;
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;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;

# SSE support
proxy_buffering off;
proxy_cache off;
}
}

Caddy Configuration

punt.example.com {
reverse_proxy localhost:3000
}

Caddy automatically handles HTTPS and headers.

Security Checklist

Before deploying to production:

  • Generate a strong AUTH_SECRET
  • Set AUTH_TRUST_HOST=true only behind trusted proxy
  • Set TRUST_PROXY=true only behind trusted proxy
  • Enable HTTPS (via reverse proxy or directly)
  • Configure firewall rules
  • Set up database backups
  • Review file upload limits
  • Test rate limiting

Monitoring

Health Check

PUNT responds to requests at the root path:

curl http://localhost:3000/

Logs

Application logs are written to stdout. Use your platform's log aggregation:

  • Railway: Built-in log viewer
  • Docker: docker logs <container>
  • systemd: journalctl -u punt

Scaling

Horizontal Scaling

PUNT uses PostgreSQL, which supports concurrent connections natively. You can run multiple PUNT instances pointed at the same database for horizontal scaling.

Vertical Scaling

For more capacity:

  • Increase Node.js memory: NODE_OPTIONS="--max-old-space-size=4096"
  • Add more CPU cores
  • Use SSD storage for database

Backup Strategy

Database Backup

Regular PostgreSQL backups:

pg_dump $DATABASE_URL > backup.sql

Or use PUNT's built-in export:

  1. Admin Panel → Database → Export
  2. Store the JSON backup securely

File Backup

Backup the uploads directory:

tar -czf uploads-backup.tar.gz /path/to/uploads/

Next Steps