Skip to content

Deploying Chhoto URL

Chhoto URL is a lightweight, open-source URL shortening service that enables users to create short, memorable links from long URLs. It provides features like custom aliases, QR code generation, link analytics, expiration dates, and password protection, making it ideal for marketers, developers, and organizations that need a self-hosted alternative to commercial URL shortening services. Chhoto URL gives you complete control over your links without relying on third-party services.

This guide will walk you through deploying Chhoto URL on Klutch.sh, a modern cloud platform that simplifies containerized application deployment. By the end of this guide, you’ll have a fully functional URL shortening service ready for use.

Why Deploy Chhoto URL on Klutch.sh?

Klutch.sh provides an excellent platform for hosting Chhoto URL:

  • Docker-native deployment - Klutch.sh automatically detects and deploys Dockerized applications
  • Fast and reliable - Serve short URL redirects with minimal latency
  • Custom domains - Use your own domain for branded short links
  • Environment configuration - Manage secrets and configuration through the dashboard
  • Data persistence - Reliable storage for URL mappings and analytics
  • Scalability - Easily scale resources as your link volume grows

Prerequisites

Before deploying Chhoto URL on Klutch.sh, you’ll need:

  • A Klutch.sh account (sign up for free)
  • Access to the Klutch.sh dashboard
  • A GitHub repository to store your Chhoto URL deployment configuration
  • A custom domain (optional but recommended for branded short links)
  • Basic understanding of Docker and containerization

Deployment Steps

  1. Create a Dockerfile

    Create a Dockerfile in the root of your repository to containerize Chhoto URL:

    FROM node:20-alpine
    # Install system dependencies
    RUN apk add --no-cache \
    build-base \
    python3 \
    git \
    curl
    # Set working directory
    WORKDIR /app
    # Clone Chhoto URL repository
    RUN git clone https://github.com/shayneobrien/chhoto-url.git . && \
    git checkout main
    # Install dependencies
    RUN npm install
    # Build the application
    RUN npm run build || true
    # Create necessary directories
    RUN mkdir -p /app/data /app/logs
    # Expose port
    EXPOSE 3000
    # Health check
    HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD node -e "require('http').get('http://localhost:3000/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})" || exit 1
    # Start the application
    CMD ["npm", "start"]
  2. Create Environment Configuration File

    Create a .env.example file to document required environment variables:

    # Chhoto URL Environment Configuration
    # Application Settings
    NODE_ENV=production
    PORT=3000
    HOST=0.0.0.0
    # Database Configuration
    DATABASE_URL=postgresql://chottourl:chottopass@localhost:5432/chottourl
    DB_HOST=db
    DB_PORT=5432
    DB_NAME=chottourl
    DB_USER=chottourl
    DB_PASSWORD=secure_password_change_in_production
    # Redis Configuration (for caching)
    REDIS_URL=redis://redis:6379
    REDIS_DB=0
    # Application Base URL
    BASE_URL=https://example-app.klutch.sh
    SHORT_LINK_PREFIX=s
    # Security
    APP_SECRET=your-app-secret-change-in-production
    JWT_SECRET=your-jwt-secret-change-in-production
    # Link Settings
    DEFAULT_EXPIRATION_DAYS=365
    MAX_EXPIRATION_DAYS=3650
    ALLOW_CUSTOM_ALIASES=true
    ENABLE_QR_CODES=true
    ENABLE_LINK_PREVIEW=true
    # File Upload Configuration
    MAX_FILE_SIZE=10485760
    UPLOAD_DIR=/app/data/uploads
    # Email Configuration (Optional)
    SMTP_HOST=smtp.gmail.com
    SMTP_PORT=587
    SMTP_USER=your-email@gmail.com
    SMTP_PASSWORD=your-app-password
    SMTP_FROM=noreply@example-app.klutch.sh
    # Authentication
    ENABLE_USER_REGISTRATION=true
    REQUIRE_EMAIL_VERIFICATION=false
    # API Configuration
    API_ENABLED=true
    API_RATE_LIMIT=100
    CORS_ORIGIN=https://example-app.klutch.sh
    # Admin Settings
    ADMIN_EMAIL=admin@example.com
    ADMIN_PASSWORD=change-me-in-production
    # Analytics
    ENABLE_ANALYTICS=true
    TRACK_IP_ADDRESS=false
    # Logging
    LOG_LEVEL=info
    LOG_DIR=/app/logs
    # Feature Flags
    ENABLE_API_KEYS=true
    ENABLE_BULK_SHORTENING=false
    ENABLE_LINK_EXPIRATION=true
    ENABLE_LINK_CLICKS_LIMIT=false
  3. Create Application Configuration File

    Create a config.js file for application-specific settings:

    module.exports = {
    app: {
    name: 'Chhoto URL',
    version: '1.0.0',
    environment: process.env.NODE_ENV || 'production',
    port: process.env.PORT || 3000,
    host: process.env.HOST || '0.0.0.0',
    baseUrl: process.env.BASE_URL || 'http://localhost:3000',
    shortLinkPrefix: process.env.SHORT_LINK_PREFIX || 's'
    },
    database: {
    url: process.env.DATABASE_URL,
    host: process.env.DB_HOST,
    port: parseInt(process.env.DB_PORT) || 5432,
    name: process.env.DB_NAME,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    pool: {
    min: 2,
    max: 10,
    idleTimeoutMillis: 30000,
    connectionTimeoutMillis: 2000
    }
    },
    redis: {
    url: process.env.REDIS_URL,
    db: parseInt(process.env.REDIS_DB) || 0,
    retryStrategy: (times) => Math.min(times * 50, 2000),
    maxRetriesPerRequest: null
    },
    security: {
    appSecret: process.env.APP_SECRET,
    jwtSecret: process.env.JWT_SECRET,
    tokenExpiration: '7d'
    },
    links: {
    defaultExpirationDays: parseInt(process.env.DEFAULT_EXPIRATION_DAYS) || 365,
    maxExpirationDays: parseInt(process.env.MAX_EXPIRATION_DAYS) || 3650,
    allowCustomAliases: process.env.ALLOW_CUSTOM_ALIASES === 'true',
    enableQrCodes: process.env.ENABLE_QR_CODES === 'true',
    enableLinkPreview: process.env.ENABLE_LINK_PREVIEW === 'true'
    },
    fileUpload: {
    maxFileSize: parseInt(process.env.MAX_FILE_SIZE) || 10485760,
    uploadDir: process.env.UPLOAD_DIR || '/app/data/uploads',
    allowedMimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp']
    },
    cors: {
    origin: process.env.CORS_ORIGIN || 'http://localhost:3000'
    },
    auth: {
    enableUserRegistration: process.env.ENABLE_USER_REGISTRATION === 'true',
    requireEmailVerification: process.env.REQUIRE_EMAIL_VERIFICATION === 'true'
    },
    api: {
    enabled: process.env.API_ENABLED === 'true',
    rateLimit: parseInt(process.env.API_RATE_LIMIT) || 100
    },
    email: {
    host: process.env.SMTP_HOST,
    port: parseInt(process.env.SMTP_PORT) || 587,
    user: process.env.SMTP_USER,
    password: process.env.SMTP_PASSWORD,
    from: process.env.SMTP_FROM || 'noreply@chhoto.local'
    },
    logging: {
    level: process.env.LOG_LEVEL || 'info',
    dir: process.env.LOG_DIR || '/app/logs'
    }
    };
  4. Create Database Initialization Script

    Create an init-db.sh file to set up the PostgreSQL database:

    #!/bin/bash
    set -e
    echo "Initializing Chhoto URL database..."
    # Wait for PostgreSQL to be ready
    until PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -U "$DB_USER" -d "postgres" -c "\q"; do
    echo 'Waiting for postgres...'
    sleep 1
    done
    echo "PostgreSQL is ready!"
    # Create database if it doesn't exist
    PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -U "$DB_USER" -d "postgres" << EOF
    CREATE DATABASE $DB_NAME;
    EOF
    echo "Database created!"
    # Run migrations
    echo "Running database migrations..."
    npm run migrate
    # Seed initial data
    echo "Seeding initial data..."
    npm run seed || true
    echo "Database initialization complete!"

    Make it executable:

    Terminal window
    chmod +x init-db.sh
  5. Create Docker Compose for Local Development

    Create a docker-compose.yml file for local development and testing (not used for Klutch.sh deployment):

    version: '3.8'
    services:
    chottourl:
    build: .
    container_name: chottourl-dev
    ports:
    - "3000:3000"
    environment:
    - NODE_ENV=development
    - DATABASE_URL=postgresql://chottourl:chottopass@db:5432/chottourl
    - DB_HOST=db
    - DB_PORT=5432
    - DB_NAME=chottourl
    - DB_USER=chottourl
    - DB_PASSWORD=chottopass
    - REDIS_URL=redis://redis:6379
    - BASE_URL=http://localhost:3000
    - APP_SECRET=dev-secret-change-in-production
    - JWT_SECRET=dev-jwt-secret-change-in-production
    - ENABLE_USER_REGISTRATION=true
    - ENABLE_ANALYTICS=true
    depends_on:
    - db
    - redis
    volumes:
    - ./data:/app/data
    - ./src:/app/src
    networks:
    - chottourl-network
    db:
    image: postgres:16-alpine
    container_name: chottourl-db
    environment:
    - POSTGRES_USER=chottourl
    - POSTGRES_PASSWORD=chottopass
    - POSTGRES_DB=chottourl
    volumes:
    - chottourl_db_data:/var/lib/postgresql/data
    networks:
    - chottourl-network
    healthcheck:
    test: ["CMD-SHELL", "pg_isready -U chottourl"]
    interval: 10s
    timeout: 5s
    retries: 5
    redis:
    image: redis:7-alpine
    container_name: chottourl-redis
    networks:
    - chottourl-network
    healthcheck:
    test: ["CMD", "redis-cli", "ping"]
    interval: 10s
    timeout: 5s
    retries: 5
    volumes:
    chottourl_db_data:
    networks:
    chottourl-network:
    driver: bridge
  6. Create .gitignore File

    Create a .gitignore file to exclude sensitive data from version control:

    # Environment files
    .env
    .env.local
    .env.*.local
    # Node.js
    node_modules/
    npm-debug.log
    yarn-error.log
    package-lock.json
    yarn.lock
    # Build artifacts
    dist/
    build/
    .next/
    out/
    # Data and uploads
    data/
    uploads/
    public/uploads/
    # Logs
    logs/
    *.log
    # IDE
    .vscode/
    .idea/
    *.swp
    *.swo
    *~
    .DS_Store
    # Cache
    .cache/
    .turbo/
    # Database
    *.sqlite
    *.sqlite3
  7. Push Configuration to GitHub

    Push your repository to GitHub with all configuration files:

    Terminal window
    git add Dockerfile .env.example config.js init-db.sh \
    docker-compose.yml .gitignore
    git commit -m "Initial Chhoto URL deployment configuration for Klutch.sh"
    git push origin main
  8. Deploy on Klutch.sh

    1. Navigate to klutch.sh/app and log in to your dashboard
    2. Click Create New App
    3. Connect your GitHub repository containing the Chhoto URL deployment files (the Dockerfile will be automatically detected)
    4. Configure your application settings:
      • Set your preferred app name
      • Review the detected Dockerfile configuration
      • Select a region for deployment
    5. Click Deploy to start the deployment process
    6. Monitor the deployment progress in the dashboard
    7. Wait for the deployment to complete and your app to become active
  9. Configure Environment Variables

    1. In your app dashboard, navigate to Environment Variables section
    2. Add all required variables from your .env.example file:
      • DATABASE_URL: Your PostgreSQL connection string
      • DB_HOST: Your PostgreSQL hostname
      • DB_NAME: Database name (chottourl)
      • DB_USER: Database user
      • DB_PASSWORD: Secure database password
      • REDIS_URL: Your Redis connection string
      • BASE_URL: Set to https://example-app.klutch.sh (or your custom domain)
      • APP_SECRET: Generate a secure secret with openssl rand -base64 32
      • JWT_SECRET: Generate a secure JWT secret with openssl rand -base64 32
      • ADMIN_EMAIL and ADMIN_PASSWORD: Administrator credentials
    3. Click Save to apply the environment variables
    4. Your application will automatically restart with the new configuration
  10. Configure Traffic Routes

    1. In your app dashboard, navigate to Traffic settings
    2. Select HTTP as the traffic type
    3. Set the internal port to 3000 (Chhoto URL Node.js server default)
    4. Configure any custom domain settings if you have a domain
    5. Save your traffic configuration
  11. Attach Persistent Volumes

    Chhoto URL requires persistent storage for uploaded files, data, and logs.

    1. In your app dashboard, navigate to Volumes settings
    2. Click Add Volume to create storage for application data:
      • Enter mount path: /app/data
      • Set volume size to 20GB (adjust based on expected link volume and analytics data)
      • Click Attach to create and mount the volume
    3. Click Add Volume again for application logs:
      • Enter mount path: /app/logs
      • Set volume size to 5GB
      • Click Attach to create and mount the volume

    Your Chhoto URL application will now be accessible at your configured domain or at example-app.klutch.sh.

Initial Setup and Configuration

After deploying Chhoto URL on Klutch.sh, complete the initial setup to prepare your URL shortening service.

Access Your Chhoto URL Instance

  1. Navigate to https://example-app.klutch.sh in your web browser
  2. You’ll see the Chhoto URL home page
  3. Click Admin or navigate to /admin for administrator access
  4. Log in with the admin credentials you set in environment variables
  5. Complete the initial setup wizard

Configure Your Chhoto URL Instance

Once logged in, configure these essential settings:

Site Settings:

  • Set your site name and branding
  • Configure the short link base URL (your domain)
  • Set link expiration defaults
  • Configure analytics tracking

Link Settings:

  • Enable/disable custom aliases
  • Set maximum alias length
  • Configure default expiration period
  • Enable/disable QR code generation
  • Set link preview options

User Management:

  • Create additional administrator accounts if needed
  • Configure user registration settings
  • Set email verification requirements
  • Configure user roles and permissions

API Configuration:

  • Enable API access for developers
  • Generate API keys for integrations
  • Set API rate limits
  • Configure API documentation access

Create Administrator Account

  1. Access the admin panel at /admin
  2. Use the credentials configured in environment variables
  3. Change the default password immediately
  4. Enable two-factor authentication for security
  5. Configure additional admin users as needed

To control link creation:

  1. In admin panel, navigate to SettingsLinks
  2. Configure custom alias allowance
  3. Set expiration date defaults and limits
  4. Enable/disable QR code generation
  5. Configure link preview settings

URL Shortening Best Practices

  • Regularly review and remove expired links
  • Monitor link creation patterns for abuse
  • Implement link validity checks
  • Archive analytics data periodically
  • Set up automated cleanup policies

Security Considerations

  • Enable password protection for sensitive links
  • Use custom aliases carefully to prevent conflicts
  • Monitor for phishing or malicious content
  • Implement link scanning with external services
  • Review access logs for suspicious activity

Performance Optimization

  • Use caching for frequently accessed redirects
  • Monitor database query performance
  • Optimize analytics queries
  • Enable Redis caching for redirect lookups
  • Configure CDN for faster redirects (optional)

Analytics and Monitoring

  • Track link click statistics regularly
  • Monitor referrer sources and devices
  • Set up alerts for unusual activity
  • Review user behavior patterns
  • Generate reports on popular links

Deployment Best Practices

Security Measures

  • Keep Chhoto URL updated to the latest version
  • Use strong, unique passwords for all accounts
  • Enable two-factor authentication for administrators
  • Configure firewall rules to restrict access if needed
  • Use HTTPS for all communications (automatic with Klutch.sh)
  • Regularly review user access permissions
  • Implement rate limiting on link creation

Monitoring and Maintenance

  • Monitor disk usage for data and logs
  • Set up alerts for deployment failures
  • Review logs regularly for errors or security issues
  • Schedule maintenance windows for updates
  • Test backup restoration procedures monthly
  • Monitor database performance

Scaling Considerations

As your URL shortening service grows:

  • Increase volume sizes proactively before running out of space
  • Monitor database performance and optimize queries
  • Implement link analytics archiving
  • Consider read replicas for analytics queries
  • Archive old link data for compliance

Accessing Chhoto URL

Once deployment is complete and configured:

  1. Users access Chhoto URL at your configured domain or example-app.klutch.sh
  2. Users can create short links from long URLs
  3. Users can customize aliases for branded links
  4. Users can generate QR codes for short links
  5. Users can view click analytics for their links
  6. Admin panel provides full service management

Troubleshooting Deployment Issues

Application Won’t Start

Check the following:

  • Verify all required environment variables are set
  • Ensure database connection string is correct
  • Check that Redis is accessible
  • Review application logs in the dashboard
  • Verify Node.js version compatibility

Database Connection Errors

Steps to resolve:

  • Verify DATABASE_URL environment variable format
  • Ensure database is running and accessible
  • Check database user credentials
  • Verify network connectivity between services
  • Test database connectivity from application logs

Possible solutions:

  • Verify application has write permissions to data directory
  • Check available disk space on volumes
  • Ensure database is not at capacity
  • Verify BASE_URL is correctly configured
  • Review link creation logs for errors

Performance Issues

Optimization steps:

  • Increase application memory allocation
  • Enable Redis caching for redirects
  • Optimize database queries
  • Configure query result caching
  • Monitor and archive old analytics data

Advanced Configuration

Environment Variables for Customization

You can customize Chhoto URL behavior with these environment variables:

Terminal window
# Link Configuration
SHORT_LINK_PREFIX=s
ALLOW_CUSTOM_ALIASES=true
MAX_ALIAS_LENGTH=30
DEFAULT_EXPIRATION_DAYS=365
# Database Connection Pool
DB_POOL_MIN=2
DB_POOL_MAX=10
DB_IDLE_TIMEOUT=30000
# Analytics
TRACK_IP_ADDRESS=false
TRACK_USER_AGENT=true
ENABLE_GEOGRAPHIC_TRACKING=false
# Feature Flags
ENABLE_QR_CODES=true
ENABLE_LINK_PREVIEW=true
ENABLE_API_KEYS=true
ENABLE_BULK_SHORTENING=false
# Cache Configuration
CACHE_TTL=3600
REDIS_MAX_RETRIES=3
# Security
ENFORCE_HTTPS=true
SECURE_COOKIES=true
RATE_LIMIT_WINDOW=900000
RATE_LIMIT_MAX_REQUESTS=100

Custom Domain Setup

To use a custom domain with your Chhoto URL instance:

  1. In your Klutch.sh dashboard, navigate to Domains
  2. Add your custom domain
  3. Follow the DNS configuration instructions
  4. Update your environment variables with the new domain:
    • BASE_URL=https://your-domain.com
  5. Save and redeploy your application

API Integration

To enable API access for programmatic link creation:

  1. In Chhoto URL admin panel, navigate to API Settings
  2. Generate API keys for your applications
  3. Configure API rate limits
  4. Document API endpoints for developers
  5. Set up API usage monitoring

Additional Resources

Learn more about Chhoto URL and Klutch.sh:

Conclusion

You now have a fully functional Chhoto URL instance running on Klutch.sh! Your self-hosted URL shortening service is ready for users to create and manage short links.

With the robust infrastructure provided by Klutch.sh and the powerful features of Chhoto URL, you can create a branded URL shortening solution with complete control. Remember to:

  • Keep your application updated with the latest Chhoto URL releases
  • Monitor link creation and usage patterns
  • Maintain regular backups of your database
  • Follow security best practices for link handling
  • Scale your infrastructure as your link volume grows

For additional support or questions about deploying Chhoto URL on Klutch.sh, refer to the documentation and community resources linked above.