Skip to main content

Self-Hosting Guide: Deploy Dub for URL Management

·OSSAlt Team
duburl-shortenerself-hostingdockerguide

Self-Hosting Guide: Deploy Dub for URL Management

Dub is the open source Bitly alternative — short links, QR codes, analytics, and team workspaces. Self-hosting gives you unlimited links, unlimited clicks, custom domains, and full data ownership.

Requirements

  • VPS with 2 GB RAM minimum
  • Docker and Docker Compose
  • Two domain names: one for the app (e.g., links.yourdomain.com) and one for short links (e.g., go.yourdomain.com)
  • 10+ GB disk

Step 1: Clone and Configure

git clone https://github.com/dubinc/dub.git
cd dub

# Copy environment file
cp .env.example .env

Step 2: Configure Environment

Edit .env:

# App
NEXTAUTH_SECRET=your-random-secret-32-chars
NEXTAUTH_URL=https://links.yourdomain.com

# Database
DATABASE_URL=postgresql://dub:your-strong-password@db:5432/dub

# Redis
UPSTASH_REDIS_REST_URL=http://redis:8079
UPSTASH_REDIS_REST_TOKEN=your-redis-token

# Short link domain
NEXT_PUBLIC_APP_DOMAIN=links.yourdomain.com
SHORT_DOMAIN=go.yourdomain.com

# Storage (for QR codes, OG images)
STORAGE_ACCESS_KEY=your-s3-key
STORAGE_SECRET_KEY=your-s3-secret
STORAGE_ENDPOINT=https://s3.yourdomain.com
STORAGE_BUCKET_NAME=dub

# SMTP
SMTP_HOST=smtp.resend.com
SMTP_PORT=587
SMTP_USER=resend
SMTP_PASSWORD=re_your_api_key
EMAIL_FROM=links@yourdomain.com

Generate secrets:

openssl rand -hex 32  # NEXTAUTH_SECRET

Step 3: Docker Compose Setup

# docker-compose.yml
services:
  dub:
    build: .
    container_name: dub
    restart: unless-stopped
    ports:
      - "3000:3000"
    env_file: .env
    depends_on:
      - db
      - redis

  db:
    image: postgres:16-alpine
    container_name: dub-db
    restart: unless-stopped
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=dub
      - POSTGRES_USER=dub
      - POSTGRES_PASSWORD=your-strong-password

  redis:
    image: redis:7-alpine
    container_name: dub-redis
    restart: unless-stopped
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

Step 4: Build and Start

docker compose build
docker compose up -d

Step 5: Reverse Proxy (Caddy)

# /etc/caddy/Caddyfile

# App dashboard
links.yourdomain.com {
    reverse_proxy localhost:3000
}

# Short link domain
go.yourdomain.com {
    reverse_proxy localhost:3000
}
sudo systemctl restart caddy

Step 6: DNS Configuration

links.yourdomain.com  A  your-server-ip
go.yourdomain.com     A  your-server-ip

Step 7: Initial Setup

  1. Open https://links.yourdomain.com
  2. Create your account
  3. Create your first workspace
  4. Add your custom short link domain (go.yourdomain.com)

Via dashboard:

  1. Click Create Link
  2. Enter destination URL
  3. Customize short path (optional)
  4. Add UTM parameters
  5. Generate QR code
  6. Save

Via API:

curl -X POST 'https://links.yourdomain.com/api/links' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  --data '{
    "url": "https://example.com/long-page-url",
    "key": "launch",
    "domain": "go.yourdomain.com"
  }'
# Creates: go.yourdomain.com/launch

Bulk create:

curl -X POST 'https://links.yourdomain.com/api/links/bulk' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  --data '[
    { "url": "https://example.com/page-1", "key": "p1" },
    { "url": "https://example.com/page-2", "key": "p2" },
    { "url": "https://example.com/page-3", "key": "p3" }
  ]'

Step 9: Analytics

Dub tracks for every link:

  • Click count over time
  • Geographic distribution (country, city)
  • Device and browser breakdown
  • Referral sources
  • Top performing links

API analytics:

curl 'https://links.yourdomain.com/api/analytics?domain=go.yourdomain.com&key=launch&interval=30d' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Step 10: Team Workspaces

  1. SettingsTeam → invite members
  2. Assign roles (owner, member)
  3. Team members share links and analytics
  4. Use tags to organize links by campaign

Production Hardening

Backups:

# Database backup (daily cron)
docker exec dub-db pg_dump -U dub dub > /backups/dub-$(date +%Y%m%d).sql

Updates:

cd dub
git pull
docker compose build
docker compose up -d

Monitoring:

  • Monitor short link domain with Uptime Kuma
  • Track redirect latency (should be < 100ms)
  • Set up disk space alerts

Resource Usage

LinksRAMCPUDisk
1-10K1 GB1 core5 GB
10K-100K2 GB2 cores10 GB
100K+4 GB4 cores30 GB

VPS Recommendations

ProviderSpecPrice
Hetzner2 vCPU, 4 GB RAM€4.50/month
DigitalOcean2 vCPU, 2 GB RAM$12/month
Linode1 vCPU, 2 GB RAM$12/month

Compare link management tools on OSSAlt — features, analytics, and pricing side by side.