Skip to content

Install without Docker

Install Quackback without Docker using Bun and a direct PostgreSQL connection.

This guide is for users who prefer to run Quackback directly on their server without containerization.

Prerequisites

Bun

Version: 1.4.0 or higher

# Install Bun
curl -fsSL https://bun.sh/install | bash
 
# Verify installation
bun --version

PostgreSQL

Version: 14 or higher

Required extensions:

  • vector (pgvector 0.5.0 or newer) for similarity search
  • pg_trgm (from the PostgreSQL contrib package) for text search

PostgreSQL is the only datastore you need. Background jobs, caches, and realtime events all run on it, so there is no Redis or queue service to install. See System Requirements for connection-mode and privilege requirements.

Other Tools

  • Git
  • OpenSSL (for generating secrets)

Installation Steps

1. Clone the Repository

git clone https://github.com/quackbackio/quackback.git
cd quackback

2. Install Dependencies

bun install

3. Configure Environment

Copy the example environment file:

cp .env.example .env

Generate a secure auth secret:

# Generate a 32-byte secret
openssl rand -base64 32

Edit .env with your settings:

# Required settings
DATABASE_URL=postgresql://quackback:your_password@localhost:5432/quackback
SECRET_KEY=your-generated-secret-key-at-least-32-characters
BASE_URL=https://feedback.yourcompany.com
 
# One reverse proxy in front of the app (see the reverse proxy guide)
TRUSTED_PROXY_HOPS=1

See Environment Variables for all options.

4. Set Up PostgreSQL

Install PostgreSQL 18

Ubuntu/Debian:

# Add PostgreSQL APT repository
sudo sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
 
# Install PostgreSQL 18
sudo apt update
sudo apt install postgresql-18 postgresql-18-pgvector

macOS (Homebrew):

brew install postgresql@18
brew services start postgresql@18
 
# Install pgvector
brew install pgvector

RHEL/CentOS/Fedora:

# Install PostgreSQL 18 repo
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
 
# Install PostgreSQL and extensions
sudo dnf install -y postgresql18-server postgresql18-contrib pgvector_18

Create Database and User

# Switch to postgres user
sudo -u postgres psql
-- Create user
CREATE USER quackback WITH PASSWORD 'your_secure_password';
 
-- Create database
CREATE DATABASE quackback OWNER quackback;
 
-- Connect to database
\c quackback
 
-- Enable required extensions (Quackback also tries this on startup)
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pg_trgm;
 
-- Grant permissions
GRANT ALL PRIVILEGES ON DATABASE quackback TO quackback;
GRANT ALL ON SCHEMA public TO quackback;

5. Run Migrations

bun run db:migrate

This creates all required tables and indexes. Before it changes anything, the migrator checks the PostgreSQL version, the extensions, and the database user's privileges, and stops with a clear message if something is missing.

6. Build the Application

bun run build

This creates an optimized production build in apps/web/.output/.

7. Start the Server

bun run --cwd apps/web start

The server starts on port 3000 by default.

Process Management

For production, use a process manager to keep Quackback running and automatically restart on failures.

Create /etc/systemd/system/quackback.service:

[Unit]
Description=Quackback Feedback Platform
After=network.target postgresql.service
Requires=postgresql.service
 
[Service]
Type=simple
User=quackback
Group=quackback
WorkingDirectory=/opt/quackback
Environment=NODE_ENV=production
EnvironmentFile=/opt/quackback/.env
ExecStart=/home/quackback/.bun/bin/bun run --cwd apps/web start
Restart=always
RestartSec=10
 
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/quackback
 
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=quackback
 
[Install]
WantedBy=multi-user.target

Enable and start:

# Reload systemd
sudo systemctl daemon-reload
 
# Enable on boot
sudo systemctl enable quackback
 
# Start service
sudo systemctl start quackback
 
# Check status
sudo systemctl status quackback
 
# View logs
journalctl -u quackback -f

One instance handles everything by default (QUACKBACK_ROLE=all, the default when the variable is unset). To scale HTTP and background processing separately, add a second systemd unit with Environment=QUACKBACK_ROLE=worker (and set the first unit's QUACKBACK_ROLE=web). See Scale with multiple replicas.

PM2 (Alternative)

# Install PM2
bun install -g pm2
 
# Create ecosystem file
cat > ecosystem.config.js << 'EOF'
module.exports = {
  apps: [{
    name: 'quackback',
    cwd: '/opt/quackback/apps/web',
    script: '.output/server/index.mjs',
    interpreter: 'bun',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    instances: 1,
    autorestart: true,
    watch: false,
    max_memory_restart: '1G'
  }]
}
EOF
 
# Start with PM2
pm2 start ecosystem.config.js
 
# Save configuration
pm2 save
 
# Enable startup script
pm2 startup

Directory Structure

Recommended production layout:

/opt/quackback/
├── .env                    # Environment configuration
├── apps/
│   └── web/
│       └── .output/        # Built application
├── packages/               # Internal packages
├── node_modules/           # Dependencies
├── package.json
└── bun.lock

Security Considerations

File Permissions

# Create dedicated user
sudo useradd -r -s /bin/false quackback
 
# Set ownership
sudo chown -R quackback:quackback /opt/quackback
 
# Restrict .env file
sudo chmod 600 /opt/quackback/.env

Firewall

# UFW example
sudo ufw allow 22/tcp      # SSH
sudo ufw allow 80/tcp      # HTTP (for redirect)
sudo ufw allow 443/tcp     # HTTPS
sudo ufw enable

Do NOT expose port 3000 directly. Use a reverse proxy.

Update Quackback

Upgrading from 0.13? Read Upgrade from 0.13 to 0.14 first. It has one-time steps.

If you are using Docker, migrations run automatically on container startup. This manual migration step is only needed for non-Docker installations.

1. Stop the Service

sudo systemctl stop quackback

2. Backup Database

pg_dump -Fc quackback > quackback_backup_$(date +%Y%m%d).dump

3. Pull Updates

cd /opt/quackback
git pull origin main

4. Install Dependencies

bun install

5. Run Migrations

bun run db:migrate

6. Rebuild

bun run build

7. Restart Service

sudo systemctl start quackback

Update Script

Save this script as /opt/quackback/update.sh to automate the update process.

#!/bin/bash
set -e
 
cd /opt/quackback
 
echo "Stopping service..."
sudo systemctl stop quackback
 
echo "Creating backup..."
pg_dump -Fc quackback > /var/backups/quackback/quackback_$(date +%Y%m%d_%H%M%S).dump
 
echo "Pulling updates..."
git pull origin main
 
echo "Installing dependencies..."
bun install
 
echo "Running migrations..."
bun run db:migrate
 
echo "Building..."
bun run build
 
echo "Starting service..."
sudo systemctl start quackback
 
echo "Update complete!"

Health Checks

Application Health

# Liveness: the process is up
curl http://localhost:3000/api/health/live
 
# Readiness: database, migrations, and background workers
curl http://localhost:3000/api/health/ready

Database Connection

psql $DATABASE_URL -c "SELECT 1"

Service Status

sudo systemctl status quackback

Troubleshooting

Port Already in Use

# Find what's using port 3000
sudo lsof -i :3000
 
# Kill the process or change PORT in .env

Database Connection Failed

Check connection string format:

postgresql://user:password@host:port/database

Test connection:

psql "postgresql://quackback:password@localhost:5432/quackback" -c "SELECT 1"

Permission Denied

Ensure the quackback user owns all files:

sudo chown -R quackback:quackback /opt/quackback

Build Fails

Clear cache and reinstall:

rm -rf node_modules
rm -rf apps/web/.output
bun install
bun run build

Migrations Fail

Check database user permissions:

GRANT ALL PRIVILEGES ON DATABASE quackback TO quackback;
GRANT ALL ON SCHEMA public TO quackback;

Next Steps