Skip to content

Deploying Funkwhale

Introduction

Funkwhale is a self-hosted, open-source music server and federated audio platform that lets you stream, share, and discover music across the Fediverse. Built with Python and Django, Funkwhale provides robust features including audio library management, podcast hosting, federation with other instances, user playlists, and ActivityPub support. This comprehensive guide walks you through deploying Funkwhale on Klutch.sh using Docker, providing a scalable and production-ready music streaming solution.

Whether you’re building a personal music library, hosting podcasts, or creating a community audio platform, deploying Funkwhale on Klutch.sh gives you the infrastructure and reliability needed for modern audio streaming. This guide covers everything from basic setup to production configurations, including Docker deployment, persistent storage, database setup, environment variables, and security best practices.


Prerequisites

Before deploying Funkwhale, ensure you have:

  • A Klutch.sh account
  • A GitHub repository for your Funkwhale deployment
  • Basic knowledge of Docker and PostgreSQL
  • (Recommended) A PostgreSQL database for production use
  • (Optional) A Redis instance for caching and background tasks

Understanding Funkwhale Architecture

Funkwhale consists of several key components:

  • API Server: Django-based REST API that handles all application logic (default port: 5000)
  • PostgreSQL Database: Stores metadata, user data, and application state
  • Redis: Provides caching and message brokering for Celery background tasks
  • Media Storage: File system or object storage for audio files, album art, and user uploads
  • Celery Workers: Process background tasks like audio imports and transcoding

For Klutch.sh deployments, we’ll focus on containerizing the API server while connecting to managed database services.


Creating Your Dockerfile

Klutch.sh automatically detects a Dockerfile in your repository root and uses it for deployment. Here’s a production-ready Dockerfile for Funkwhale:

Basic Dockerfile

FROM funkwhale/funkwhale:latest
# Expose the API port
EXPOSE 5000
# The official image includes necessary entrypoints
CMD ["./docker-entrypoint.sh"]

This basic Dockerfile uses the official Funkwhale image which includes all dependencies pre-configured.

Production Dockerfile with Customizations

For production deployments with additional features:

FROM funkwhale/funkwhale:1.4.0
# Install additional system dependencies
RUN apt-get update && apt-get install -y \
ffmpeg \
curl \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Create directories for persistent data
RUN mkdir -p /srv/funkwhale/data/media \
/srv/funkwhale/data/music \
/srv/funkwhale/data/staticfiles && \
chown -R funkwhale:funkwhale /srv/funkwhale/data
# Expose API port
EXPOSE 5000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost:5000/ || exit 1
CMD ["./docker-entrypoint.sh"]

This production Dockerfile:

  • Pins to a specific version for reproducibility
  • Installs ffmpeg for audio processing
  • Creates persistent data directories
  • Sets proper file permissions
  • Includes health checks for monitoring

Configuring Persistent Storage

Funkwhale requires persistent volumes to store user uploads, music files, and static assets. In the Klutch.sh dashboard, configure the following volumes:

Required Volumes

    1. Media Storage - User uploads, album art, and processed audio:

      • Mount Path: /srv/funkwhale/data/media
      • Recommended Size: 50GB (adjust based on expected library size)
    2. Music Library - Imported music collection:

      • Mount Path: /srv/funkwhale/data/music
      • Recommended Size: Based on your music collection
    3. Static Files - Django static assets and frontend files:

      • Mount Path: /srv/funkwhale/data/staticfiles
      • Recommended Size: 5GB

Important: Without persistent volumes, all user uploads and imported music will be lost when the container restarts.


Database Configuration

Funkwhale requires PostgreSQL as its primary database. You have two options:

Option A: Managed PostgreSQL Service

Use an external managed PostgreSQL service (recommended):

    1. Provision a PostgreSQL 12+ database from your provider
    2. Create the Funkwhale database:
      CREATE DATABASE funkwhale WITH ENCODING 'UTF8';
    3. Create a dedicated user:
      CREATE USER funkwhale_user WITH PASSWORD 'secure_password_here';
      GRANT ALL PRIVILEGES ON DATABASE funkwhale TO funkwhale_user;

Option B: PostgreSQL on Klutch.sh

Deploy PostgreSQL as a separate application on Klutch.sh and connect via internal networking.


Environment Variables

Configure these environment variables in the Klutch.sh dashboard. Mark sensitive values as secrets to prevent logging.

Essential Variables

