Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Funkwhale Ubuntu
GUIDEInstall Guides

How to Install Funkwhale on Ubuntu 24.04 — Self-Hosted Music Streaming

20 min read

How to Install Funkwhale on Ubuntu 24.04 — Self-Hosted Music Streaming on Your VPS

Funkwhale turns your VPS into a private music streaming service that you actually own. You import your own FLAC and MP3 library, subscribe to any podcast RSS feed, and federate with the rest of the Fediverse over ActivityPub — the same protocol that powers Mastodon and PeerTube. No algorithm decides what you hear next, no label can revoke a track you paid for, and no provider can change the terms of service on a library you already built. This guide walks you through a full Funkwhale install on Ubuntu 24.04 using Docker Compose, from a fresh SSH session to a federated, TLS-secured instance playing your first album.

Need the hardware? Funkwhale's Docker stack runs comfortably on our Professional VPS plan with 6 vCPU and 12 GB RAM. The 200 GB NVMe gives you room for a real music collection before you ever need object storage.

Table of Contents

  • What is Funkwhale?
  • Why Self-Host Music Streaming Instead of Using Spotify?
  • Prerequisites
  • Step 1: Update the System and Create a Service User
  • Step 2: Install Docker Engine and the Compose Plugin
  • Step 3: Download the Funkwhale Compose Bundle
  • Step 4: Configure the .env File
  • Step 5: Prepare the Music Import Directory
  • Step 6: Launch the Stack
  • Step 7: Create the Superuser
  • Step 8: Install the Nginx Reverse Proxy
  • Step 9: Obtain a TLS Certificate
  • Step 10: Enable Federation via ActivityPub
  • Step 11: Subscribe to Podcasts
  • Importing Your Music Library
  • Backup and Maintenance
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is Funkwhale?

    Funkwhale is an open-source, community-driven audio platform that combines three things most commercial services keep separate: a personal music library, a podcast player, and a federated social layer. It is built in Python (Django) on the backend, Vue.js on the frontend, and uses PostgreSQL, Redis, and Celery for persistence and background work. Federation is handled through ActivityPub, so a track or a podcast you publish on your instance can be discovered and followed by users on any other Funkwhale, Mastodon, or compatible Fediverse server.

    The project started in 2017 as a GPL-licensed alternative to Grooveshark and has grown into a mature platform with a mobile app, a Subsonic-compatible API (so clients like Ultrasonic, DSub, and Symfonium work out of the box), and a clean web player. Documentation lives at docs.funkwhale.audio, and the reference Docker Compose deployment is maintained as part of every release.

    Typical use cases for a self-hosted Funkwhale instance include archiving a personal collection of FLAC rips that you never want a streaming service to lose, running a small community radio where multiple users share channels and playlists, hosting your own podcast with an RSS feed that listeners can subscribe to from any podcatcher, or bridging a DJ or label catalogue into the Fediverse so new releases surface in Mastodon timelines.

    Why Self-Host Music Streaming Instead of Using Spotify?

    Commercial music streaming is cheap and convenient, but the tradeoffs are structural, not accidental. Running Funkwhale on your own VPS fixes several of them at once.

    • You own the library — Every track you upload stays on disk at a path you control. If Funkwhale's maintainers disappear tomorrow, your files are still there and playable with VLC, mpv, or any other audio tool.
    • No DRM, no regional blocking — Files are stored as plain FLAC, MP3, Ogg Vorbis, or Opus. There is no encryption layer, no license server, and no country gate between you and the audio.
    • Tracks cannot be removed remotely — On commercial platforms, albums disappear when licensing deals expire or when artists are delisted. On your Funkwhale instance, a track is gone only when you delete the file.
    • Predictable flat-rate cost — A VPS plus bandwidth costs the same whether you stream one hour a month or ten hours a day. There is no per-stream payout model quietly reshaping what gets recommended.
    • Privacy by default — Your listening history, likes, and playlists live in a PostgreSQL database on a server you own. No advertiser buys it, no recommendation engine trains on it without your consent.
    • Podcasts in the same player — Funkwhale fetches podcast RSS feeds directly, so your music and your shows live in one library with one set of playlists, offline downloads, and bookmarks.
    • Federation is optional and granular — You can keep the instance fully private, open it to a handful of friends, or federate with the broader Fediverse. The choice is per-library, not platform-wide.

    Cost Comparison: Self-Hosted Funkwhale vs. Commercial Streaming

    ScenarioSpotify FamilyApple MusicSelf-Hosted Funkwhale (VPS)
    Monthly cost~EUR 17.99~EUR 16.99EUR 19.99 (flat)
    Max users per account66Unlimited
    Tracks you can lose to licensing changesAll of themAll of themNone
    DRM on downloadsYesYesNo
    Podcasts includedYesYesYes
    Custom uploads of personal FLACsNoLimited (Match)Yes, unlimited
    Fediverse integrationNoNoYes (ActivityPub)
    Mobile clientProprietaryProprietaryOfficial app + any Subsonic client
    For a household with a real music collection and more than a couple of listeners, Funkwhale on a Professional VPS pays for itself on the feature set alone, not just the pricing.

    Prerequisites

    Before you start, make sure you have:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access.
    • A domain name (for example music.example.com) with an A record pointing at your VPS's public IPv4 address and, optionally, a AAAA record for IPv6.
    • SSH access to the server.
    • At least 8 GB of RAM (12 GB recommended once transcoding and federation are active).
    • At least 100 GB of disk for the system, Postgres, and your music. Plan more if you have a large FLAC collection.
    • Ports 80 and 443 open in your provider's firewall.
    Recommended Plan: Professional
    >
    For a comfortable Funkwhale instance that can federate, transcode on the fly, and serve multiple concurrent listeners without stuttering, we recommend the Professional VPS plan:
    >
    - 6 vCPU cores
    - 12 GB RAM
    - 200 GB NVMe SSD
    - Unmetered bandwidth
    - EUR 19.99/month
    >
    The 200 GB NVMe holds roughly 4,000 CD-quality FLAC albums or 40,000 well-encoded MP3s before you need to attach object storage.

    Connect to your server:

    bash
    ssh root@your-server-ip

    Step 1: Update the System and Create a Service User

    Start with a clean, patched base:

    bash
    apt update && apt upgrade -y
    apt install -y ca-certificates curl gnupg lsb-release ufw

    Create a dedicated non-root user that will own the Funkwhale files and run the Compose stack:

    bash
    adduser --disabled-password --gecos "" funkwhale
    usermod -aG sudo funkwhale

    Enable a basic firewall. Funkwhale only needs SSH, HTTP, and HTTPS exposed to the public:

    bash
    ufw allow OpenSSH
    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw --force enable

    Switch to the service user for the rest of the install:

    bash
    su - funkwhale

    Step 2: Install Docker Engine and the Compose Plugin

    Funkwhale's reference deployment assumes Docker Engine with the Compose v2 plugin. Install the official Docker Debian repository (Ubuntu 24.04 Noble is supported):

    bash
    sudo install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg

    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu noble stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    Add the funkwhale user to the docker group so you do not need sudo for every compose command:

    bash
    sudo usermod -aG docker funkwhale
    exit

    Log back in to apply the new group membership:

    bash
    ssh funkwhale@your-server-ip
    docker version
    docker compose version

    You should see client and server versions printed without any permission errors.

    Step 3: Download the Funkwhale Compose Bundle

    Create the instance directory and pull the current release's deployment artifacts. Check docs.funkwhale.audio for the latest stable version tag before running this — substitute it into the FUNKWHALE_VERSION variable below.

    bash
    export FUNKWHALE_VERSION="1.4.0"
    mkdir -p ~/funkwhale && cd ~/funkwhale

    curl -L -o docker-compose.yml \ "https://dev.funkwhale.audio/funkwhale/funkwhale/-/raw/${FUNKWHALE_VERSION}/deploy/docker-compose.yml"

    curl -L -o .env.example \ "https://dev.funkwhale.audio/funkwhale/funkwhale/-/raw/${FUNKWHALE_VERSION}/deploy/env.prod.sample"

    curl -L -o nginx.template \ "https://dev.funkwhale.audio/funkwhale/funkwhale/-/raw/${FUNKWHALE_VERSION}/deploy/docker.nginx.template"

    curl -L -o nginx.proxy.conf \ "https://dev.funkwhale.audio/funkwhale/funkwhale/-/raw/${FUNKWHALE_VERSION}/deploy/docker.proxy.conf"

    cp .env.example .env

    The docker-compose.yml defines six services that work together:

    • postgres — PostgreSQL 15, holds users, tracks metadata, federation state, and listening history.
    • redis — Cache, session store, and Celery broker.
    • api — The Django application server (runs on gunicorn) that serves the REST and ActivityPub APIs.
    • celeryworker — Background worker for imports, transcoding jobs, and federation deliveries.
    • celerybeat — Scheduler that periodically fetches podcast feeds and runs cleanup tasks.
    • front — Nginx container serving the compiled Vue.js frontend and proxying the API.

    Step 4: Configure the .env File

    Open the .env file and edit the important values:

    bash
    nano .env

    Set the hostname, generate a strong DJANGO_SECRET_KEY, and pick a database password. A one-liner to generate the secret key:

    bash
    openssl rand -base64 45

    Then set these keys in .env:

    ini
    # The public hostname users will type in their browser
    FUNKWHALE_HOSTNAME=music.example.com
    FUNKWHALE_PROTOCOL=https

    Django

    DJANGO_SECRET_KEY=<paste the openssl output here> DJANGO_ALLOWED_HOSTS=music.example.com DJANGO_SETTINGS_MODULE=config.settings.production

    Database

    DATABASE_URL=postgresql://funkwhale@postgres:5432/funkwhale POSTGRES_USER=funkwhale POSTGRES_PASSWORD=<strong password> POSTGRES_DB=funkwhale

    Cache

    CACHE_URL=redis://redis:6379/0 CELERY_BROKER_URL=redis://redis:6379/0

    Email (adjust or leave the default console backend for now)

    EMAIL_CONFIG=consolemail:// [email protected]

    Paths

    MEDIA_ROOT=/srv/funkwhale/data/media STATIC_ROOT=/srv/funkwhale/data/static MUSIC_DIRECTORY_PATH=/music MUSIC_DIRECTORY_SERVE_PATH=/srv/funkwhale/data/music

    Reverse proxy

    FUNKWHALE_WEB_WORKERS=4 NGINX_MAX_BODY_SIZE=100M

    Federation

    FEDERATION_ENABLED=True

    A couple of notes on the trickier values:

    • FUNKWHALE_HOSTNAME becomes part of federated actor URLs and is effectively permanent. Choose it carefully — changing it after you start federating breaks every remote follow you have.
    • MUSIC_DIRECTORY_PATH is the path inside the api container where your music lives. MUSIC_DIRECTORY_SERVE_PATH is the path on the host. The volume mount in docker-compose.yml bridges the two.
    • FEDERATION_ENABLED=True turns on ActivityPub. Keep it off initially if you only want a private instance for yourself.
    Save and exit the editor.

    Step 5: Prepare the Music Import Directory

    Create the host directories the containers will mount:

    bash
    sudo mkdir -p /srv/funkwhale/data/{media,static,music}
    sudo chown -R 1000:1000 /srv/funkwhale

    Place your music under /srv/funkwhale/data/music/, organised however you like — Funkwhale reads ID3 tags and Vorbis comments rather than relying on folder structure, but a typical layout of Artist/Album/Track.flac works well. Supported formats include FLAC, MP3, Ogg Vorbis, Opus, AAC, and WAV.

    You can symlink an existing collection in:

    bash
    sudo ln -s /mnt/nas/flac-library/* /srv/funkwhale/data/music/

    For object storage (S3, Backblaze B2, etc.), see the S3_* variables in .env.example and the object storage guide in the official docs.

    Step 6: Launch the Stack

    Pull the images and bring everything up in the background:

    bash
    cd ~/funkwhale
    docker compose pull
    docker compose up -d

    First boot takes a minute or two. Watch the logs until the Django migrations and static asset collection finish:

    bash
    docker compose logs -f api

    You are ready to move on when you see Listening at: http://0.0.0.0:5000 from gunicorn and no red ERROR lines.

    Check that all six containers are running:

    bash
    docker compose ps

    Expected output:

    text
    NAME                       IMAGE                                          STATUS
    funkwhale-postgres-1       postgres:15-alpine                             Up (healthy)
    funkwhale-redis-1          redis:7-alpine                                 Up
    funkwhale-api-1            funkwhale/funkwhale:1.4.0                      Up
    funkwhale-celeryworker-1   funkwhale/funkwhale:1.4.0                      Up
    funkwhale-celerybeat-1     funkwhale/funkwhale:1.4.0                      Up
    funkwhale-front-1          funkwhale/funkwhale:1.4.0                      Up

    Step 7: Create the Superuser

    Create the first admin account by running manage.py createsuperuser inside the api container:

    bash
    docker compose run --rm api python manage.py createsuperuser

    You will be prompted for a username, email address, and password:

    text
    Username: admin
    Email address: [email protected]
    Password:
    Password (again):
    Superuser created successfully.

    This account can log in at https://music.example.com once the reverse proxy is up, and can access the Django admin at /api/admin/ for low-level database operations.

    Step 8: Install the Nginx Reverse Proxy

    Funkwhale ships with a tested Nginx configuration. You can either run Nginx inside Docker (included in the Compose file as the front container, which already listens on port 80 of the host) or use a host-level Nginx, which is simpler for adding Let's Encrypt.

    Install host Nginx:

    bash
    sudo apt install -y nginx

    Render the Funkwhale Nginx template with your hostname baked in:

    bash
    sudo mkdir -p /etc/nginx/funkwhale
    sudo cp ~/funkwhale/nginx.template /etc/nginx/funkwhale/funkwhale.template
    sudo cp ~/funkwhale/nginx.proxy.conf /etc/nginx/funkwhale/funkwhale_proxy.conf

    sudo tee /etc/nginx/sites-available/funkwhale > /dev/null <<'EOF' upstream funkwhale-api { server 127.0.0.1:5000; }

    server { listen 80; listen [::]:80; server_name music.example.com;

    location /.well-known/acme-challenge/ { root /var/www/html; }

    location / { return 301 https://$host$request_uri; } }

    server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name music.example.com;

    ssl_certificate /etc/letsencrypt/live/music.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/music.example.com/privkey.pem;

    # Provided by Funkwhale — handles /api, /federation, /media, static, and the SPA include /etc/nginx/funkwhale/funkwhale.template;

    set $funkwhale_url http://funkwhale-api; client_max_body_size 100M; } EOF

    sudo ln -s /etc/nginx/sites-available/funkwhale /etc/nginx/sites-enabled/

    Edit the Compose file so the front and api containers only listen on loopback — the host Nginx fronts them. Find the ports: block on the front service and change 80:80 to 127.0.0.1:5000:80, then:

    bash
    docker compose up -d

    Step 9: Obtain a TLS Certificate

    Install Certbot and request a Let's Encrypt certificate:

    bash
    sudo apt install -y certbot python3-certbot-nginx
    sudo certbot --nginx -d music.example.com --redirect --agree-tos -m [email protected] --non-interactive

    Certbot edits the Nginx config in place, installs the certificate, and sets up the automatic renewal timer. Confirm the timer is active:

    bash
    systemctl status certbot.timer

    Reload Nginx and hit your instance:

    bash
    sudo nginx -t && sudo systemctl reload nginx
    curl -I https://music.example.com

    A 200 OK response with a valid strict-transport-security header means you are live. Open the URL in a browser and log in with the superuser credentials from Step 7.

    Step 10: Enable Federation via ActivityPub

    With FEDERATION_ENABLED=True in .env, your instance already publishes a /.well-known/webfinger endpoint and serves ActivityPub actors under /federation/actors/<user>. To verify federation is reachable from the outside:

    bash
    curl "https://music.example.com/.well-known/nodeinfo"
    curl "https://music.example.com/.well-known/webfinger?resource=acct:[email protected]"

    Both requests should return JSON documents describing your server and the admin actor.

    Inside the Funkwhale web UI, open Settings → Federation and:

  • Add a description and icon so your instance is recognisable in other servers' follow lists.
  • Go to Channels and follow a few remote channels — try [email protected] for the flagship community instance.
  • Announce your instance on the Fediverse: a Mastodon post mentioning #Funkwhale and your hostname usually gets you discovered within a day.
  • Federation traffic happens over standard HTTPS on port 443, so there is nothing extra to open in the firewall. Posts, likes, and library announcements are signed with per-actor RSA keys that Funkwhale generates automatically.

    If you also run a Mastodon instance, users there can follow your Funkwhale channels directly. The same is true for PeerTube video channels — the Fediverse treats all three the same way.

    Step 11: Subscribe to Podcasts

    Funkwhale treats podcasts as a specialised kind of channel. To subscribe:

  • Click the search icon in the top bar and paste a podcast RSS URL (for example https://feeds.simplecast.com/54nAGcIl for The Changelog).
  • Funkwhale fetches the feed, imports every episode's metadata, and starts pulling audio files in the background via Celery.
  • Click Subscribe on the resulting channel page.
  • From now on, celerybeat refreshes every subscribed feed on a schedule (default: every 30 minutes). New episodes appear in your home timeline and are auto-downloaded if you enable that in Settings → Subscriptions.

    You can also use the Subsonic API endpoint (/api/subsonic/rest/) to connect any Subsonic-compatible podcatcher — Symfonium, DSub, play:Sub, Ultrasonic — using your Funkwhale username and a generated Subsonic password from Settings → Subsonic API.

    Importing Your Music Library

    With music placed under /srv/funkwhale/data/music/, trigger an in-place import that reads the files without copying them:

    bash
    docker compose run --rm api python manage.py import_files \
      "$(python3 -c 'print(open(\"/app/config/settings/common.py\").read())' 2>/dev/null; echo /music)" \
      "/music//.flac" "/music//.mp3" "/music//.ogg" "/music//.opus" \
      --recursive --noinput --in-place --library-id <LIBRARY_UUID>

    Get the <LIBRARY_UUID> by creating a new library first via the web UI under Library → + New library, then copying the UUID from its URL.

    For smaller one-off imports, the web UI's drag-and-drop uploader is often easier — it kicks off the same Celery pipeline behind the scenes.

    Backup and Maintenance

    Back up three things regularly: the Postgres database, the .env file (it contains your DJANGO_SECRET_KEY), and the media directory if you rely on it for uploads.

    A nightly database dump:

    bash
    docker compose exec -T postgres pg_dump -U funkwhale funkwhale \
      | gzip > ~/backups/funkwhale-$(date +%F).sql.gz

    Upgrade to a new Funkwhale release by editing the image tag in docker-compose.yml, then:

    bash
    docker compose pull
    docker compose run --rm api python manage.py migrate --noinput
    docker compose up -d

    Always read the release notes at docs.funkwhale.audio before a major version bump — migrations can take several minutes on large databases.

    Troubleshooting

    ProblemCauseSolution
    502 Bad Gateway from Nginxapi container not running or still migratingdocker compose logs api — wait for gunicorn to bind, or restart the stack
    DisallowedHost error in logsDJANGO_ALLOWED_HOSTS missing your hostnameAdd it to .env, then docker compose up -d
    Files uploaded but no audio on playbackHost path not mounted into api or permissions wrongls -l /srv/funkwhale/data/music — must be owned by UID 1000, readable by others
    Federation requests return 401HTTP signature mismatch — usually a clock skewsudo timedatectl set-ntp true and timedatectl status to confirm sync
    Celery tasks stuck in PENDINGRedis unreachable or worker crasheddocker compose logs celeryworker redis, then docker compose restart celeryworker
    Podcast feed fails to updateFeed server blocks Funkwhale's User-AgentSet RSS_FEED_REFRESH_DELAY higher and check the feed in a browser
    Music imports silently skip filesMissing or malformed ID3 tagsTag files with MusicBrainz Picard before import
    Stream logs live from a specific service:

    bash
    docker compose logs -f celeryworker

    FAQ

    Can I keep my Funkwhale instance fully private and skip federation entirely?

    Yes. Set FEDERATION_ENABLED=False in .env and restart the stack. Your instance will still serve the web UI, the Subsonic API, and the podcast player, but it will not publish ActivityPub actors or accept follows from remote servers. You can toggle federation on later without losing any data — Funkwhale generates actor keys on first use.

    How much disk space do I need for a serious music collection?

    A rough rule: 500 MB per hour of lossless FLAC at 16-bit/44.1 kHz, or about 80 MB per hour at 192 kbps MP3. A 200 GB Professional plan holds roughly 400 hours of FLAC or 2,500 hours of MP3 before you need to add a block storage volume or enable S3. Funkwhale's in-place import means you can mount a separate larger disk at /srv/funkwhale/data/music without moving files around.

    How does Funkwhale compare to Navidrome for a pure personal library?

    Navidrome is a lighter, single-binary server focused entirely on the Subsonic API. If all you want is to stream your own FLACs to a Subsonic client on your phone, Navidrome is simpler to run and uses less RAM. Funkwhale is the better choice when you also want podcasts in the same player, a full web UI for guests, federation with Mastodon and PeerTube, or multi-user channels with per-library permissions. Both can coexist on the same VPS if you have the RAM.

    What clients can I use with Funkwhale?

    The official Funkwhale Android and iOS apps work over the native API. Any Subsonic-compatible client also works via /api/subsonic/rest/ — the popular choices are Symfonium and Substreamer on Android, play:Sub on iOS, and Sublime Music on Linux desktop. For browser use, the bundled Vue.js web UI is fully responsive and works well on mobile.

    Does Funkwhale transcode on the fly for slower connections?

    Yes. When a client requests a track in a format the server supports for transcoding (controlled by LISTEN_TRANSCODE settings), the api container uses ffmpeg via Celery to produce the requested format — typically to Ogg Vorbis or MP3 at a lower bitrate for mobile data. Transcoded chunks are cached, so subsequent listens do not re-run ffmpeg. Transcoding is the main reason to run 6 vCPU: a single CPU core can transcode roughly two streams in parallel without audible glitches.

    Can multiple users upload to the same library?

    Libraries in Funkwhale have granular permissions: each one is owned by a user and can be shared with specific collaborators, opened to all registered users, or published for public and federated access. A common pattern for households is one "Main Library" owned by the admin with upload rights for family members, plus private per-user libraries for personal collections. Permissions are set per-library in Library → settings, not globally.

    Is Funkwhale GDPR-compliant out of the box?

    Funkwhale's design minimises personal data collection — there are no analytics beacons, no third-party trackers, and no ad networks. As the operator, you are the data controller for anything your users upload and listen to, so you are responsible for your own privacy policy and for honouring deletion requests. The built-in Settings → Your data panel lets every user export their data as JSON and delete their account, which satisfies GDPR Article 17 (right to erasure) and Article 20 (right to data portability) by default.

    Next Steps

    With Funkwhale running, there are several directions to take the setup further:

    • Run a companion Mastodon instance so you can post updates about new channels and new imports to the same Fediverse audience that follows your Funkwhale library.
    • Pair it with PeerTube if you also publish music videos or concert recordings. PeerTube federates natively with Funkwhale over ActivityPub, and a single follow from a Mastodon user covers both services.
    • Add Navidrome alongside Funkwhale if you want an ultra-lightweight Subsonic-only endpoint for your own phone while keeping Funkwhale for federation and podcasts.
    • Move media to object storage — the official docs at docs.funkwhale.audio cover S3, Backblaze B2, and Wasabi configuration via the S3_* env vars. This is the standard approach once your library exceeds the VPS's local NVMe.
    • Set up off-site backups — pipe your nightly pg_dump plus a rsync of /srv/funkwhale/data/media to a second VPS or a B2 bucket. Funkwhale data is all recoverable from those two sources.

    Want Funkwhale Without the Install?
    >
    Our Professional VPS plan gives you the hardware for a smooth Funkwhale instance — 6 vCPU, 12 GB RAM, 200 GB NVMe, unmetered bandwidth — for EUR 19.99/month. Deploy Ubuntu 24.04 in under two minutes and walk through this guide on a fresh server in well under an hour.
    >
    Launch Your Funkwhale VPS Now

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket