Kutt logo

Kutt

Free, modern URL shortener with a built-in dashboard

Alternative to: Bitly, TinyURL, Rebrandly


Kutt is a free and open-source URL shortener that lets you create shortened links under your own custom domain, with password-protected and expiring links, and detailed visit statistics. It includes a built-in web dashboard for managing links and accounts, and can be self-hosted with SQLite, PostgreSQL, or MariaDB as the database backend.

Kutt Docker Compose example

Self-host Kutt on your own server, homelab, or VPS starting from this Docker Compose example. It runs Kutt in Docker containers using the official kutt/kutt:latest, postgres:16-alpine, redis:alpine images, with persistent volumes and automatic restarts preconfigured. Review the environment variables and adjust them to your setup, save the file as compose.yml (or docker-compose.yml), and start the stack with docker compose up -d.

services:
  server:
    image: kutt/kutt:latest
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - custom:/kutt/custom
    environment:
      # Display name of the instance, shown in the UI
      SITE_NAME: "Kutt"
      # Domain used to build short links, shown to users (host or host:port)
      DEFAULT_DOMAIN: "localhost:3000"
      # Random string used to sign JWT authentication tokens
      JWT_SECRET: "changeme"
      # Database client — pg selects PostgreSQL
      DB_CLIENT: "pg"
      # PostgreSQL host (service name on the compose network)
      DB_HOST: "postgres"
      # PostgreSQL port
      DB_PORT: "5432"
      # PostgreSQL database name
      DB_NAME: "kutt"
      # PostgreSQL user
      DB_USER: "kutt"
      # PostgreSQL password
      DB_PASSWORD: "changeme"
      # Enable Redis for caching and sessions
      REDIS_ENABLED: "true"
      # Redis host (service name on the compose network)
      REDIS_HOST: "redis"
      # Redis port
      REDIS_PORT: "6379"
      # Disable open self-registration of new accounts
      DISALLOW_REGISTRATION: "true"
      # Disable anonymous (not-logged-in) link creation
      DISALLOW_ANONYMOUS_LINKS: "true"
      # Enable outbound email (verification, password reset, reports)
      MAIL_ENABLED: "false"
      # SMTP server host
      MAIL_HOST: ""
      # SMTP server port
      MAIL_PORT: "587"
      # Use TLS/SSL for the SMTP connection
      MAIL_SECURE: "true"
      # SMTP username
      MAIL_USER: ""
      # From address for outgoing email, e.g. "Kutt <support@example.com>"
      MAIL_FROM: ""
      # SMTP password
      MAIL_PASSWORD: ""
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: "kutt"
      POSTGRES_USER: "kutt"
      POSTGRES_PASSWORD: "changeme"
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "kutt"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

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

volumes:
  db_data:
  custom:
  redis_data:

Values set to changeme are required — replace them with your own values before starting Kutt.

Prefer a managed setup? WinterFlow installs, configures, and updates Kutt for you using this same Docker Compose configuration.