Terminal window
# Django Configuration
DJANGO_SECRET_KEY=your-random-secret-key-min-50-chars
DJANGO_ALLOWED_HOSTS=example-app.klutch.sh,*.klutch.sh
FUNKWHALE_HOSTNAME=example-app.klutch.sh
FUNKWHALE_PROTOCOL=https
# Database Configuration
DATABASE_URL=postgresql://funkwhale_user:password@postgres-host:5432/funkwhale
# Redis Configuration (if using)
REDIS_URL=redis://redis-host:6379/0
CELERY_BROKER_URL=redis://redis-host:6379/1
# Storage Paths
MEDIA_ROOT=/srv/funkwhale/data/media
MUSIC_DIRECTORY_PATH=/srv/funkwhale/data/music
STATIC_ROOT=/srv/funkwhale/data/staticfiles

Optional Variables

Terminal window
# Email Configuration
EMAIL_CONFIG=smtp+ssl://user:password@smtp.example.com:465
# S3-Compatible Object Storage (alternative to local storage)
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_STORAGE_BUCKET_NAME=funkwhale-media
AWS_S3_ENDPOINT_URL=https://s3.example.com
# Federation
FEDERATION_ENABLED=true
FEDERATION_COLLECTION_PAGE_SIZE=50
# Security
CSRF_TRUSTED_ORIGINS=https://example-app.klutch.sh

Nixpacks Customization

If you need to customize the build or start command, use Nixpacks environment variables:

Terminal window
# Custom start command
NIXPACKS_START_CMD=./docker-entrypoint.sh
# Custom build command
NIXPACKS_BUILD_CMD=python manage.py collectstatic --noinput

Deploying to Klutch.sh

Follow these steps to deploy Funkwhale:

    1. Prepare Your Repository

      • Create a GitHub repository for your Funkwhale deployment
      • Add your Dockerfile to the repository root
      • Commit and push your changes
    2. Create Application

      • Navigate to klutch.sh/app
      • Click “Create New App”
      • Connect your GitHub repository
    3. Configure Network Settings

      • Select HTTP as the traffic type
      • Set internal port to 5000 (Funkwhale’s default API port)
    4. Add Persistent Volumes

      • Add volumes for media, music, and static files as described above
      • Specify mount path and size for each volume
    5. Set Environment Variables

      • Add all required environment variables from the section above
      • Mark passwords and keys as secrets
      • Ensure FUNKWHALE_HOSTNAME matches your app URL
    6. Deploy

      • Click “Deploy” to start the build process
      • Klutch.sh automatically detects your Dockerfile and builds the image
      • Monitor build logs for any errors
    7. Initialize Database

      • Once deployed, run migrations via container console:
        Terminal window
        python manage.py migrate
      • Create superuser account:
        Terminal window
        python manage.py createsuperuser
    8. Access Your Instance

      • Open https://example-app.klutch.sh in your browser
      • Log in with your superuser credentials
      • Complete the initial setup wizard

Post-Deployment Configuration

Importing Your Music Library

    1. Upload music files to the /srv/funkwhale/data/music volume
    2. Import files via the container console:
      Terminal window
      python manage.py import_files /srv/funkwhale/data/music --in-place --async
    3. Monitor import progress in the Funkwhale admin interface

Enabling Federation

If you want to federate with other Funkwhale instances:

    1. Set FEDERATION_ENABLED=true in environment variables
    2. Configure your instance domain in admin panel
    3. Enable ActivityPub federation under Settings → Federation
    4. Add trusted instances to your allowlist

User Registration Settings

    1. Navigate to Settings → Instance in admin panel
    2. Configure registration policy (open, approval-based, or invite-only)
    3. Set upload quotas per user
    4. Configure moderation settings

Custom Domain Setup

To use a custom domain:

    1. In Klutch.sh dashboard, go to your app’s domain settings
    2. Add your custom domain (e.g., music.yourdomain.com)
    3. Update DNS records:
      • Add CNAME record pointing to your Klutch.sh app URL
      • Or add A record to the provided IP address
    4. Update environment variables:
      • FUNKWHALE_HOSTNAME=music.yourdomain.com
      • DJANGO_ALLOWED_HOSTS=music.yourdomain.com
      • CSRF_TRUSTED_ORIGINS=https://music.yourdomain.com
    5. Redeploy the application

Klutch.sh automatically provisions TLS certificates for custom domains.


Backup and Disaster Recovery

Database Backups

Regular database backups are critical:

Terminal window
# Create backup
pg_dump -h postgres-host -U funkwhale_user -d funkwhale > backup-$(date +%Y%m%d).sql
# Restore backup
psql -h postgres-host -U funkwhale_user -d funkwhale < backup-20240101.sql

Media Files Backup

  • Use cloud provider snapshots for persistent volumes
  • Or sync to object storage:
    Terminal window
    rclone sync /srv/funkwhale/data/media s3:bucket/funkwhale-backup/

Automated Backup Strategy

    1. Schedule daily database dumps
    2. Sync media files to object storage weekly
    3. Keep 30 days of backups
    4. Test restore procedures monthly

Performance Optimization

Database Optimization

    1. Use connection pooling (PgBouncer)
    2. Run VACUUM ANALYZE weekly
    3. Monitor slow queries and add indexes

Redis Caching

Configure Redis for improved performance:

Terminal window
REDIS_MAX_MEMORY=2gb
CACHE_URL=redis://redis-host:6379/2

CDN for Media Delivery

    1. Configure S3-compatible storage backend
    2. Enable CDN (CloudFront, CloudFlare, etc.)
    3. Set AWS_S3_CUSTOM_DOMAIN to CDN URL

Security Best Practices

Application Security

    1. Keep Funkwhale Updated

      • Monitor release notes
      • Test updates in staging first
      • Apply security patches promptly
    2. Strong Secrets

      • Use cryptographically random values for DJANGO_SECRET_KEY
      • Generate with: openssl rand -base64 50
      • Rotate secrets periodically
    3. Database Security

      • Use strong passwords
      • Restrict database access by IP
      • Enable SSL/TLS for connections
    4. User Permissions

      • Use approval-based registration for new instances
      • Set reasonable upload quotas
      • Enable moderation tools

Network Security

  • Keep DJANGO_ALLOWED_HOSTS restrictive
  • Use HTTPS only (enforced by Klutch.sh)
  • Configure proper CORS settings
  • Implement rate limiting for API endpoints

Troubleshooting

App Won’t Start

Symptoms: Container crashes after deployment

Solutions:

    1. Check logs in Klutch.sh dashboard
    2. Verify all environment variables are set
    3. Test database connectivity:
      Terminal window
      psql $DATABASE_URL -c "SELECT 1"
    4. Check volume permissions

Database Connection Errors

Symptoms: “could not connect to server” errors

Solutions:

    1. Verify DATABASE_URL format is correct
    2. Test connection from container
    3. Check PostgreSQL allows connections from Klutch.sh
    4. Verify user permissions

Audio Files Won’t Play

Symptoms: Files upload but streaming fails

Solutions:

    1. Verify ffmpeg is installed in container
    2. Check media file permissions
    3. Ensure MEDIA_ROOT volume is writable
    4. Review logs for transcoding errors

Scaling Your Instance

Horizontal Scaling

    1. Deploy separate Celery worker containers
    2. Use Redis for task queue
    3. Deploy multiple API containers with load balancing
    4. Use shared storage for media files

Vertical Scaling

  • Increase CPU for better transcoding performance
  • Add RAM for caching and Django performance
  • Expand storage volumes as library grows

Advanced Configuration

External Storage

Configure S3-compatible storage:

Terminal window
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_STORAGE_BUCKET_NAME=funkwhale-media
AWS_S3_REGION_NAME=us-east-1
DEFAULT_FILE_STORAGE=storages.backends.s3boto3.S3Boto3Storage

Custom Branding

    1. Add custom CSS in admin panel
    2. Upload custom logos
    3. Configure instance description
    4. Set custom colors and themes

LDAP Authentication

Terminal window
LDAP_ENABLED=true
LDAP_SERVER_URI=ldap://ldap.example.com
LDAP_BIND_DN=cn=admin,dc=example,dc=com
LDAP_BIND_PASSWORD=password
LDAP_USER_SEARCH_BASE_DN=ou=users,dc=example,dc=com

Resources

Official Documentation

Klutch.sh Documentation

Community


Conclusion

Deploying Funkwhale on Klutch.sh provides a powerful, scalable solution for self-hosted music streaming. With Docker containerization, persistent storage, and managed infrastructure, you can focus on building your music library and community rather than managing servers. Whether you’re running a personal music server or a federated audio platform, Klutch.sh delivers the performance and reliability needed for production workloads.

For additional support, refer to the Funkwhale community forums and Klutch.sh documentation. Happy streaming!