Author | Nejat Hakan |
nejat.hakan@outlook.de | |
PayPal Me | https://paypal.me/nejathakan |
Music Streaming Server Funkwhale
Introduction to Funkwhale
Welcome to the world of self-hosted music streaming with Funkwhale! In an era where centralized streaming services dominate, Funkwhale offers a refreshing alternative: an open-source, self-hosted, and federated audio streaming platform. Think of it as your personal Spotify or Apple Music, but entirely under your control, respecting your privacy, and capable of connecting with a wider community.
What is Funkwhale?
Funkwhale is a free, open-source software project that allows you to host and stream your personal music collection. It provides a clean web interface accessible from any device with a browser, as well as compatibility with clients supporting the Subsonic API (like DSub, Substreamer, Audinaut, etc.). Key features include:
- Your Music, Your Server: You upload your music library to your own server, maintaining full ownership and control over your files.
- Web-Based Access: Stream your music from anywhere using a modern web browser.
- Subsonic API Support: Use a variety of third-party mobile and desktop apps to connect to your Funkwhale instance.
- Metadata Management: Funkwhale attempts to automatically fetch metadata (artist info, album art, etc.) for your music.
- Playlists & Favorites: Organize your music with playlists and mark your favorite tracks.
- Federation (ActivityPub): This is a standout feature. Funkwhale instances can connect using the ActivityPub protocol (the same protocol powering Mastodon and other Fediverse services). This allows users on different Funkwhale servers (called "pods") to share music libraries (based on permissions), discover new music, and follow each other's listening activity, creating a decentralized social music network.
Why Self-Host Funkwhale?
- Control: You decide what music is available, who can access it, and how the server operates. No arbitrary removals or region restrictions.
- Privacy: Your listening habits are not tracked by large corporations for advertising or other purposes. The data stays on your server.
- Ownership: You use your own music files. No reliance on a service's catalog. Ideal for extensive collections of ripped CDs, purchased downloads, or independent artists.
- Cost: While server hosting has costs, there are no recurring subscription fees for the software itself.
- Federation: Participate in a larger, interconnected network of music lovers, discovering music beyond your own library.
- Open Source: Freedom to inspect, modify, and contribute to the software. Benefit from a community-driven development model.
Core Concepts
- Instance/Pod: A single installation of Funkwhale running on a server.
- Library: Your collection of music tracks uploaded to the instance.
- User: An account on a specific Funkwhale instance.
- Federation: The ability for different Funkwhale instances to communicate and share information using ActivityPub.
- ActivityPub: A standardized W3C protocol for decentralized social networking.
This guide will walk you through setting up and managing your own Funkwhale instance, starting with the basics and progressing to more advanced configurations. We'll use Docker for ease of deployment in the initial stages, as it simplifies dependency management significantly.
1. Preparing Your Server (Basic)
Before installing Funkwhale, you need a server environment ready to host it. This section covers the fundamental requirements and initial server setup, focusing on Linux, the most common platform for self-hosting. We recommend using a recent LTS (Long-Term Support) version of Debian or Ubuntu for stability and community support.
Server Requirements (Minimum Recommendations)
While Funkwhale can run on very low-spec hardware (like a Raspberry Pi), performance, especially with larger libraries or multiple users, will be impacted. For a reasonably smooth experience for personal use or a small group:
- Operating System: A modern Linux distribution (Debian 11/12, Ubuntu 20.04/22.04 LTS recommended).
- CPU: 2 vCPU cores (x86_64 architecture recommended). ARM is possible but might require more troubleshooting.
- RAM: 2 GB minimum, 4 GB+ recommended for better performance, especially during music scanning/importing.
- Disk Space: Enough space for the OS (~10-20GB), Funkwhale's Docker images and database (~5-10GB), plus enough space for your entire music library. Storage needs can grow significantly! Use SSDs for better database and application performance.
- Internet Connection: A stable internet connection with decent upload speed is crucial for streaming music out from your server. A static IP address is highly recommended, especially for federation and reliable external access, though dynamic DNS can be used as an alternative.
Choosing a Hosting Method
- Virtual Private Server (VPS): Renting a server from providers like DigitalOcean, Linode, Hetzner, OVH, etc. Offers good performance, a public IP address, and scalability. This is often the easiest starting point.
- Dedicated Server: Renting a full physical server. More powerful but often more expensive.
- Home Server: Using a spare computer or a device like a Raspberry Pi at home. Requires managing your home network (port forwarding, potentially dynamic DNS) and depends on your home internet's upload speed.
- Cloud Platforms: AWS, Google Cloud, Azure. Can be powerful and flexible but often more complex and potentially expensive if not managed carefully.
For this guide, we'll assume you have access to a server (likely a VPS or a home server) running Debian or Ubuntu with root or sudo privileges.
Initial Server Setup and Security
This is a crucial step. Never run services on an unsecured server.
-
Connect to your Server: Use SSH (Secure Shell) to connect to your server's terminal. Replace
your_server_ip
with your server's actual IP address andyour_username
if you already have a non-root user. If logging in as root initially: -
Update System Packages: Ensure your server's software is up-to-date.
(Note: If logged in as root, you can omitsudo
) -
Create a Non-Root User: Running everything as root is a security risk. Create a dedicated user account for daily operations. Replace
You'll be prompted to set a password and fill in some optional information.newuser
with your desired username. -
Grant Sudo Privileges: Add the new user to the
sudo
group to allow them to perform administrative tasks. -
Log in as the New User: Disconnect from the root session (
From now on, useexit
) and log back in as your new user:sudo
before commands requiring root privileges. -
Basic Firewall Setup (UFW): Uncomplicated Firewall (UFW) is a user-friendly interface for managing
iptables
.- Allow SSH: Crucial so you don't lock yourself out! (Port 22 is default)
- Allow HTTP/HTTPS: We'll need these later for Funkwhale's web interface (Port 80 for HTTP, Port 443 for HTTPS).
- Enable UFW: Confirm with 'y'.
- Check Status: This should show the allowed ports (22, 80, 443) and the default policy (deny incoming, allow outgoing).
Essential Software Installation
We need git
to download the Funkwhale setup files and potentially other tools later.
Your server now has a basic secure foundation. The next step is installing Docker, which will manage the Funkwhale application environment.
Workshop Basic Server Preparation
Goal: Perform the initial secure setup of a fresh Debian/Ubuntu server.
Prerequisites: Access to a new Debian or Ubuntu server instance (VPS or local VM) via SSH, initially as the root
user.
Steps:
-
Connect as Root:
(Enter root password when prompted) -
Update System: Run the update and upgrade commands:
(Wait for the process to complete. This might take a few minutes) -
Create Your User: Choose a username (e.g.,
(Follow prompts to set a strong password and fill optional info)funkadmin
) and create the user: -
Grant Sudo Rights: Add the new user to the
sudo
group: -
Set up UFW Firewall:
- Allow SSH:
- Allow standard web ports:
- Enable the firewall: (Press 'y' and Enter to confirm)
- Verify the rules: (Expected Output: Status: active, with rules allowing 22, 80, 443/tcp)
-
Install Git:
-
Reconnect as New User:
- Disconnect the root session:
- Connect as your newly created user:
(Enter the password you set for
funkadmin
)
-
Test Sudo: Try running a command with
(Enter yoursudo
:funkadmin
password when prompted. The command should execute successfully.)
Outcome: You now have a server with updated packages, a non-root user with sudo
privileges, and a basic firewall configured, ready for the Docker and Funkwhale installation.
2. Installation using Docker (Recommended for Beginners)
Docker provides a containerization platform that simplifies application deployment by packaging an application and its dependencies together. Using Docker and Docker Compose (a tool for defining and running multi-container Docker applications) is the officially recommended and generally easiest way to install and manage Funkwhale. It isolates Funkwhale from your host system and handles complex dependencies automatically.
Understanding Docker and Docker Compose
- Docker: Imagine a lightweight virtual machine (though technically different). A Docker image is a template containing the application code, libraries, and dependencies. A Docker container is a running instance of an image. Docker manages these containers, ensuring they have the resources they need and are isolated from each other and the host OS.
- Docker Compose: Funkwhale isn't just one program; it typically involves a web server (Nginx), the Funkwhale API backend (Python/Django), a database (PostgreSQL), a cache (Redis), and background task workers (Celery). Docker Compose uses a YAML file (
docker-compose.yml
) to define all these services, their configurations, networks, and volumes (for persistent data storage) and allows you to start, stop, and manage them together with simple commands.
Installing Docker and Docker Compose
We'll follow the official Docker installation instructions, as package managers often have outdated versions.
-
Remove Old Versions (if any):
(It's okay if these commands report that none of these packages are installed.) -
Set up Docker's
apt
Repository:(Note: Replace# Add Docker's official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl gnupg -y 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 # Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update
ubuntu
withdebian
in thehttps://download.docker.com/linux/ubuntu
URL if you are using Debian). -
Install Docker Engine, CLI, Containerd, and Compose:
-
Verify Docker Installation: Check that Docker is running:
(Should show 'active (running)') Run the hello-world image: (This will download and run a small test container, printing a confirmation message.) -
(Optional but Recommended) Add User to Docker Group: To avoid typing
Important: You need to log out and log back in for this group change to take effect! Now, reconnect:sudo
for every Docker command, add your user to thedocker
group.ssh your_user@your_server_ip
. Verify you can run Docker commands withoutsudo
: (Should run without permission errors, likely showing an empty list of containers)
Downloading and Configuring Funkwhale
Funkwhale provides a repository containing the necessary docker-compose.yml
file and configuration templates.
-
Clone the Funkwhale Docker Repository: Choose a location to store the Funkwhale configuration. A common practice is
/opt
or your user's home directory.(If you cloned intocd /opt # Or: cd ~ sudo git clone https://dev.funkwhale.audio/funkwhale/funkwhale-docker.git cd funkwhale-docker
/opt
, subsequent commands in this directory might requiresudo
unless you change ownership/permissions. Cloning into~
avoids this.) Let's assume you cloned into/opt/funkwhale-docker
and will usesudo
when needed. -
Copy and Edit the Environment File: Funkwhale uses an
Now, you must edit this file. Use a terminal editor like.env
file to store configuration variables used by Docker Compose.nano
: Crucial Variables to Set:FUNKWHALE_HOSTNAME
: Required. This is the domain name where your Funkwhale instance will be accessible (e.g.,funkwhale.yourdomain.com
). Do not includehttp://
orhttps://
. Even if you don't have a domain yet, set a plausible one you intend to use. Using just an IP address is strongly discouraged and breaks federation. For initial local testing only, you might uselocalhost
, but change it before going live.NGINX_MAX_BODY_SIZE
: Controls the maximum upload size for music files. The default100m
(100 MB) might be too small for high-quality FLAC files. Increase it if needed (e.g.,500m
or1024m
for 1 GB).POSTGRES_PASSWORD
,DJANGO_SECRET_KEY
: Change these from the defaults to strong, unique passwords/keys. You can generate strong random strings using commands likeopenssl rand -base64 32
.FUNKWHALE_API_IP
,FUNKWHALE_FRONTEND_IP
: Defaults (0.0.0.0
) are usually fine, meaning they listen on all network interfaces within the Docker network.- Optional (For Later): Review settings related to email (
SMTP_...
), object storage (AWS_...
), etc., but the defaults are okay for getting started locally.
Save the file and exit
nano
(Ctrl+X, then Y, then Enter).
Running Funkwhale
With Docker installed and the .env
file configured, starting Funkwhale is straightforward.
-
Pull Docker Images: Download all the necessary container images defined in
(This might take some time depending on your internet speed)docker-compose.yml
. -
Start the Containers: This command builds (if necessary), creates, and starts all the services (Nginx, API, database, etc.) in the background (
-d
flag). -
Check Container Status: See if all containers are running and healthy.
You should see several containers (likefunkwhale-docker-api-1
,funkwhale-docker-frontend-1
,funkwhale-docker-nginx-1
,funkwhale-docker-postgres-1
,funkwhale-docker-redis-1
,funkwhale-docker-worker-1
) with aState
ofUp
orrunning
. If any are restarting or exited, check the logs (see next step). -
View Logs (Troubleshooting): If something isn't working, check the combined logs:
Or logs for a specific service (e.g., the API): (Press Ctrl+C to stop following logs)
If all containers are running, Funkwhale should now be accessible, although likely only via HTTP on your server's IP address initially, unless you've already configured DNS and a reverse proxy (covered later). The default setup exposes Funkwhale on port 80.
Workshop Installing Funkwhale with Docker
Goal: Install Docker, Docker Compose, download the Funkwhale configuration, customize it, and launch the Funkwhale containers.
Prerequisites: A server prepared according to Workshop 1, logged in as your non-root sudo
user (e.g., funkadmin
).
Steps:
-
Install Docker and Docker Compose:
- Execute the commands from the "Installing Docker and Docker Compose" section above (Steps 1-4).
- (Remember to adjust the repository URL for Debian if applicable)
- Verify with
sudo systemctl status docker
andsudo docker run hello-world
.
-
Add User to Docker Group (and Re-login):
- Run
sudo usermod -aG docker ${USER}
. - Run
exit
to log out. - Log back in:
ssh funkadmin@your_server_ip
. - Verify permission by running
docker ps
(withoutsudo
). It should execute without error.
- Run
-
Clone Funkwhale Docker Repository:
- Navigate to your chosen directory (e.g.,
/opt
or~
). We'll use/opt
here, requiringsudo
.
- Navigate to your chosen directory (e.g.,
-
Prepare Configuration:
- Copy the sample environment file:
- Edit the
.env
file: - Set
FUNKWHALE_HOSTNAME
: Enter the domain name you plan to use (e.g.,music.mydomain.org
). Crucially, ensure this is set correctly. - Set
NGINX_MAX_BODY_SIZE
: Increase if desired (e.g.,500m
). - Generate and Set Passwords/Keys:
- Open another terminal connected to your server (or use
tmux
/screen
). - Generate a Postgres password:
openssl rand -base64 32
- Generate a Django secret key:
openssl rand -base64 32
- Copy these generated values into the
POSTGRES_PASSWORD
andDJANGO_SECRET_KEY
fields in yournano
editor session.
- Open another terminal connected to your server (or use
- Save and exit
nano
(Ctrl+X, Y, Enter).
-
Pull Docker Images:
(Wait for downloads to complete) -
Launch Funkwhale:
-
Verify Containers:
(Ensure all services show as 'running' or 'Up'. It might take a minute or two for health checks to pass). -
Initial Access Test (Optional, might fail depending on firewall/network): Try accessing Funkwhale in your browser using your server's IP address:
http://your_server_ip
. You might see the Funkwhale setup page or an Nginx welcome page, depending on the exact state. Don't worry if it doesn't fully work yet; we still need DNS and HTTPS.
Outcome: You have successfully downloaded and launched the Funkwhale Docker containers using a customized configuration. The core services are running, ready for initial setup and further configuration (like DNS and HTTPS).
3. Initial Configuration and First Steps
With the Funkwhale containers running, the next step is to perform the initial setup through the web interface or command line, primarily creating your administrator account. Then, we'll explore basic instance settings and upload your first music tracks.
Creating the Administrator Account
Funkwhale needs at least one user with administrative privileges to manage the instance. You can create this user via the command line interface within the API container.
-
Access the API Container: Use
docker compose exec
to run a command inside the runningapi
service container. We'll run themanage
script (Funkwhale's Django management utility) to create a superuser. -
Follow the Prompts: You will be asked for:
- Username: Choose a username for your admin account (e.g.,
admin
, or your preferred username). - Email address: Provide a valid email address.
- Password: Enter and confirm a strong password for this account.
If successful, you'll see a "Superuser created successfully." message.
- Username: Choose a username for your admin account (e.g.,
Accessing the Web Interface
Now that you have an admin account, you can log in.
-
Find Your Access URL:
- If you already set up DNS and a reverse proxy (covered later): Access Funkwhale via the
FUNKWHALE_HOSTNAME
you configured (e.g.,https://funkwhale.yourdomain.com
). - If you haven't set up DNS/HTTPS yet: You might be able to access it via your server's IP address:
http://your_server_ip
. Remember, this is not recommended for long-term use due to security and federation issues. Your browser might also give security warnings.
- If you already set up DNS and a reverse proxy (covered later): Access Funkwhale via the
-
Log In: Navigate to the Funkwhale URL in your web browser. You should see the Funkwhale login page. Enter the username and password you just created for the superuser account.
Exploring Basic Instance Settings
Once logged in as the administrator, you can configure various aspects of your Funkwhale instance.
-
Navigate to Admin Settings: Click your username/avatar in the top-right corner, then select "Administration".
-
Instance Settings: Go to
Settings -> Instance
. Here you can configure:- Instance name: A public name for your Funkwhale pod (e.g., "My Awesome Music Pod").
- Instance description: A brief description displayed publicly.
- Instance short description: A shorter version.
- Contact email: A public contact address for your instance.
- Closed registrations: Check this box if you don't want random users to be able to sign up. You can still invite users manually. For a personal server, enabling this is highly recommended.
- Enable federation: Controls whether your instance participates in the Funkwhale network. Keep it enabled if you want to connect with others.
- Terms of service: Set up terms for your users if applicable.
-
Review Other Sections: Briefly explore other admin sections like
Users
,Federation
,Content
, etc. We'll delve into these in more detail later. For now, ensuring registration is configured (open or closed) according to your preference is the most important step. Remember to Save changes after modifying settings.
Uploading Your First Tracks
Let's add some music! Funkwhale needs music files stored in a specific location that its containers can access. The default Docker setup maps a volume for this purpose.
-
Identify the Music Directory on the Host: The
docker-compose.yml
file defines volumes. Look for thevolumes:
section under theapi
or a dedicatedimporter
service (depending on the Funkwhale version). It usually maps a host directory to/srv/funkwhale/music
inside the container. By default in the officialfunkwhale-docker
setup, it often maps the host directory./data/music
(relative to thefunkwhale-docker
directory) to the container's music path.- Check your
docker-compose.yml
:sudo nano docker-compose.yml
- Find the
volumes:
section for theapi
service. Look for a line like- ./data/music:/srv/funkwhale/music:ro
or similar. The part before the colon is the host path (e.g.,/opt/funkwhale-docker/data/music
), the part after is the container path. The:ro
means read-only for that specific service, but uploads happen via the API which has write access to the underlying volume storage, often managed elsewhere or through different container mounts. The key is finding the persistent storage location for music on your host machine. In recent versions, this is often managed via named Docker volumes (funkwhale_music
), making direct host access slightly trickier without inspecting the volume location.
Let's assume the common
./data/music
relative mapping for simplicity: The music directory on your host server would be/opt/funkwhale-docker/data/music
. - Check your
-
Create the Directory (if it doesn't exist): If you used the default
./data/music
mapping:Note: Finding the correct UID/GID is important. If uploads fail later, permissions are a common culprit.# Navigate to the funkwhale-docker directory cd /opt/funkwhale-docker # Create the music directory sudo mkdir -p data/music # Ensure correct permissions (allow Funkwhale process to read) # Find the UID/GID the Funkwhale container runs as (often 1000:1000 or 991:991) # You can check with: sudo docker compose exec api id # Assuming UID=991, GID=991: sudo chown -R 991:991 data/music # Or more permissively (less secure, for testing): sudo chmod -R 775 data/music
-
Transfer Music Files: Copy some music files (MP3, FLAC, Ogg, etc.) from your computer to this directory on the server. You can use tools like
scp
(Secure Copy) orrsync
.-
Using
scp
(from your local machine): -
Using
rsync
(from your local machine, often preferred for large transfers):Important Note on Trailing Slashes: The presence or absence of a trailing slash# Copy a directory recursively, showing progress: rsync -avz --progress /path/to/your/local/music_folder/ funkadmin@your_server_ip:/opt/funkwhale-docker/data/music/
/
on the source path is significant inrsync
:rsync -a source_dir remote:dest_dir
: Copies thesource_dir
itself intodest_dir
, resulting indest_dir/source_dir
.rsync -a source_dir/ remote:dest_dir
: Copies the contents ofsource_dir
intodest_dir
, resulting indest_dir/file1
,dest_dir/file2
, etc.
-
-
Scan the Library: Funkwhale doesn't automatically detect new files. You need to tell it to scan the music directory.
- Via the Web UI: Log in as admin, go to
Administration -> Libraries
. You should see a default library. Click the "Scan" button (or similar action) associated with it. - Via the Command Line (Recommended for large libraries): This runs the scan in the background and provides more feedback.
(Replace
# Execute the library scan command in the api container sudo docker compose exec api python manage.py import_files --recursive --path /srv/funkwhale/music --library-id 1 --follow-symlinks
/srv/funkwhale/music
if your internal container path is different. Replacelibrary-id 1
if you created a different library, though1
is usually the default.)
The scan might take time depending on the number of files. You can monitor progress via the command line output or sometimes in the web UI's activity feed.
- Via the Web UI: Log in as admin, go to
-
Enjoy Your Music: Once the scan completes, navigate back to the main Funkwhale interface (click the Funkwhale logo or "Home"). You should see your uploaded music appear under "Recently Added" or by browsing your library!
Workshop Initial Setup and Music Upload
Goal: Create the admin user, configure basic instance settings, upload a few sample music tracks, and scan them into the library.
Prerequisites: Funkwhale containers running (Workshop 2 completed). Access to the server terminal. Some music files (e.g., MP3s) on your local computer.
Steps:
-
Create Admin User:
- Navigate to the Funkwhale docker directory:
cd /opt/funkwhale-docker
- Run the
createsuperuser
command: - Follow the prompts to set username (e.g.,
admin
), email, and a strong password.
- Navigate to the Funkwhale docker directory:
-
Access Web UI:
- Open your browser and go to
http://your_server_ip
(or your configured domain if already set up). - Log in with the admin credentials you just created.
- Open your browser and go to
-
Configure Basic Settings:
- Click username -> Administration -> Settings -> Instance.
- Set an Instance name (e.g., "My Test Pod").
- Check the Closed registrations box (recommended for personal use).
- Click Save changes.
-
Prepare Music Directory on Host:
- Assuming the default mapping
./data/music
:
- Assuming the default mapping
-
Upload Music:
- Open a terminal on your local computer.
- Use
scp
orrsync
to upload a few music files or a small folder to the server's music directory. Replace placeholders:(Enter# Example using scp to copy a local folder named 'sample-music' scp -r /path/to/your/local/sample-music funkadmin@your_server_ip:/opt/funkwhale-docker/data/music/
funkadmin
's password when prompted)
-
Scan Library via CLI:
- Go back to your server terminal in the
/opt/funkwhale-docker
directory. - Run the import command (assuming default library ID 1 and container path):
- Wait for the scan to complete. Watch the output for progress or errors.
- Go back to your server terminal in the
-
Verify in Web UI:
- Refresh the Funkwhale web interface in your browser.
- Go to the "Library" or "Home" section.
- You should now see the albums/tracks you uploaded. Try playing one!
Outcome: You have successfully performed the initial Funkwhale setup, configured essential instance settings, uploaded music, and made it available for streaming through the web interface.
4. Understanding the User Interface
Now that you have a running Funkwhale instance with some music in it, let's familiarize ourselves with the web interface from a regular user's perspective (though your admin account works fine). This interface is how you'll primarily interact with your music collection.
Main Navigation Components
The Funkwhale web UI is typically organized with a sidebar (on wider screens) or a bottom navigation bar (on mobile) providing access to the main sections:
- Home: Your landing page. Often shows recently added albums, recently played tracks, and maybe some recommendations or radio suggestions.
- Library: This is the core section for browsing your uploaded music collection. It usually has sub-sections:
- Albums: Browse by album covers and titles.
- Artists: Browse by artist name. Clicking an artist shows their albums and tracks in your library.
- Tracks: A flat list of all individual tracks in your library, sortable by various criteria.
- Genres: Browse music categorized by genre (based on metadata).
- Playlists: View and manage your created playlists. You can create new playlists, add tracks to them, and reorder tracks.
- Favorites: Access tracks, albums, or artists you've marked as favorites (usually by clicking a heart icon ❤️).
- Radios: Funkwhale can generate dynamic "radios" based on your listening history, favorites, or specific artists/genres. This is a great way to discover connections within your library.
- History: Shows your recent listening history.
- Search: A search bar (usually at the top) allows you to quickly find artists, albums, or tracks within your library (and potentially federated content, depending on configuration).
- Administration (Admin Only): The section you previously used for instance configuration, user management, etc. Only visible to admin users.
Playback Controls
Typically located at the bottom of the screen, the playback controls include:
- Play/Pause Button: Controls the current track playback.
- Previous/Next Track Buttons: Navigate within the current play queue or album.
- Timeline/Seek Bar: Shows the current playback position and total duration. You can click or drag to seek within the track.
- Volume Control: Adjust the playback volume.
- Playback Queue: An icon (often looks like a list or stack) that opens the current list of tracks queued for playback. You can view, reorder, or remove tracks from the queue.
- Repeat Mode: Options to repeat the current track, repeat the entire queue, or turn repeat off.
- Shuffle Mode: Toggle shuffling (randomizing the order) of the play queue.
- Cover Art & Track Info: Displays the album art, track title, and artist of the currently playing song.
Key User Actions
- Playing Music:
- Click the play button on an album cover to play the whole album.
- Click the play button next to a specific track to play that track.
- Click the "Add to queue" button (often
+
or similar) to add an album or track to the end of the current playback queue without interrupting the current song.
- Managing Playlists:
- Navigate to the "Playlists" section and click "Create Playlist".
- While browsing, find tracks or albums you want to add, click the options menu (usually
...
), and select "Add to playlist".
- Marking Favorites: Click the heart icon (❤️) next to tracks, albums, or artists.
- Editing Your Profile: Click your username/avatar -> Settings (or Profile). Here you can change your display name, avatar, bio, and potentially manage application passwords (for Subsonic clients) or notification settings.
Understanding the Play Queue
The Play Queue is fundamental to how Funkwhale handles playback. When you choose to play something:
- Direct Play (Album/Track): Clicking play on an album or track typically clears the current queue and replaces it with the selected item(s).
- Add to Queue: Explicitly adding items appends them to the end of the existing queue.
- Radio: Starting a radio generates a dynamic queue based on its criteria.
You can view and manipulate the queue directly to create custom listening sessions on the fly.
Workshop Exploring the Funkwhale UI
Goal: Become comfortable navigating the Funkwhale web interface, playing music, creating a playlist, and marking favorites.
Prerequisites: A running Funkwhale instance with some music uploaded (Workshop 3 completed). Logged into the Funkwhale web UI.
Steps:
-
Explore the Library:
- Click "Library" in the navigation.
- Browse through the "Albums", "Artists", and "Tracks" views. Get a feel for how your music is organized.
- Click on an Artist name. Observe how it displays their albums and tracks.
- Click on an Album cover. View the tracklist for that album.
-
Play Music:
- Go back to the "Albums" view in your Library.
- Hover over an album cover and click the Play icon that appears. Music should start playing, and the playback controls at the bottom should become active.
- Use the playback controls: Pause, play, skip to the next track, go back to the previous track.
- Click on the timeline/seek bar to jump to a different part of the song.
- Adjust the volume.
-
Use the Play Queue:
- While the first album is playing, go back to the Library -> Albums view.
- Find a different album. Hover over it, click the options menu (
...
), and select "Add to queue". - Find a specific track in the "Tracks" view. Click its options menu (
...
) and select "Add to queue". - Click the Play Queue icon in the playback controls (usually near the volume/shuffle/repeat buttons).
- Observe the list of upcoming tracks. You should see the rest of the first album, followed by the second album you added, and then the single track.
- Try dragging tracks within the queue to reorder them.
- Remove a track from the queue using its remove/delete icon.
-
Create a Playlist:
- Click "Playlists" in the navigation.
- Click the "Create Playlist" button (or similar).
- Give your playlist a name (e.g., "My Favorites Mix") and optionally a description. Click "Create".
- Go back to your Library -> Tracks view.
- Find a few tracks you like. For each track, click its options menu (
...
), select "Add to playlist", and choose the "My Favorites Mix" playlist you just created. - Navigate back to the "Playlists" section and click on your new playlist to view its contents.
-
Mark Favorites:
- While browsing your Library (Albums, Artists, or Tracks), find an item you particularly like.
- Click the heart icon (❤️) associated with it. The heart should fill in.
- Mark a few different items (a track, an album, an artist) as favorites.
- Click "Favorites" in the navigation.
- Verify that the items you marked appear in the respective sections (Favorite Tracks, Favorite Albums, Favorite Artists).
-
Use Search:
- Click the Search bar at the top.
- Type the name of an artist or album in your library.
- Review the search results and click one to navigate to it.
Outcome: You should now feel comfortable navigating the main sections of the Funkwhale UI, controlling playback, managing the play queue, creating playlists, and marking your favorite music. This forms the foundation for enjoying your self-hosted music collection.
(Intermediate Sections follow)
5. Domain Name and HTTPS Setup
Running Funkwhale purely via an IP address is insecure, prevents federation from working correctly, and will cause issues with modern browsers. To make your Funkwhale instance truly usable and professional, you need a domain name and HTTPS encryption. This section explains why and guides you through setting it up using Nginx (as included in the default Docker setup) and Let's Encrypt for free SSL/TLS certificates.
Why Domain Names and HTTPS Are Crucial
- Identity & Accessibility: A domain name (e.g.,
music.yourdomain.com
) provides a stable, memorable address for your service, unlike an IP address which might change (especially on home connections). - Federation: Funkwhale's federation relies on unique, stable identifiers tied to domain names. Instances identify each other using addresses like
@user@music.yourdomain.com
. This cannot work reliably with IP addresses. - Security (HTTPS):
- Encryption: HTTPS (HTTP Secure) encrypts the traffic between your users' browsers and your server. This prevents eavesdroppers on the network (e.g., on public Wi-Fi) from seeing login credentials, browsing habits, or the music being streamed.
- Authentication: The SSL/TLS certificate used for HTTPS verifies that the server the user is connecting to is actually the one associated with the domain name, preventing man-in-the-middle attacks.
- Browser Requirements: Modern browsers increasingly flag non-HTTPS sites as insecure and may block features like geolocation or service workers used by web applications. Many Subsonic clients also require HTTPS connections.
- Trust: A padlock icon in the browser bar signals to users that the connection is secure, building trust in your service.
Prerequisites
- Domain Name: You need to register a domain name (e.g.,
yourdomain.com
) from a domain registrar (like Namecheap, GoDaddy, Gandi, Porkbun, etc.). - DNS Configuration: You need access to your domain's DNS settings (usually provided by your registrar or a dedicated DNS service like Cloudflare). You must create a DNS record (typically an
A
record) pointing your desired hostname (e.g.,music.yourdomain.com
or justfunkwhale.yourdomain.com
) to your server's public IP address.- A Record: Maps a hostname directly to an IPv4 address.
- AAAA Record: Maps a hostname directly to an IPv6 address (if your server has one).
- CNAME Record: Maps a hostname to another hostname (less common for the primary service address).
- Propagation Time: DNS changes can take anywhere from a few minutes to 48 hours to propagate globally, although it's often much faster. You can use online tools like
dnschecker.org
to verify propagation.
- Server Access: SSH access to your Funkwhale server.
- Working Funkwhale Installation (Docker): The Docker setup from previous sections, including the Nginx container.
Configuring Nginx and Let's Encrypt
The official funkwhale-docker
setup includes an Nginx container acting as a reverse proxy. This means Nginx receives incoming web requests (on ports 80 and 443) and forwards them to the appropriate backend service (the Funkwhale frontend or API containers). It's also the ideal place to handle SSL/TLS termination (decrypting HTTPS traffic).
The setup often includes built-in support for Let's Encrypt via Certbot. Let's Encrypt is a free, automated, and open Certificate Authority (CA) that provides SSL/TLS certificates.
-
Ensure DNS is Pointing Correctly: Before proceeding, double-check that the hostname you set in
FUNKWHALE_HOSTNAME
(in your.env
file) resolves to your server's IP address. Useping your.funkwhale.domain
ordig your.funkwhale.domain
from your local machine or an online tool. -
Update
Verify/Set:.env
File: Make sure the.env
file in yourfunkwhale-docker
directory has the correctFUNKWHALE_HOSTNAME
. Also, ensure the Let's Encrypt settings are enabled (they usually are by default):FUNKWHALE_HOSTNAME=your.funkwhale.domain
(Your actual domain)LETSENCRYPT_ENABLED=true
LETSENCRYPT_EMAIL=youremail@example.com
(Your actual email, used for expiry notifications)LETSENCRYPT_MODE=standalone
(Orwebroot
if configured differently, butstandalone
often works well with the default Docker setup's handling of the challenge).
Save and close the file.
-
Restart Funkwhale Containers to Apply
.env
Changes: Apply the changes made to the.env
file by recreating the containers. -
Initiate Let's Encrypt Certificate Request: The official Funkwhale Docker setup often includes a script or relies on Certbot running within the Nginx container to automatically handle certificate acquisition upon startup when
LETSENCRYPT_ENABLED=true
. However, sometimes manual initiation or specific container execution is needed, especially on the first run or if it failed.-
Check Logs: First, check the Nginx container logs to see if certificate acquisition was attempted and if it succeeded or failed:
Look for messages related to Certbot or Let's Encrypt. -
Manual Certbot (If Needed): If automatic acquisition fails, you might need to manually run Certbot inside the Nginx container. The exact command can vary based on the
funkwhale-docker
version and configuration. A common approach might involve:Adapt the command based on the specific Certbot setup within your Nginx container (check its Dockerfile or entrypoint script if unsure). Sometimes a simpler# Execute certbot inside the nginx container sudo docker compose exec nginx certbot certonly --webroot -w /var/www/certbot \ -d your.funkwhale.domain --email youremail@example.com \ --rsa-key-size 4096 --agree-tos --non-interactive --force-renewal
certbot renew
or a specific script inside the container is used.Another common pattern uses Certbot in standalone mode before Nginx fully starts, or temporarily stops Nginx:
Consult the specific documentation for your version of# Example using standalone (might require stopping Nginx temporarily) sudo docker compose stop nginx sudo docker compose run --rm --entrypoint "\ certbot certonly --standalone \ --preferred-challenges http -d your.funkwhale.domain \ --email youremail@example.com --agree-tos --non-interactive \ --rsa-key-size 4096" certbot_service # Assuming a dedicated certbot service or using the nginx image sudo docker compose start nginx
funkwhale-docker
if automatic acquisition doesn't work.
-
-
Automatic Renewal: The provided Nginx container image usually includes a mechanism (like a cron job running
certbot renew
) to automatically renew the certificates before they expire (Let's Encrypt certificates are valid for 90 days). Verify this by checking the container's configuration or logs over time. -
Verify HTTPS Access:
- Wait a few minutes after restarting the containers or running Certbot.
- Access your Funkwhale instance using
https://your.funkwhale.domain
in your browser. - Check for the padlock icon in the address bar, indicating a secure connection. Click it to inspect the certificate details (it should be issued by Let's Encrypt to your domain).
- You should also be automatically redirected from HTTP to HTTPS if you try accessing
http://your.funkwhale.domain
.
Troubleshooting
- DNS Propagation: Ensure your DNS A record is correct and has propagated. Use
dig
ornslookup
. - Firewall: Make sure ports 80 (for Let's Encrypt HTTP-01 challenge) and 443 (for HTTPS) are open on your server's firewall (e.g., UFW). Check
sudo ufw status
. - Docker Networking: Ensure Nginx container can receive traffic on ports 80/443. The
docker-compose.yml
usually maps host ports 80 and 443 to the Nginx container. - Let's Encrypt Rate Limits: If you experiment too much, you might hit Let's Encrypt's rate limits. Wait a while before trying again. Use the
--staging
flag with Certbot for testing to avoid hitting production limits. - Nginx Configuration Errors: Check Nginx logs (
sudo docker compose logs nginx
) for syntax errors or other issues. The default Funkwhale template is usually robust, but custom modifications can introduce errors. .env
File Issues: Double-check syntax and values in your.env
file. EnsureFUNKWHALE_HOSTNAME
exactly matches the domain in the certificate request.
Workshop Setting up Domain and HTTPS
Goal: Configure DNS, enable Let's Encrypt in Funkwhale's Docker setup, obtain an SSL certificate, and access Funkwhale securely via HTTPS.
Prerequisites: A registered domain name. Access to your domain's DNS settings. A running Funkwhale Docker instance (Workshop 3 completed). Server firewall allowing ports 80 and 443.
Steps:
-
Configure DNS:
- Log in to your domain registrar or DNS provider's control panel.
- Go to the DNS management section for your domain.
- Create an
A
record:- Host/Name: The subdomain you want to use (e.g.,
funkwhale
ormusic
). If you want to use the bare domain (e.g.,yourdomain.com
), the host is often@
or left blank, but using a subdomain is common practice. - Value/Points to: Your Funkwhale server's public IP address.
- TTL (Time To Live): Use the default (often 1 hour or automatic).
- Host/Name: The subdomain you want to use (e.g.,
- Save the record.
-
Verify DNS Propagation:
- Wait 5-15 minutes (or longer, depending on TTL).
- Open a terminal on your local computer.
- Use
ping
ordig
: (Replacefunkwhale.yourdomain.com
with your actual chosen hostname). - Confirm that the command resolves to your server's correct IP address. If not, wait longer or double-check your DNS record.
-
Update Funkwhale
.env
Configuration:- Connect to your server via SSH.
- Navigate to the Funkwhale directory:
cd /opt/funkwhale-docker
- Edit the environment file:
sudo nano .env
- Set
FUNKWHALE_HOSTNAME
to the exact hostname you configured in DNS (e.g.,funkwhale.yourdomain.com
). - Ensure
LETSENCRYPT_ENABLED=true
. - Set
LETSENCRYPT_EMAIL
to your real email address. - Save and close (Ctrl+X, Y, Enter).
-
Restart Funkwhale and Trigger Certificate Acquisition:
-
Monitor Logs:
- Wait about 30-60 seconds for containers to start.
- Check the Nginx logs for Let's Encrypt activity:
- Look for lines indicating a successful certificate request from Certbot. You might see mentions of challenges being verified and certificates being saved/deployed. Press Ctrl+C to exit log following. If you see errors, investigate based on the error message (DNS, firewall, rate limits?).
-
Test HTTPS Access:
- Open your web browser.
- Navigate to
https://funkwhale.yourdomain.com
(usinghttps
). - Verification:
- Does the Funkwhale login page load?
- Is there a padlock icon in the address bar?
- Click the padlock: Does it show a certificate issued by Let's Encrypt for your domain?
- Try accessing
http://funkwhale.yourdomain.com
(withouts
). Are you automatically redirected to HTTPS?
Outcome: Your Funkwhale instance is now accessible via a user-friendly domain name with a valid HTTPS certificate, ensuring secure connections for you and your users, and enabling proper federation capabilities.
6. User Management and Permissions
Funkwhale allows you to control who can access your instance and what they can do. As the administrator, you can manage user accounts, control registration methods, and assign roles.
Registration Methods
How users get accounts on your instance is a key decision.
-
Open Registration:
- How it works: Anyone visiting your instance's login page can click a "Sign Up" or "Register" link and create an account themselves.
- Configuration: In
Administration -> Settings -> Instance
, uncheck the "Closed registrations" box. - Pros: Easiest way to let many users join, good for public or community instances.
- Cons: Can lead to spam accounts, requires moderation, less control over who joins. You might need CAPTCHA or email verification configured (check
.env
or admin settings) to mitigate spam.
-
Invite-Only:
- How it works: Existing users (or just admins, depending on settings) generate unique invitation links that they can send to people they want to invite. Only someone with a valid invite link can register.
- Configuration:
- Check the "Closed registrations" box in
Administration -> Settings -> Instance
. - Configure invite settings in
Administration -> Settings -> Invitations
. You can control if all users can create invites or only moderators/admins, and set expiry times for invites.
- Check the "Closed registrations" box in
- Pros: More control over who joins, reduces spam potential, suitable for private or semi-private instances.
- Cons: Requires manual action to add new users.
-
Closed Registration (No Invites):
- How it works: The "Closed registrations" box is checked, and invite generation is disabled or restricted to admins only. New users can only be created manually by an administrator via the admin interface.
- Configuration: Check "Closed registrations", configure invitation settings restrictively.
- Pros: Maximum control, suitable for purely personal instances or very small, tightly controlled groups.
- Cons: Most restrictive, all user creation is manual admin work.
Managing Users via Admin Interface
Navigate to Administration -> Users
to manage accounts.
- Viewing Users: See a list of all registered users, their username, email (visible to admin), status (active/inactive), role, and join date.
- Creating Users (Manual): If registrations are closed/invite-only, you can manually create accounts here using the "Create user" button. You'll need to set a username, email, and initial password.
- Editing Users: Click on a username to view details and modify settings:
- Profile: Change display name, email (with verification).
- Account: Change username, set/reset password, activate/deactivate the account. Deactivating prevents login but keeps the user's data.
- Permissions: Assign roles (see below).
- Deleting Users: Be cautious! Deleting a user is generally permanent and might remove associated data (though content like uploaded music might remain if managed by the library owner, not the user specifically). Deactivating is often safer.
Roles and Permissions
Funkwhale has a simple role-based permission system:
- User (Default): Standard account. Can listen to music (according to library permissions), create playlists, favorite tracks, manage their own profile, potentially create invites (if allowed by instance settings). Cannot access administration settings.
- Moderator: Inherits user permissions. Additionally, can typically manage content (e.g., moderate comments if enabled), manage other non-admin users (activate/deactivate, perhaps edit profiles), and potentially manage federation blocks/mutes. Has limited access to the Administration panel.
- Administrator: Full control over the instance. Can manage all settings, all users (including assigning roles, deleting users), libraries, federation settings, view logs, etc. The superuser created initially is an administrator.
Assigning Roles:
- Go to
Administration -> Users
. - Click the username of the user you want to modify.
- Go to the "Permissions" tab for that user.
- Check the boxes for "Is moderator" or "Is administrator" as needed.
- Save changes.
Grant roles sparingly, especially administrator privileges.
Library Permissions (Brief Overview)
While user roles control instance access, access to the music itself is often controlled at the library level. This is covered more in the next section, but typically:
- Libraries can be public (visible to anyone, even logged-out visitors), internal (visible to all logged-in users on your instance), or private (visible only to specific users or groups you grant access to).
- The administrator usually sets up the initial libraries and their visibility.
Workshop Managing Users and Invites
Goal: Configure the instance for invite-only registration, create an invitation, register a new user using the invite, and promote that user to moderator.
Prerequisites: Logged into Funkwhale as the administrator.
Steps:
-
Configure Invite-Only Registration:
- Go to
Administration -> Settings -> Instance
. - Ensure the Closed registrations checkbox is checked.
- Click Save changes.
- Go to
Administration -> Settings -> Invitations
. - Decide who can create invites. For this workshop, let's allow admins only. Ensure "Users can create invitations" (or similar wording) is unchecked unless you specifically want moderators/users to invite others. If there are separate controls for roles, ensure admins can create invites.
- Optionally set an expiry time for invites (e.g., 7 days).
- Click Save changes.
- Go to
-
Create an Invitation:
- Go to
Administration -> Invitations
(this section might be top-level or under Users). - Click the "Create invitation" button.
- You might be able to add a note or description.
- Click "Create".
- A unique invitation link/code will be generated. Copy this link. It will look something like
https://your.funkwhale.domain/invited/a1b2c3d4e5f6...
.
- Go to
-
Register a New User (Simulated):
- Log out of your admin account (click username -> Logout).
- Open a new private/incognito browser window (important to avoid session conflicts).
- Paste the invitation link you copied into the address bar of the private window and press Enter.
- You should see a registration form specifically for invitees.
- Fill it out with details for a new test user:
- Username (e.g.,
testuser
) - Email (use a real email you can access, or a temporary email service, for testing potential email features)
- Password (set a password for
testuser
)
- Username (e.g.,
- Agree to terms (if any) and complete the registration.
- You should be automatically logged in as
testuser
.
-
Verify New User Access:
- As
testuser
, try accessing theAdministration
panel (you shouldn't be able to). - Browse the library, play music. The experience should be that of a standard user.
- Log out as
testuser
and close the private browser window.
- As
-
Promote User to Moderator:
- Log back into the main browser window as your administrator account.
- Go to
Administration -> Users
. - Find
testuser
in the list and click on their username. - Go to the "Permissions" tab.
- Check the Is moderator box.
- Click Save changes.
-
Verify Moderator Access (Optional):
- Log out as admin.
- Log in as
testuser
. - Check if you now have access to some parts of the
Administration
panel (e.g., perhaps user management, but not instance settings). The exact permissions depend on the Funkwhale version.
Outcome: You have successfully configured your Funkwhale instance for controlled, invite-only registrations, created an invite, registered a new user, and modified that user's role, demonstrating core user management capabilities.
7. Managing Libraries and Importing Music
A "Library" in Funkwhale is a collection of music tracks, usually corresponding to a specific directory on your server's filesystem where the music files are stored. You can have multiple libraries, each with potentially different content and visibility settings. This section covers creating libraries, different ways to import music, and managing metadata.
Understanding Libraries
- Purpose: Libraries group your music logically. You might have one main library for all your music, or separate libraries for different genres, sources (e.g., "CD Rips", "Bandcamp Purchases"), or user groups.
- Association with Filesystem: Each library is linked to a specific directory path inside the Funkwhale containers (e.g.,
/srv/funkwhale/music
). This container path is then mapped to a directory on your host server via Docker volumes (as configured indocker-compose.yml
). - Ownership: Libraries are typically owned by a user (often the admin user by default).
- Visibility/Access Control: This is a key feature. When creating or editing a library, you can set its visibility:
- Public: Anyone visiting your instance (even logged-out users) can browse and listen to this library.
- Internal: Only users logged into your Funkwhale instance can access this library.
- Private: Only the library owner and specific users/groups explicitly granted access can see or listen to the library.
Creating and Managing Libraries (Admin UI)
- Navigate: Log in as admin, go to
Administration -> Libraries
. - Default Library: You'll likely see a default library created during setup, often called "Music" or similar, linked to the primary music volume.
- Create New Library: Click "Create library".
- Name: Give it a descriptive name (e.g., "Classical Collection", "Shared Music").
- Owner: Assign a user as the owner (usually yourself, the admin).
- Path: Crucially, specify the path inside the container where this library's music will reside. If you want to use the same main music folder defined in
docker-compose.yml
(e.g.,/srv/funkwhale/music
), enter that. If you want a separate sub-folder for this library (e.g.,/srv/funkwhale/music/classical
), you would enter that path. Important: Ensure the corresponding directory exists on your host system within the mapped volume and has the correct permissions for Funkwhale to read. - Visibility: Choose Public, Internal, or Private. If Private, you'll configure access later.
- Save the library.
- Editing: Click on an existing library name to change its settings (Name, Visibility, etc.). Note that changing the Path after music has been imported can cause issues unless you also move the files accordingly on the host.
- Scanning: Each library needs to be scanned independently to detect and import music files within its assigned path. Use the "Scan" button next to the library listing.
Importing Music Files
Getting your music files into the correct directory on the server and telling Funkwhale to process them is the import process.
Method 1: Manual Copy + Scan (Covered Briefly Before)
- Copy Files: Use
scp
orrsync
to copy music files/folders from your local machine to the appropriate directory on the host server that corresponds to the library's path (e.g.,/opt/funkwhale-docker/data/music/classical/
if the library path is/srv/funkwhale/music/classical
). - Set Permissions: Ensure the copied files and directories have the correct ownership and permissions for the Funkwhale process inside the container to read them (e.g.,
sudo chown -R 991:991 /opt/funkwhale-docker/data/music/classical/
). - Trigger Scan: Go to
Administration -> Libraries
and click "Scan" for the relevant library, OR use the CLI command:
Method 2: Watch Folders (Automatic Scanning - Experimental/Advanced)
Some Funkwhale versions might offer experimental support for "watch folders," where Funkwhale automatically detects and imports new files added to a specific directory. This often requires additional setup (like inotify-tools
on the host and specific configuration) and may not be as reliable as manual scanning, especially with Docker volumes. Consult the latest Funkwhale documentation if you wish to explore this. Generally, manual scanning after copying is the most robust method.
Method 3: Upload via Web UI (Less Common for Bulk Imports)
Regular users (depending on permissions) might be able to upload individual tracks or archives directly through the web interface. This is usually found under user settings or a dedicated upload section. This is convenient for occasional additions but not efficient for large libraries. The maximum upload size is controlled by NGINX_MAX_BODY_SIZE
in your .env
file and potentially other Nginx/Funkwhale settings.
Metadata Handling
When Funkwhale scans your files, it reads embedded metadata tags (ID3 tags for MP3, Vorbis comments for FLAC/Ogg, etc.) to identify the track title, artist, album, genre, track number, etc.
- Accuracy: The quality of your library in Funkwhale heavily depends on the accuracy and completeness of your files' existing metadata tags. It's highly recommended to use a dedicated music tagging application (like MusicBrainz Picard, mp3tag, EasyTAG) to clean up and standardize your tags before uploading/importing.
- Fetching External Data: Funkwhale can optionally attempt to fetch additional metadata (like artist bios, album art) from external sources like MusicBrainz. This behavior might be configurable in the admin settings.
- Troubleshooting Metadata:
- Unknown Artist/Album: Files likely lack proper tags.
- Incorrect Grouping: Inconsistent artist or album names (e.g., "The Beatles" vs. "Beatles") can cause tracks/albums to be split incorrectly. Standardize your tags!
- Missing Album Art: Ensure album art is embedded in the files or available as a
folder.jpg
(or similar) in the album directory. Funkwhale's external fetching might also find it.
- Rescanning: If you update the metadata tags of files already imported into Funkwhale using an external tool, you will need to rescan the library for Funkwhale to pick up the changes. Funkwhale might have options for rescanning metadata specifically, or a full re-import might be necessary in some cases.
Workshop Creating a Private Library and Importing Music
Goal: Create a new, private library, copy specific music into its corresponding host directory, and scan only that library. Then grant access to your testuser
.
Prerequisites: Admin access to Funkwhale. testuser
created (Workshop 6). Some music files ready to upload (distinct from any previously uploaded). Server terminal access.
Steps:
-
Prepare Host Directory:
- On your server, create a new sub-directory within your main Funkwhale music data directory.
-
Create Private Library in Funkwhale:
- Log in to Funkwhale as admin.
- Go to
Administration -> Libraries
. - Click "Create library".
- Name:
My Private Stash
- Owner: Select your admin user.
- Path:
/srv/funkwhale/music/private_collection
(This must match the directory you created, relative to the container's music mount point). - Visibility: Select Private.
- Click Create library.
-
Upload Music to the New Directory:
- On your local computer, prepare a folder with a few music tracks you want to be private.
- Use
scp
orrsync
to copy these files into the new directory on the server: - Verify files are on the server and set permissions if needed (rsync with
-a
often preserves permissions, but double-check ownership):
-
Scan the New Library:
- Go back to
Administration -> Libraries
in the Funkwhale web UI. - Find the "My Private Stash" library.
- Click the "Scan" button specifically for this library.
- Alternatively, use the CLI, finding the new library's ID first (check the URL when editing it, or use a manage command to list libraries) and then scanning:
- Go back to
-
Verify Privacy (Admin View):
- As admin, navigate to the main Library section. You should be able to see and play music from "My Private Stash".
-
Verify Privacy (testuser View):
- Log out as admin.
- Log in as
testuser
. - Navigate to the Library section.
- You should not see the "My Private Stash" library or its contents.
-
Grant Access to testuser:
- Log out as
testuser
. - Log back in as admin.
- Go to
Administration -> Libraries
. - Click on the name "My Private Stash" to edit it.
- Find the "Access Control" or "Permissions" section for the library (the exact location might vary slightly).
- There should be an option to add users or groups. Search for
testuser
. - Add
testuser
to the list of users who have access. You might be able to set read-only or other permissions. Grant basic read/listen access. - Save the library changes.
- Log out as
-
Verify Access (testuser View):
- Log out as admin.
- Log in as
testuser
again. - Navigate to the Library section.
- You should now see the "My Private Stash" library and be able to browse and play its contents.
Outcome: You have successfully created a separate, private library, imported music into it, verified its privacy, and then granted access to a specific user, demonstrating fine-grained control over music access within your Funkwhale instance.
8. Federation Basics (ActivityPub)
One of Funkwhale's most unique features compared to other self-hosted music servers is its ability to federate. Using the ActivityPub protocol, your Funkwhale instance can connect with other Funkwhale instances (and potentially other ActivityPub-compatible services) to create a decentralized social network around music.
What is Federation and ActivityPub?
- Federation: Imagine email. You can have an account at
gmail.com
and send an email to someone atoutlook.com
oryour-university.edu
. These are separate systems (servers) run by different organizations, but they can communicate using a common protocol (SMTP). Federation in social media works similarly. Instead of one giant platform (like Twitter or Facebook), you have many independent servers (instances) that can talk to each other. - ActivityPub: This is the specific W3C standard protocol that enables this communication for services like Mastodon, Pleroma, PixelFed, PeerTube, and Funkwhale. It defines how different servers can exchange information about users, posts (or "activities"), follows, likes, shares, etc., in a standardized way.
How Federation Works in Funkwhale
When federation is enabled on your instance (Administration -> Settings -> Instance -> Enable federation
should be checked):
- Instance Discovery: Your instance can learn about other Funkwhale instances (pods). This might happen through manual following, user searches, or directories.
- User Profiles: Each user on a federated instance has a unique identifier like
@username@your.funkwhale.domain
. This allows users on different instances to find and follow each other. - Following:
- You can follow users on other Funkwhale instances.
- Users on other instances can follow users on your instance (if their profiles/libraries are public or internal).
- Content Sharing (Based on Permissions):
- Public Libraries: If a library on instance
A
is set to "Public", users on instanceB
who follow a user from instanceA
(or discover content from instanceA
) might be able to see and potentially listen to tracks from that public library directly through their interface on instanceB
. - Favorites/Listens: When you favorite a track or listen to music (depending on your privacy settings), this activity can be broadcast to your followers, including those on other instances. This allows for music discovery across the network.
- Federated Search: Your search results might include publicly available music from other instances your pod knows about.
- Public Libraries: If a library on instance
- Control: You remain in control of what leaves your instance. Private libraries are not federated. Users can often control the privacy level of their listening history or favorites. Administrators can block federation with specific instances if necessary (
Administration -> Federation -> Federating instances -> Block instance
).
Benefits of Federation
- Music Discovery: Discover new artists and tracks available on other pods that aren't in your personal library.
- Community: Connect with users who have similar music tastes, regardless of which instance they use.
- Resilience: The network isn't dependent on a single company or server. If one pod goes offline, the rest of the network continues to function.
- Wider Reach (Optional): If you host public domain music or creative commons tracks, federation allows others in the network to easily discover and listen to them.
Potential Considerations
- Resource Usage: Fetching information and potentially proxying audio from other instances can consume bandwidth and server resources (CPU/RAM). This is usually manageable but something to be aware of. Funkwhale often caches federated information to reduce load.
- Moderation: If interacting with a wide network, you might encounter content or instances you wish to avoid. Admins have tools to block problematic instances.
- Privacy: Be mindful of what information is shared. Public libraries are public. Your favorites and listening history might be shared if set to public. Review your user profile settings (
Settings -> Profile
orPrivacy
) to control activity sharing. Instance administrators set the defaults. - Configuration: Federation relies heavily on your instance being correctly set up with a domain name and HTTPS. Your
FUNKWHALE_HOSTNAME
must be accurate and reachable from the internet.
Exploring Federation Features
- Searching: Use the search bar. Try searching for a user on another known Funkwhale instance using their full handle (e.g.,
@someuser@another.funkwhale.pod
). You might also find federated tracks or albums. - Following: If you find a user on another instance, you should see a "Follow" button on their profile page.
- Federation Admin Panel: As admin, explore
Administration -> Federation
.- Federating instances: See instances your pod knows about, potentially block specific ones.
- Followers/Following: See follower relationships involving your instance's users.
- Activity Queue: Monitor outgoing and incoming federation activities (advanced).
Workshop Exploring Federation
Goal: Find another Funkwhale instance, follow a user (if possible), and observe how federated content might appear.
Prerequisites: Your Funkwhale instance running with HTTPS and federation enabled.
Note: This workshop relies on interacting with the live Fediverse. Finding active users/instances to follow requires some exploration. You can look for Funkwhale instances on directories like fedidb.org or ask in Funkwhale community channels (like their Matrix room). For this exercise, we'll simulate the steps. Let's assume there's another instance called open.audio
and a user @cassidy@open.audio
who has a public library.
Steps:
-
Log in: Log in to your Funkwhale instance (
https://your.funkwhale.domain
) as your regular user (or admin). -
Enable Federation (Verify):
- If logged in as admin, quickly check
Administration -> Settings -> Instance
and ensure "Enable federation" is checked.
- If logged in as admin, quickly check
-
Find a Federated User/Instance:
- (Method A: Direct Search) Use the search bar at the top. Enter the full handle of a user on another instance you know exists (e.g.,
@cassidy@open.audio
). Press Enter. - (Method B: Exploration) Browse instance directories like fedidb.org to find other public Funkwhale instances. Visit one (e.g.,
https://open.audio
) in your browser. Find a user profile page on that instance (often accessible via/users/username
). Note their full handle (@username@instance.domain
). Then go back to your instance and use the search bar (Method A).
- (Method A: Direct Search) Use the search bar at the top. Enter the full handle of a user on another instance you know exists (e.g.,
-
View Federated Profile:
- If the search is successful, you should see the profile of
@cassidy@open.audio
appear in your search results within your instance's interface. Click on it. - You are now viewing their profile as seen from your instance. You might see their bio, avatar, and potentially tabs for their public uploads or favorites, depending on what instance
open.audio
shares.
- If the search is successful, you should see the profile of
-
Follow the User:
- On their profile page viewed from your instance, look for a "Follow" button. Click it.
- The button state should change to "Pending" or "Following", depending on whether the remote user requires follow approval.
-
Discover Federated Content (Explore):
- Now that you're following someone (or your instance is aware of
open.audio
), explore your Funkwhale instance:- Search: Try searching for an artist or album you know is in
@cassidy@open.audio
's public library but not in yours. It might appear in the search results, potentially marked as originating from the remote instance. - Home Feed/Discover: Check your home feed or any "discover" sections. Federated content (like public favorites from people you follow) might start appearing over time.
- Browsing Federated Libraries (If UI supports): Some UI versions might have explicit ways to browse the public libraries of followed instances or users. Explore the Library or Federation sections.
- Search: Try searching for an artist or album you know is in
- Now that you're following someone (or your instance is aware of
-
Federation Administration (Admin Task):
- Log in as admin.
- Go to
Administration -> Federation -> Federating instances
. - Do you see
open.audio
listed? This confirms your instance is aware of it. You can see statistics and potentially block it if needed.
Outcome: You have simulated or performed the actions of searching for and following a user on a different Funkwhale instance. You understand how federation allows instances to connect and potentially share public content, enabling music discovery beyond your own library. You also know where administrators can monitor and control these federated connections.
9. Backup and Restore Strategies
Running any self-hosted service requires a solid backup plan. Losing your Funkwhale data could mean losing user accounts, playlists, favorites, listening history, and potentially even your carefully curated music files if they aren't stored elsewhere. This section covers what data needs backing up and how to implement basic backup and restore procedures.
What Needs Backing Up?
A complete Funkwhale backup involves several components, primarily managed by the Docker setup:
- Database: This is the most critical part. It stores user accounts, passwords (hashed), playlists, favorites, listening history, track metadata indexed from your files, federation information, instance settings, etc. In the default Docker setup, this is a PostgreSQL database running in its own container.
- Music Files: The actual
.mp3
,.flac
, etc., files you uploaded. Where these are stored depends on your volume mapping indocker-compose.yml
. It could be a directory on the host (like/opt/funkwhale-docker/data/music
) or a named Docker volume. Crucially, decide if this backup process is your only copy of the music files. Ideally, you should have another primary backup of your original music files elsewhere, treating the Funkwhale server storage as a working copy. However, if Funkwhale is the only place they reside, backing them up from the server is essential. - Configuration Files: Primarily the
.env
file which contains your domain, passwords, and keys. While you could recreate this, backing it up is easy and recommended. You might also have custom Nginx configurations if you modified them. - Docker Volumes (Implicit Data): Besides the main music data, Docker might use named volumes for other persistent data (like the PostgreSQL data itself, Redis data (less critical, often cache), Certbot certificates). Backing up the database logically (dump) and the core config/music files is often sufficient, but backing up the Docker volumes directly provides a more complete snapshot.
Backup Methods
We'll focus on logical backups (database dumps, file copies) as they are generally easier to manage and restore across different environments.
1. Backing Up the PostgreSQL Database
The best way to back up PostgreSQL is using the pg_dump
utility. We need to execute this command inside the Postgres container.
-
Identify Container and DB Details:
- Find the name of your Postgres container:
sudo docker compose ps
(look for thepostgres
service). Let's assume it'sfunkwhale-docker-postgres-1
. - Find the database name, user, and password from your
.env
file (POSTGRES_DB
,POSTGRES_USER
,POSTGRES_PASSWORD
).
- Find the name of your Postgres container:
-
Perform the Dump:
# Execute pg_dump inside the postgres container and redirect output to a file on the host sudo docker compose exec -T postgres pg_dump -U $POSTGRES_USER -d $POSTGRES_DB > /path/to/your/backups/funkwhale_db_backup_$(date +%Y%m%d_%H%M%S).sql
- Replace
$POSTGRES_USER
and$POSTGRES_DB
with the actual values from your.env
file (or use shell variables if defined). You might be prompted for thePOSTGRES_PASSWORD
. - Alternatively, to avoid password prompts in scripts, you can pass the password via an environment variable (less secure if visible in process lists) or use a
.pgpass
file (more secure, requires setup inside the container or mounting). Usingdocker compose exec -T
handles input/output redirection cleanly. - Replace
/path/to/your/backups/
with the actual directory on your host server where you want to store database backups. - The
$(date +%Y%m%d_%H%M%S)
part adds a timestamp to the filename.
- Replace
2. Backing Up Music Files
Use rsync
for efficient file copying.
- Identify Host Music Directory: Find the directory on your host system that maps to Funkwhale's music volume (e.g.,
/opt/funkwhale-docker/data/music/
). - Perform the Sync:
# Sync the music directory to a backup location sudo rsync -avz --delete /opt/funkwhale-docker/data/music/ /path/to/your/backups/funkwhale_music/
- Replace
/opt/funkwhale-docker/data/music/
with your actual source directory. Note the trailing slash/
to copy the contents of the directory. - Replace
/path/to/your/backups/funkwhale_music/
with your backup destination. -a
: Archive mode (preserves permissions, ownership, timestamps, etc.).-v
: Verbose output.-z
: Compresses data during transfer.--delete
: Deletes files in the destination that no longer exist in the source (keeps the backup synchronized). Use with caution if you need to recover accidentally deleted files from the backup later – consider snapshotting tools or removing--delete
for archival purposes.
- Replace
3. Backing Up Configuration
Simply copy the essential config files.
# Ensure you are in the directory containing your funkwhale-docker setup
cd /opt/funkwhale-docker
# Copy .env file (and potentially docker-compose.yml if you customized it)
sudo cp .env /path/to/your/backups/config_backup/
sudo cp docker-compose.yml /path/to/your/backups/config_backup/
# Also back up any custom Nginx configs if you have them
# sudo cp ./nginx/user_conf.d/*.conf /path/to/your/backups/config_backup/nginx_conf/
4. Automating Backups
Manually running these commands is prone to being forgotten. Use cron
(the standard Linux scheduler) to automate them.
-
Create a Backup Script:
# /home/funkadmin/scripts/backup_funkwhale.sh #!/bin/bash # --- Configuration --- BACKUP_DIR="/mnt/backup_drive/funkwhale_backups" # Destination for backups (use a separate drive if possible!) FUNKWHALE_DOCKER_DIR="/opt/funkwhale-docker" MUSIC_SOURCE_DIR="${FUNKWHALE_DOCKER_DIR}/data/music/" CONFIG_SOURCE_DIR="${FUNKWHALE_DOCKER_DIR}" # Source environment variables for DB connection source "${CONFIG_SOURCE_DIR}/.env" TIMESTAMP=$(date +%Y%m%d_%H%M%S) DB_BACKUP_FILE="${BACKUP_DIR}/database/funkwhale_db_${TIMESTAMP}.sql" MUSIC_BACKUP_DIR="${BACKUP_DIR}/music/" CONFIG_BACKUP_DIR="${BACKUP_DIR}/config/" # --- Create Backup Directories --- mkdir -p "${BACKUP_DIR}/database" mkdir -p "${MUSIC_BACKUP_DIR}" mkdir -p "${CONFIG_BACKUP_DIR}" mkdir -p "${CONFIG_BACKUP_DIR}/nginx_conf" # If backing up nginx conf echo "Starting Funkwhale Backup: ${TIMESTAMP}" # --- Database Backup --- echo "Backing up database..." cd ${FUNKWHALE_DOCKER_DIR} # Need to be here for docker compose exec # Use PGPASSWORD for non-interactive dump (check security implications) export PGPASSWORD=$POSTGRES_PASSWORD docker compose exec -T postgres pg_dump -U $POSTGRES_USER -d $POSTGRES_DB > "${DB_BACKUP_FILE}" unset PGPASSWORD # Unset password variable immediately # Optional: Compress the SQL dump gzip "${DB_BACKUP_FILE}" echo "Database backup complete: ${DB_BACKUP_FILE}.gz" # --- Music Files Backup --- echo "Backing up music files..." rsync -av --delete "${MUSIC_SOURCE_DIR}" "${MUSIC_BACKUP_DIR}" echo "Music files backup complete." # --- Configuration Backup --- echo "Backing up configuration files..." cp "${CONFIG_SOURCE_DIR}/.env" "${CONFIG_BACKUP_DIR}/.env.${TIMESTAMP}" cp "${CONFIG_SOURCE_DIR}/docker-compose.yml" "${CONFIG_BACKUP_DIR}/docker-compose.yml.${TIMESTAMP}" # cp ${CONFIG_SOURCE_DIR}/nginx/user_conf.d/*.conf ${CONFIG_BACKUP_DIR}/nginx_conf/ echo "Configuration backup complete." # --- Prune Old Backups (Example: Keep last 7 DB backups) --- echo "Pruning old database backups..." find "${BACKUP_DIR}/database/" -name '*.sql.gz' -type f -mtime +7 -delete echo "Backup finished: $(date +%Y%m%d_%H%M%S)" exit 0
- Make the script executable:
chmod +x /home/funkadmin/scripts/backup_funkwhale.sh
- Test the script manually:
sudo /home/funkadmin/scripts/backup_funkwhale.sh
(usesudo
if directories require it).
- Make the script executable:
-
Schedule with Cron:
- Edit the crontab for the root user (or your admin user if they have permissions and docker access):
sudo crontab -e
- Add a line to run the script daily (e.g., at 3:30 AM):
(This runs the script at 3:30 AM every day and logs output to
/var/log/funkwhale_backup.log
) - Save and close the crontab.
- Edit the crontab for the root user (or your admin user if they have permissions and docker access):
5. Offsite Backups
Storing backups on the same server is risky. If the server fails or is compromised, you lose both the original data and the backups. Implement a strategy to copy your backups offsite:
- Another Server: Use
rsync
orscp
to transfer the backup files to another server you control. - Cloud Storage: Use tools like
rclone
to sync your backup directory to services like Backblaze B2, AWS S3, Google Cloud Storage, or others.rclone
can handle encryption during transfer. - External Hard Drive: Regularly connect an external drive and
rsync
backups to it (requires manual intervention or careful scripting).
Restore Procedure (Overview)
Restoring requires reversing the process. Always test your restore process periodically!
- Prepare Fresh Environment: Set up a new server (if needed), install Docker, clone
funkwhale-docker
. - Restore Configuration: Copy your backed-up
.env
anddocker-compose.yml
files into thefunkwhale-docker
directory. - Restore Music Files: Copy/rsync the backed-up music files back to the host music directory (e.g.,
/opt/funkwhale-docker/data/music/
). Ensure permissions are correct. - Start Containers (Except API initially?): It might be safer to start only the database container first:
sudo docker compose up -d postgres
. Wait for it to initialize. - Restore Database:
- Find the name of the new Postgres container.
- Copy the SQL backup file to the server if it's not already there. Unzip it if needed (
gunzip funkwhale_db_backup_....sql.gz
). - Execute the restore command inside the Postgres container. This will overwrite the existing database!
(Replace placeholders. You might need to handle passwords.)
# Copy backup file into container (or use cat | docker exec) sudo docker cp /path/to/your/backups/funkwhale_db_backup_....sql funkwhale-docker-postgres-1:/tmp/backup.sql # Execute psql inside the container to restore sudo docker compose exec postgres psql -U $POSTGRES_USER -d $POSTGRES_DB -f /tmp/backup.sql # OR, stream the file directly (avoids intermediate copy) cat /path/to/your/backups/funkwhale_db_backup_....sql | sudo docker compose exec -T postgres psql -U $POSTGRES_USER -d $POSTGRES_DB
- Start All Containers:
sudo docker compose up -d
. - Verify: Access Funkwhale via your browser. Check if users, playlists, and music library look correct. You might need to trigger a library scan (
docker compose exec api python manage.py fs_check
) if file states seem inconsistent with the database.
Workshop Implement Basic Backup Script
Goal: Create and test a basic script to back up the Funkwhale database and configuration files (we'll skip the music files in this workshop for simplicity, assuming they are backed up elsewhere or the library is small).
Prerequisites: Running Funkwhale instance. Access to the server terminal. nano
or another text editor.
Steps:
-
Create Backup Directory: Choose a location outside your
funkwhale-docker
directory to store backups. -
Create the Backup Script:
- Create a script file:
nano ~/backup_funkwhale_simple.sh
- Paste the following content, carefully replacing placeholders:
#!/bin/bash echo "--- Starting Simple Funkwhale Backup ---" TIMESTAMP=$(date +%Y%m%d_%H%M%S) # --- Configuration --- # !!! SET THESE CORRECTLY !!! FUNKWHALE_DOCKER_DIR="/opt/funkwhale-docker" # Path to your funkwhale-docker checkout BACKUP_BASE_DIR="/opt/funkwhale_backups" # Backup destination created in Step 1 CONFIG_BACKUP_DIR="${BACKUP_BASE_DIR}/config" DB_BACKUP_DIR="${BACKUP_BASE_DIR}/database" DB_BACKUP_FILE="${DB_BACKUP_DIR}/funkwhale_db_${TIMESTAMP}.sql" # --- Source .env for DB variables --- # Check if .env exists if [[ -f "${FUNKWHALE_DOCKER_DIR}/.env" ]]; then source "${FUNKWHALE_DOCKER_DIR}/.env" else echo "Error: ${FUNKWHALE_DOCKER_DIR}/.env not found!" exit 1 fi # Check essential variables are set if [[ -z "$POSTGRES_USER" || -z "$POSTGRES_DB" || -z "$POSTGRES_PASSWORD" ]]; then echo "Error: Database variables not set in .env file!" exit 1 fi # --- Backup Config --- echo "Backing up config files..." cp "${FUNKWHALE_DOCKER_DIR}/.env" "${CONFIG_BACKUP_DIR}/.env.${TIMESTAMP}" cp "${FUNKWHALE_DOCKER_DIR}/docker-compose.yml" "${CONFIG_BACKUP_DIR}/docker-compose.yml.${TIMESTAMP}" echo "Config backup done." # --- Backup Database --- echo "Backing up database..." cd "${FUNKWHALE_DOCKER_DIR}" || exit 1 # Need to be in docker-compose dir export PGPASSWORD=$POSTGRES_PASSWORD docker compose exec -T postgres pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" > "${DB_BACKUP_FILE}" DB_DUMP_EXIT_CODE=$? unset PGPASSWORD if [[ $DB_DUMP_EXIT_CODE -eq 0 ]]; then # Optional: Compress the backup gzip "${DB_BACKUP_FILE}" echo "Database backup successful: ${DB_BACKUP_FILE}.gz" else echo "Error: Database backup failed with exit code ${DB_DUMP_EXIT_CODE}!" # Optional: remove failed/empty file rm -f "${DB_BACKUP_FILE}" exit 1 fi # --- Pruning old backups (keep last 5) --- echo "Pruning old DB backups..." find "${DB_BACKUP_DIR}" -name '*.sql.gz' -type f -printf '%T@ %p\n' | sort -nr | tail -n +6 | cut -d' ' -f2- | xargs -I {} rm -- {} echo "Pruning old Config backups (.env)..." find "${CONFIG_BACKUP_DIR}" -name '.env.*' -type f -printf '%T@ %p\n' | sort -nr | tail -n +6 | cut -d' ' -f2- | xargs -I {} rm -- {} echo "--- Backup Finished ---" exit 0
- Save and close (
Ctrl+X
,Y
,Enter
).
- Create a script file:
-
Make Script Executable:
-
Run the Script Manually: Execute the script. You might need
Watch the output for any errors.sudo
depending on permissions of/opt/funkwhale_backups
and your Docker setup. -
Verify Backups: Check the contents of your backup directory:
You should see a timestamped.sql.gz
database backup and timestamped copies of your.env
anddocker-compose.yml
files.
Outcome: You have created a basic, functional script to back up your critical Funkwhale configuration and database. This script can be run manually or automated using cron
for regular backups. Remember to add music file backups and offsite storage for a complete strategy.
(Advanced Sections follow)
10. Advanced Nginx Configuration
The Nginx container provided with the funkwhale-docker
setup acts as a vital reverse proxy, handling incoming connections, SSL/TLS termination, and routing requests to the appropriate Funkwhale backend services (API and frontend). While the default configuration is generally robust, you might want to customize it for improved performance, enhanced security, or specific features.
Understanding the Default Nginx Setup
Typically, the funkwhale-docker
setup includes:
- Nginx Container: Runs the Nginx web server.
- Default Configuration: Located usually within the container at
/etc/nginx/nginx.conf
(main config) and/etc/nginx/conf.d/funkwhale.conf
(or similar, for the Funkwhale-specific directives). - SSL/TLS Handling: Configured to use Let's Encrypt certificates (if enabled) stored in a volume (often
/etc/letsencrypt
). It usually enforces HTTPS by redirecting HTTP requests. - Proxying: Uses
proxy_pass
directives to forward requests for/api/
(or similar) to the Funkwhale API container and other requests to the Funkwhale frontend container. - Static Files: May serve some static assets directly for better performance.
- Upload Size Limit: Configured via
client_max_body_size
(often controlled by theNGINX_MAX_BODY_SIZE
variable in.env
).
Customizing Nginx Configuration
Modifying the core Nginx configuration inside the container directly is not recommended, as changes will be lost when the container is recreated. The intended way to add custom settings is usually via user-defined configuration snippets.
-
Locate User Configuration Directory: Check the
docker-compose.yml
file for thenginx
service definition. Look at itsvolumes
section. You'll often find a mapping like:This maps a directory namedvolumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/user_conf.d:/etc/nginx/user_conf.d:ro # <-- This one! # ... other volumes for logs, certs, etc.
nginx/user_conf.d
on your host (relative to thedocker-compose.yml
file) to/etc/nginx/user_conf.d
inside the Nginx container. The main Funkwhale Nginx config (/etc/nginx/conf.d/funkwhale.conf
) is usually set up toinclude /etc/nginx/user_conf.d/*.conf;
inside theserver
block. -
Create Custom Snippets: Any file ending in
.conf
that you place in the host directorynginx/user_conf.d/
will be included in the Nginx configuration. -
Restart Nginx: After adding or modifying files in
nginx/user_conf.d/
, you need to restart the Nginx container for the changes to take effect:
Example Customizations
Place these snippets inside your .conf
file within nginx/user_conf.d/
.
1. Enhancing Security Headers
These headers instruct browsers on how to handle your site's content, mitigating common attacks like clickjacking and cross-site scripting (XSS).
# In nginx/user_conf.d/security_headers.conf
# Prevent Clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;
# Prevent MIME-type sniffing
add_header X-Content-Type-Options "nosniff" always;
# Enable XSS filter in older browsers (modern ones have it built-in)
# Note: This header is largely deprecated, but harmless to include for older compatibility.
add_header X-XSS-Protection "1; mode=block" always;
# Referrer Policy (Controls how much referrer info is sent)
# 'strict-origin-when-cross-origin' is a good default balance
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Content Security Policy (CSP) - *Use with extreme caution!*
# A basic restrictive policy - WILL LIKELY BREAK FUNKWHALE FUNCTIONALITY
# You MUST carefully analyze Funkwhale's required sources (scripts, styles, fonts, media, connect)
# and build a policy specific to its needs. Start by using reporting mode.
# add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; media-src 'self' blob:; connect-src 'self';" always;
# Start with Report-Only mode to test:
# add_header Content-Security-Policy-Report-Only "..." always;
# Permissions Policy (formerly Feature Policy) - Control browser features
# Example: Deny access to microphone and camera
add_header Permissions-Policy "microphone=(), camera=()" always;
Important: Implementing Content-Security-Policy
requires careful testing. An overly strict policy will break Funkwhale's functionality. Use browser developer tools (Console) to see CSP violations and refine the policy. Start with Report-Only
mode.
2. Enabling HTTP/2 (Usually Enabled by Default)
HTTP/2 offers performance improvements over HTTP/1.1. The default Funkwhale Nginx config usually enables this already on the HTTPS listener. Verify the listen
directive in the main Nginx config (/etc/nginx/conf.d/funkwhale.conf
inside container, or the host-mounted equivalent):
# Example listen directive with HTTP/2 enabled
listen 443 ssl http2;
listen [::]:443 ssl http2; # For IPv6
3. Enabling Gzip Compression (Usually Enabled by Default)
Compressing text-based assets (HTML, CSS, JS, JSON) reduces bandwidth usage. This is typically enabled globally in /etc/nginx/nginx.conf
or within the Funkwhale server block.
# Example Gzip settings (often in main nginx.conf or included snippet)
# gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
# gzip_min_length 256;
# gzip_buffers 16 8k;
4. Tuning Proxy Buffering
Nginx buffers responses from the backend (Funkwhale API/Frontend). Adjusting buffer sizes can sometimes impact performance, especially for large requests/responses, but default values are often adequate.
# In nginx/user_conf.d/proxy_tuning.conf
# Example: Increase proxy buffer sizes (use cautiously)
# proxy_buffer_size 128k;
# proxy_buffers 4 256k;
# proxy_busy_buffers_size 256k;
5. Custom Error Pages
Provide branded error pages instead of the default Nginx ones.
# In nginx/user_conf.d/error_pages.conf
# Define custom error pages (paths are relative to Nginx root)
error_page 404 /custom_404.html;
location = /custom_404.html {
root /usr/share/nginx/html; # Or another path where you place the HTML file
internal; # Prevents direct access to the error page file
}
error_page 500 502 503 504 /custom_50x.html;
location = /custom_50x.html {
root /usr/share/nginx/html;
internal;
}
# You would need to mount your custom HTML files into the container
# e.g., in docker-compose.yml:
# volumes:
# - ./custom_html:/usr/share/nginx/html:ro
Testing Nginx Configuration
Before restarting the Nginx container with configuration changes, always test the syntax:
This command will reportsyntax is ok
or show the file and line number containing an error. Fix any errors before restarting.
Workshop Implementing Security Headers
Goal: Add common security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy) to your Funkwhale Nginx configuration.
Prerequisites: Running Funkwhale instance with Docker and Nginx reverse proxy. Terminal access to the server.
Steps:
-
Navigate to Funkwhale Directory:
-
Create User Config Directory: If it doesn't already exist:
-
Create Security Headers Config File:
-
Add Header Directives: Paste the following directives into the file:
# Prevent Clickjacking add_header X-Frame-Options "SAMEORIGIN" always; # Prevent MIME-type sniffing add_header X-Content-Type-Options "nosniff" always; # Referrer Policy add_header Referrer-Policy "strict-origin-when-cross-origin" always;
- Note: We are omitting
X-XSS-Protection
as it's largely deprecated andContent-Security-Policy
because it requires significant specific tuning for Funkwhale.* - Save and close (
Ctrl+X
,Y
,Enter
).
- Note: We are omitting
-
Test Nginx Configuration Syntax:
- Expected Output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
andnginx: configuration file /etc/nginx/nginx.conf test is successful
. If you get errors, double-check the syntax in yoursecurity_headers.conf
file.
- Expected Output:
-
Restart Nginx Container:
-
Verify Headers:
- Open your Funkwhale instance (
https://your.funkwhale.domain
) in your web browser. - Open the browser's Developer Tools (usually F12).
- Go to the "Network" tab.
- Refresh the Funkwhale page (Ctrl+R or Cmd+R).
- Select the main document request (usually the first HTML request for your domain).
- Look at the "Response Headers" section.
- Verify that you see the headers you added:
x-frame-options: SAMEORIGIN
,x-content-type-options: nosniff
, andreferrer-policy: strict-origin-when-cross-origin
.
- Open your Funkwhale instance (
Outcome: You have successfully added custom Nginx configuration snippets to include important security headers in the responses from your Funkwhale instance, enhancing its security posture without modifying the core Funkwhale-provided configuration files.
11. Scaling Funkwhale
While the default docker-compose
setup runs well for personal use or small groups, you might encounter performance limitations as your library grows, user count increases, or federation activity intensifies. Scaling Funkwhale involves identifying bottlenecks and potentially distributing its components across different resources or using more efficient backends.
Identifying Bottlenecks
Common areas where performance issues arise:
- CPU:
- Symptoms: Sluggish UI response, slow music scanning/importing, high load average on the server. API and Worker containers are often CPU-intensive.
- Tools:
htop
(on host),docker stats
, monitoring tools (Prometheus/Grafana).
- RAM:
- Symptoms: Services being killed unexpectedly (OOM killer), excessive swapping (if swap is enabled), slow performance. Database (PostgreSQL), cache (Redis), and API/Worker containers can consume significant RAM.
- Tools:
htop
,free -h
,docker stats
, monitoring.
- Disk I/O:
- Symptoms: Slow library scanning, slow streaming start times, slow database queries (if database files are on slow storage). Affects music file storage and database storage.
- Tools:
iotop
(on host),iostat
, monitoring (disk I/O metrics). Using SSDs/NVMe drives significantly helps.
- Network Bandwidth/Latency:
- Symptoms: Buffering during playback (especially for remote users), slow loading of federated content. Depends on server's connection, particularly upload speed.
- Tools:
speedtest-cli
,ping
,traceroute
, browser network developer tools, monitoring (network traffic).
- Database Performance:
- Symptoms: Slow loading of pages heavily reliant on database queries (library browsing, user lists, history), slow API responses.
- Tools: PostgreSQL monitoring (
pg_stat_activity
), slow query logging, database analysis tools (EXPLAIN ANALYZE
).
- Background Task Processing:
- Symptoms: Delays in federation activities, metadata fetching, or other background jobs. The
worker
container might be overwhelmed. - Tools: Funkwhale admin panel (task queues if visible), Celery monitoring tools (like Flower, if set up), worker logs.
- Symptoms: Delays in federation activities, metadata fetching, or other background jobs. The
Scaling Strategies
1. Vertical Scaling (Scaling Up)
The simplest approach: increase the resources allocated to the single server running Funkwhale.
- Add CPU Cores: Upgrade your VPS plan or server hardware.
- Add RAM: Upgrade VPS plan or install more RAM.
- Faster Storage: Migrate to SSD or NVMe drives for the OS, Docker volumes (especially database and music files).
- Faster Network: Upgrade server's network interface or plan.
Pros: Relatively easy to implement, doesn't change the architecture significantly. Cons: Has limits, can become expensive, single point of failure remains.
2. Horizontal Scaling (Scaling Out)
Distribute Funkwhale components across multiple servers or services. This is more complex but offers greater scalability and potentially redundancy.
-
Separate the Database:
- Run PostgreSQL on a dedicated server or use a managed database service (like AWS RDS, Google Cloud SQL).
- Steps:
- Set up the external PostgreSQL server/service.
- Create the Funkwhale database, user, and grant permissions.
- Update the
POSTGRES_HOST
,POSTGRES_PORT
,POSTGRES_USER
,POSTGRES_PASSWORD
,POSTGRES_DB
variables in your Funkwhale.env
file to point to the external database. - Modify
docker-compose.yml
to remove thepostgres
service definition and any dependencies on it (likedepends_on
). - Restart Funkwhale (
docker compose up -d
). Ensure firewall rules allow connection from Funkwhale server to the database server.
- Benefits: Dedicated resources for the database, can scale database independently.
-
Separate Redis:
- Similar to the database, run Redis on a dedicated server or use a managed cache service (like AWS ElastiCache).
- Steps:
- Set up external Redis.
- Update
REDIS_HOST
,REDIS_PORT
,REDIS_PASSWORD
(if needed) in.env
. - Remove the
redis
service fromdocker-compose.yml
. - Restart Funkwhale.
- Benefits: Dedicated resources for caching/task queue brokering.
-
Use External Object Storage for Music Files:
- Store music files in an S3-compatible object storage service (AWS S3, Google Cloud Storage, Backblaze B2, MinIO self-hosted). This is highly recommended for large libraries.
- Steps:
- Set up your object storage bucket and obtain credentials (access key, secret key, endpoint URL, region).
- Configure Funkwhale via
.env
variables:MUSIC_DIRECTORY_SERVE_METHOD=nginx_proxy
(Nginx on Funkwhale server still proxies requests) orremote
(Client connects directly - CORS configuration required on bucket).nginx_proxy
is often simpler initially.MUSIC_DIRECTORY_PATH=funkwhale-music/
(Path/prefix within the bucket).AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY
AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
AWS_STORAGE_BUCKET_NAME=your-funkwhale-bucket-name
AWS_S3_ENDPOINT_URL=https://your-s3-endpoint.com
(Needed for non-AWS S3)AWS_S3_REGION_NAME=your-region
(Optional or required depending on provider)AWS_LOCATION=https://your-s3-endpoint.com/your-funkwhale-bucket-name
(May be needed depending on setup)
- Remove or adjust the local music volume mount in
docker-compose.yml
. You no longer store files locally. - Restart Funkwhale.
- You will need to upload/sync your existing music library to the object storage bucket using a tool like
rclone
oraws s3 sync
. - Trigger a library rescan in Funkwhale (
python manage.py fs_check
or similar might be needed to update paths).
- Benefits: Virtually unlimited and scalable storage, potentially lower cost for storage than block devices, separates storage load from the application server.
-
Increase Number of API/Worker Containers:
- If CPU is the bottleneck on the API or Worker services, you can run multiple instances of these containers behind the Nginx load balancer.
- Steps (Basic Example):
Alternatively, use
# In docker-compose.yml services: api: # ... existing api config ... deploy: # Requires Docker Swarm mode or Kubernetes, or manual scaling replicas: 3 # Run 3 instances of the API container worker: # ... existing worker config ... deploy: replicas: 2 # Run 2 instances of the worker # Nginx config must already be set up to load balance between instances # (The default Funkwhale setup might handle this automatically if scaled this way)
docker compose up --scale api=3 --scale worker=2 -d
. Nginx needs to be configured to load balance between the scaled containers (often handled automatically by Docker's internal networking and the default Nginx config resolving the service name). - Benefits: Distributes CPU load for API processing or background tasks.
3. Caching
- Nginx Caching: Configure Nginx to cache static assets or even API responses (use with caution for dynamic content).
- Opcode Caching: Ensure PHP (if used, less relevant for Python/Django) or Python bytecode caching is effective.
- Database Query Caching: PostgreSQL has internal caches, but ensure sufficient RAM is allocated. Redis is used for application-level caching.
Considerations for Scaling
- Complexity: Horizontal scaling significantly increases deployment complexity.
- Monitoring: Robust monitoring becomes essential to track the performance of distributed components.
- Networking: Ensure low latency and sufficient bandwidth between components (Funkwhale app server, database server, Redis, object storage). Firewalls must allow necessary traffic.
- Cost: While object storage might be cheaper per GB, running multiple servers or managed services incurs costs.
Workshop Setting up MinIO for Object Storage
Goal: Set up a local MinIO server (an S3-compatible self-hosted object storage) using Docker, configure Funkwhale to use it for music storage, and upload a test file.
Prerequisites: Running Funkwhale instance (Docker). Docker and Docker Compose installed. Server terminal access. mc
(MinIO client) installed locally or on the server.
Note: This uses MinIO locally on the same server for demonstration. In a real scaling scenario, MinIO would run on separate hardware.
Steps:
-
Run MinIO Server using Docker:
- Create directories for MinIO data and config on the host:
- Choose access key and secret key (replace
YOUR_MINIO_ACCESS_KEY
andYOUR_MINIO_SECRET_KEY
with strong random strings): - Run the MinIO container:
sudo docker run -d \ -p 9000:9000 \ -p 9001:9001 \ --name minio \ -v /opt/minio/data:/data \ -v /opt/minio/config:/root/.minio \ -e "MINIO_ROOT_USER=${MINIO_ROOT_USER}" \ -e "MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}" \ minio/minio server /data --console-address ":9001"
- This maps port 9000 (API) and 9001 (Console) to the host.
- It mounts host directories for data and config.
- It passes your chosen credentials as environment variables.
-
Access MinIO Console and Create Bucket:
- Open your browser and navigate to
http://your_server_ip:9001
. - Log in using the
MINIO_ROOT_USER
andMINIO_ROOT_PASSWORD
you set. - Click on "Buckets" in the left menu.
- Click "Create Bucket".
- Enter a bucket name (e.g.,
funkwhale-music-bucket
). Bucket names must be DNS compliant (lowercase, no underscores, etc.). - Leave other settings as default for now (Versioning Off, Object Locking Off).
- Click "Create Bucket".
- Open your browser and navigate to
-
Configure Funkwhale for MinIO:
- Edit your Funkwhale
.env
file: - Add or modify the following variables (Important: The
AWS_S3_ENDPOINT_URL
must be reachable from the Funkwhale containers. Since MinIO runs on the host, we often use the host's Docker bridge IP or the host's primary IP. Usinghttp://your_server_ip:9000
is common if Funkwhale containers can reach the host IP):# --- Object Storage Settings --- MUSIC_DIRECTORY_SERVE_METHOD=nginx_proxy # Or 'remote' if you configure CORS on MinIO MUSIC_DIRECTORY_PATH=music/ # Optional: Prefix within the bucket (add trailing slash) AWS_ACCESS_KEY_ID=YOUR_MINIO_ACCESS_KEY # The one you set for MinIO AWS_SECRET_ACCESS_KEY=YOUR_MINIO_SECRET_KEY # The one you set for MinIO AWS_STORAGE_BUCKET_NAME=funkwhale-music-bucket # Your bucket name AWS_S3_ENDPOINT_URL=http://your_server_ip:9000 # ** CRITICAL ** URL to MinIO API AWS_S3_USE_SSL=false # We are using HTTP for local MinIO AWS_S3_REGION_NAME=us-east-1 # MinIO requires a region, us-east-1 is a common default # AWS_LOCATION might be needed depending on serve method and config
- Replace
YOUR_MINIO_ACCESS_KEY
,YOUR_MINIO_SECRET_KEY
,funkwhale-music-bucket
, andhttp://your_server_ip:9000
with your actual values. Using the server's public IP might work, or find the Docker host IP (e.g.,ip addr show docker0
).
- Replace
- Save and close the file.
- Edit your Funkwhale
-
(Optional) Adjust Docker Compose Volume:
- You might want to comment out or remove the local host mapping for
/srv/funkwhale/music
indocker-compose.yml
for theapi
service, as files will now go to S3. However, Funkwhale might still need some local temporary storage path, so test carefully. Leaving the volume might be safer initially.
- You might want to comment out or remove the local host mapping for
-
Restart Funkwhale:
Check logs (sudo docker compose logs api
) for any S3 connection errors. -
Upload a File to MinIO (Using
mc
client):- Install
mc
if you haven't: Follow instructions at https://min.io/docs/minio/linux/reference/minio-mc.html#install-mc - Configure
mc
to connect to your local MinIO: - Create a test file:
echo "test" > test.txt
- Copy the test file to your bucket (use the
MUSIC_DIRECTORY_PATH
if you set one): - Verify in MinIO Console: Refresh the bucket view in the MinIO web UI (
http://your_server_ip:9001
), you should see themusic
prefix (if used) andtest.txt
inside.
- Install
-
Trigger Funkwhale Scan:
- Since we didn't upload via Funkwhale, it doesn't know about the file yet. You may need to trigger a scan or use a management command to synchronize the S3 bucket with Funkwhale's database. The exact command might vary, but try:
# Check available manage commands sudo docker compose exec api python manage.py --help # Look for commands related to storage, S3 sync, or fs_check # Example (may vary): sudo docker compose exec api python manage.py fs_check --library-id 1 # Check filesystem/storage state # Or potentially a dedicated S3 sync command if available
- Alternatively, try uploading a new music file via the Funkwhale web interface (if user uploads are enabled). This will test the full write path to MinIO. If successful, the file should appear in your MinIO bucket.
- Since we didn't upload via Funkwhale, it doesn't know about the file yet. You may need to trigger a scan or use a management command to synchronize the S3 bucket with Funkwhale's database. The exact command might vary, but try:
Outcome: You have set up a local MinIO S3-compatible server and configured Funkwhale to use it as a backend for storing music files. This demonstrates the principle of separating storage, which is a key strategy for scaling Funkwhale to handle large libraries. You've also learned how to interact with MinIO using its client and web console. Remember, for production, MinIO should run on dedicated hardware and likely use HTTPS.
12. Monitoring and Logging
To ensure your Funkwhale instance runs smoothly, identify potential issues proactively, and troubleshoot problems effectively, you need robust monitoring and logging. This involves collecting metrics about system and application performance and analyzing log files for errors or warnings.
Why Monitor?
- Performance Analysis: Identify bottlenecks (CPU, RAM, Disk I/O, Network) before they severely impact user experience.
- Resource Planning: Understand resource usage trends to make informed decisions about scaling (vertical or horizontal).
- Availability: Get alerted if Funkwhale services (API, frontend, database) become unavailable.
- Troubleshooting: Correlate metrics spikes (e.g., high CPU) with specific events or errors found in logs.
- Security: Monitor for unusual activity patterns that might indicate security issues (though dedicated security monitoring tools are better suited for this).
Key Metrics to Monitor
System-Level (Host Server):
- CPU Utilization: Overall percentage, per-core usage, load average.
- RAM Usage: Total used, free, cached, swap usage.
- Disk I/O: Read/write operations per second (IOPS), throughput (MB/s), disk latency, disk space usage (especially for volumes holding Docker data, music, backups).
- Network: Bandwidth usage (in/out), packet loss, latency.
Container-Level (Docker):
- Per-Container Resource Usage: CPU, RAM, Network I/O for
api
,frontend
,nginx
,postgres
,redis
,worker
containers (docker stats
). - Container Health: Uptime, restart counts.
Application-Level (Funkwhale Specific - May require specific exporters or log parsing):
- API Response Times: Average and percentile latencies for API endpoints.
- Request Rate: Number of requests per second to API and frontend.
- HTTP Error Rates: Frequency of 4xx and 5xx errors.
- Database Performance: Query latency, connection count, cache hit rate (requires PostgreSQL monitoring).
- Celery Worker Status: Number of active workers, task queue lengths, task success/failure rates (requires Celery monitoring tools like Flower or Prometheus exporter).
- Federation Activity: Queue sizes, success/failure rates for outgoing/incoming activities.
Monitoring Tools
1. Basic Command-Line Tools (Real-time checks):
htop
: Interactive process viewer (shows CPU, RAM, load, processes). Excellent for quick checks on the host.docker stats
: Real-time resource usage statistics for running containers.iotop
: Disk I/O usage per process (requires installation).iftop
/nethogs
: Network traffic monitoring per connection/process (requires installation).free -h
: Memory usage overview.df -h
: Disk space usage.
2. Comprehensive Monitoring Stacks (Historical data, Dashboards, Alerting):
- Prometheus + Grafana: A very popular open-source combination.
- Prometheus: Time-series database that pulls ("scrapes") metrics from configured targets (exporters).
- Exporters: Small services that expose metrics in Prometheus format. Key exporters:
node-exporter
: Exposes host system metrics (CPU, RAM, Disk, Network).cadvisor
: Exposes container metrics (resource usage, etc.). Often run as a container itself.postgres_exporter
: Exposes PostgreSQL metrics.redis_exporter
: Exposes Redis metrics.- Potentially a Funkwhale/Django/Celery exporter if available, or use log/statsd aggregation.
- Grafana: Visualization platform that queries Prometheus (and other data sources) to create dashboards and graphs.
- Alertmanager: Handles alerts defined in Prometheus based on metric thresholds or conditions.
- Netdata: An all-in-one, real-time monitoring agent with automatic service discovery and pre-built dashboards. Easier setup than Prometheus/Grafana but potentially less flexible for complex alerting and long-term storage configurations. Runs as an agent on the host.
- Zabbix: Another powerful, feature-rich open-source monitoring system with its own agents, server, and web interface.
- Datadog / Dynatrace / New Relic: Commercial SaaS monitoring platforms offering extensive features but with associated costs.
Logging
Logs provide detailed records of events, errors, and activities within the application and its components.
1. Accessing Docker Container Logs:
The primary way to view logs for Funkwhale services running in Docker.
- View Combined Logs (Real-time):
- View Specific Service Logs (Real-time):
- View Older Logs (Not real-time):
2. Key Log Files/Streams to Check:
- Nginx (
nginx
container): Access logs (requests, status codes, user agents) and error logs (proxy errors, configuration issues, SSL problems). Crucial for diagnosing connection problems. - Funkwhale API (
api
container): Django application logs, shows API request processing, errors (5xx), tracebacks, database connection issues, federation processing details. Often the most important log for application-level problems. - Funkwhale Worker (
worker
container): Celery task processing logs, shows background job execution (music scanning, federation sending/receiving), errors during tasks. - Funkwhale Frontend (
frontend
container): Logs related to the web UI server itself (less common to check unless the UI itself fails to load). - PostgreSQL (
postgres
container): Database startup messages, connection errors, potentially slow query logs (if enabled). - Redis (
redis
container): Cache/broker startup, connection issues (less frequently needed for debugging).
3. Centralized Logging (Advanced):
For easier searching and analysis, especially in scaled environments, logs can be forwarded to a central logging system.
- Docker Logging Drivers: Configure Docker daemon or individual containers to use logging drivers like
syslog
,journald
,gelf
,fluentd
, or cloud provider options. - Logging Stacks (ELK/EFK):
- Elasticsearch: Search and analytics engine (stores logs).
- Logstash / Fluentd: Log collection, parsing, and forwarding agents.
- Kibana: Web interface for searching, visualizing, and analyzing logs in Elasticsearch.
- Loki + Promtail + Grafana: A newer stack, often paired with Prometheus. Loki is designed for efficient log aggregation and querying, using Grafana for visualization. Promtail is the log collection agent.
Workshop Setting up Basic Monitoring with docker stats
and htop
Goal: Use basic command-line tools to observe the resource usage of the Funkwhale server and its containers.
Prerequisites: Running Funkwhale instance (Docker). Terminal access to the server. htop
installed (sudo apt install htop
).
Steps:
-
Monitor Host Resources with
htop
:- Open a terminal connection to your Funkwhale server.
- Run
htop
: - Observe:
- CPU Bars: At the top, see the utilization percentage for each CPU core.
- Mem Bar: See total RAM usage (used, buffers, cache).
- Swp Bar: See swap space usage (ideally should be very low or zero).
- Load average: Three numbers representing average system load over 1, 5, and 15 minutes. High numbers (relative to core count) indicate sustained load.
- Process List: See individual processes running on the host. You'll likely see Docker-related processes (
dockerd
) and potentially processes running inside the containers (thoughhtop
shows host-level view). Note CPU% and MEM% used by key processes.
- Press
q
to exithtop
.
-
Monitor Container Resources with
docker stats
:- In the same terminal, run
docker stats
: (Or justdocker stats
if your user is in the docker group) - Observe: A live-updating table showing key metrics for each running container:
- CONTAINER ID: Unique identifier.
- NAME: Service name (e.g.,
funkwhale-docker-api-1
,funkwhale-docker-postgres-1
). - CPU %: Percentage of total host CPU capacity the container is currently using.
- MEM USAGE / LIMIT: How much RAM the container is using versus its limit (if set).
- MEM %: Percentage of the host's total RAM the container is using.
- NET I/O: Network data received and sent by the container.
- BLOCK I/O: Disk reads and writes performed by the container.
- PIDS: Number of processes running inside the container.
- Interact: While
docker stats
is running, open Funkwhale in your browser and perform some actions (play music, browse library, maybe trigger a small scan if possible). Watch how the resource usage for different containers (especiallyapi
,nginx
,postgres
,worker
) changes indocker stats
. - Press
Ctrl+C
to exitdocker stats
.
- In the same terminal, run
-
Check Specific Container Logs:
- Let's look for potential issues in the API logs. View the last 50 lines:
# Ensure you are in the funkwhale-docker directory cd /opt/funkwhale-docker sudo docker compose logs --tail=50 api
- Scan the output for any lines containing
ERROR
,WARNING
,Traceback
, or other indications of problems.
- Scan the output for any lines containing
- Now, follow the Nginx logs in real-time while accessing Funkwhale:
- Access your Funkwhale instance in the browser, click around. You should see access log entries appear in the terminal (showing requested URLs, status codes like 200 or 304). Look out for any 4xx or 5xx error codes.
- Press
Ctrl+C
to stop following the Nginx logs.
- Let's look for potential issues in the API logs. View the last 50 lines:
Outcome: You have used standard command-line tools (htop
, docker stats
, docker compose logs
) to get a basic, real-time overview of system and container resource usage, and to inspect recent log entries for key Funkwhale services. This provides a foundation for quick troubleshooting and performance assessment. For continuous monitoring and alerting, setting up a system like Prometheus+Grafana or Netdata would be the next step.
13. Customization and Theming
While Funkwhale provides a clean and functional user interface out of the box, you might want to personalize its appearance to match your brand, preferences, or just for fun. Customization options range from simple CSS tweaks to potentially more involved theme development (though the latter is often less straightforward).
Methods of Customization
1. Custom CSS (Recommended & Easiest)
Funkwhale allows administrators to inject custom CSS rules directly via the administration interface. This is the safest and most supported way to override styles without modifying core code.
- How it works: You write standard CSS rules that target elements in the Funkwhale UI. These rules are loaded after the default stylesheets, allowing you to override existing styles or add new ones.
- Finding Selectors: Use your browser's Developer Tools (F12) heavily. Right-click on the element you want to change and select "Inspect" or "Inspect Element". The Developer Tools will show you the HTML structure and the CSS rules currently applied to that element, including its classes and IDs, which you can use as selectors in your custom CSS.
-
Applying Custom CSS:
- Log in as administrator.
- Navigate to
Administration -> Settings -> Instance
(or sometimes a dedicatedAppearance
orCustomization
section, depending on the Funkwhale version). - Look for a text area labeled "Custom CSS" or similar.
- Paste your CSS rules into this box.
- Save the settings.
- Refresh your Funkwhale browser window (you might need to clear cache: Ctrl+Shift+R or Cmd+Shift+R) to see the changes.
-
Example Custom CSS:
/* --- Example Funkwhale Custom CSS --- */ /* Change the main background color */ body, .body { background-color: #f0f2f5; /* Light grey background */ } /* Change the header background color */ .navbar.is-fixed-top, .main-header { background-color: #333 !important; /* Dark grey header */ border-bottom: 1px solid #555; } /* Change header text color */ .navbar-item, .navbar-link, .site-title a { color: #eee !important; /* Light text on dark header */ } .navbar-item:hover, .navbar-link:hover, .site-title a:hover { color: #fff !important; background-color: #444 !important; } /* Change primary button background color */ .button.is-primary { background-color: #d93f87 !important; /* Funkwhale-ish pink */ border-color: transparent; } .button.is-primary:hover { background-color: #c82a75 !important; } /* Make album titles larger in the grid view */ .album-grid-item .album-title { font-size: 1.1em; font-weight: bold; } /* Hide the "Explore" or specific sidebar items if desired (use Inspector to find correct selector) */ /* .sidebar-menu li a[href='/explore'] { display: none; } */
-
Tips:
- Use
!important
sparingly, but it's often necessary to override highly specific default styles. - Test thoroughly in different browsers and screen sizes.
- Keep your custom CSS organized with comments.
- Start small and make incremental changes.
- Use
2. Modifying Frontend Code / Building Themes (Advanced & Fragile)
This involves directly changing the Funkwhale frontend code (likely Vue.js components and associated CSS/SCSS files) or attempting to create a full theme.
-
Challenges:
- Complexity: Requires frontend development knowledge (Vue.js, JavaScript, CSS/SCSS, build tools like Node.js/npm/yarn).
- Maintenance Burden: Your changes will likely conflict with future Funkwhale updates. You'll need to manually re-apply or adapt your modifications after each update, which can be time-consuming and error-prone.
- No Official Theme System (Historically): Funkwhale hasn't always had a well-defined, stable theme API like some other platforms (e.g., WordPress). Efforts may exist or be underway, but check the current project status.
- Build Process: You'd need to set up a development environment, modify the source code, and re-build the frontend assets.
- Deployment: You'd need to replace the default frontend container image with one containing your modified build.
-
Approach (High Level):
- Clone the Funkwhale frontend repository.
- Set up the development environment (Node.js, dependencies via
npm install
oryarn install
). - Locate the relevant Vue components or SCSS files you want to change.
- Make your modifications.
- Build the production assets (
npm run build
or similar). - Create a custom Dockerfile that takes the base Funkwhale frontend image and replaces the built assets with your custom ones.
- Build your custom Docker image.
- Update your
docker-compose.yml
to use your custom frontend image instead of the official one.
-
Recommendation: Unless you are a frontend developer prepared to maintain a fork or adapt to frequent changes, stick to the Custom CSS method. The effort and fragility of modifying the core code are generally not worth it for purely aesthetic changes.
Instance Branding
Beyond CSS, consider these elements for branding:
- Instance Name and Description: Set these clearly in
Administration -> Settings -> Instance
. - Favicon/Logo: While direct upload isn't always available, sometimes the favicon might be replaceable via Nginx rules or by overriding specific image assets (again, potentially fragile). Custom CSS might allow replacing a logo element's background image. Check the current capabilities.
- Terms of Service / About Page: If your instance is public, provide clear information about its purpose and rules.
Workshop Applying Custom CSS to Change Header Color
Goal: Use the Custom CSS feature to change the background color of the Funkwhale header/navigation bar.
Prerequisites: Logged into Funkwhale as an administrator.
Steps:
-
Identify Header Element:
- Open your Funkwhale instance in your browser.
- Right-click directly on the top navigation bar (where the logo, search, and user menu are).
- Select "Inspect" or "Inspect Element".
- The Developer Tools will open. Examine the highlighted HTML element and its parent elements. Look for classes like
navbar
,main-header
,is-fixed-top
, or similar IDs/classes associated with the main top bar. Note down a reliable selector (e.g.,.navbar.is-fixed-top
or.main-header
).
-
Navigate to Custom CSS Setting:
- In Funkwhale, go to
Administration -> Settings -> Instance
. - Scroll down to find the "Custom CSS" text area.
- In Funkwhale, go to
-
Add CSS Rule:
- Paste the following CSS rule into the text area. Replace
.navbar.is-fixed-top
if you identified a different primary selector in step 1./* Change header background */ .navbar.is-fixed-top { background-color: #2c3e50 !important; /* A dark blue-grey color */ } /* Adjust text color for better contrast (might need more specific selectors) */ .navbar.is-fixed-top .navbar-item, .navbar.is-fixed-top .navbar-link { color: #ecf0f1 !important; /* Light grey text */ } .navbar.is-fixed-top .navbar-item:hover, .navbar.is-fixed-top .navbar-link:hover { color: #fff !important; background-color: #34495e !important; /* Slightly lighter blue-grey on hover */ }
- We use
!important
here to increase the likelihood of overriding the default styles.
- Paste the following CSS rule into the text area. Replace
-
Save Changes:
- Scroll down and click the "Save changes" button.
-
Observe the Result:
- Refresh your Funkwhale browser page (use Ctrl+Shift+R or Cmd+Shift+R to bypass cache).
- The top navigation bar should now have the new dark blue-grey background color and adjusted text color.
-
Experiment (Optional):
- Try changing the color value (
#2c3e50
) to something else (e.g.,#e74c3c
for red,#27ae60
for green). - Use the Inspector tool again to find selectors for other elements (like buttons, links, body background) and try modifying them via the Custom CSS setting. Remember to save and refresh after each change.
- Try changing the color value (
Outcome: You have successfully used Funkwhale's built-in Custom CSS feature to modify the appearance of the user interface without touching any core code, demonstrating a safe and maintainable way to personalize your instance.
14. Troubleshooting Common Issues
Even with careful setup, you might encounter issues while running Funkwhale. This section outlines common problems and systematic approaches to diagnose and resolve them.
General Troubleshooting Strategy
- Identify the Symptom: What exactly is not working? Be specific. (e.g., "Cannot log in", "Music playback buffers", "Federation with instance X fails", "502 Bad Gateway error").
- Check Logs: This is almost always the first step. Examine the logs of the relevant containers (
nginx
,api
,worker
,postgres
) around the time the issue occurred. Usesudo docker compose logs -f <service_name>
orsudo docker compose logs --tail=N <service_name>
. Look forERROR
,WARNING
,FATAL
,Traceback
. - Check Container Status: Are all containers running? Use
sudo docker compose ps
. If a container is restarting frequently or exited, check its logs immediately. - Check System Resources: Is the server overloaded? Use
htop
anddf -h
to check CPU, RAM, and disk space. Resource exhaustion is a common cause of instability. - Check Network Connectivity:
- Can the server resolve DNS?
ping google.com
- Can the server reach external services if needed (e.g., object storage endpoint, other federated instances)?
curl -v <url>
- Is the firewall blocking necessary ports (80, 443, maybe database/redis ports if external)?
sudo ufw status
- Are DNS records for your Funkwhale domain pointing correctly?
dig your.funkwhale.domain
- Can the server resolve DNS?
- Verify Configuration: Double-check your
.env
file for typos, correct hostnames, ports, passwords, and keys. Ensure Nginx custom configurations (nginx/user_conf.d/
) have correct syntax (docker compose exec nginx nginx -t
). - Consult Documentation and Community: Check the official Funkwhale documentation (https://docs.funkwhale.audio/) for troubleshooting guides. Search the Funkwhale issue tracker (https://dev.funkwhale.audio/) or ask in community forums/chat (Matrix) for similar problems.
Common Problems and Solutions
1. 502 Bad Gateway Error
- Symptom: Browser shows an "502 Bad Gateway" error, usually from Nginx.
- Meaning: Nginx (the reverse proxy) cannot connect to the upstream service it's trying to forward the request to (usually the
api
orfrontend
container). - Troubleshooting:
- Check
api
/frontend
container status:sudo docker compose ps
. Is the relevant container running? If not, check its logs (sudo docker compose logs api
) to see why it failed to start or crashed. Common causes include database connection issues, configuration errors, or resource exhaustion. - Check Nginx logs:
sudo docker compose logs nginx
. Look for error messages likeconnect() failed
,(111: Connection refused)
, orupstream prematurely closed connection
indicating problems talking to the backend. - Check Docker Networking: Ensure containers are on the same Docker network and can reach each other. Usually handled automatically by
docker-compose
. - Check Resource Usage: Is the
api
container overloaded (high CPU/RAM indocker stats
) and unable to respond?
- Check
2. Cannot Log In / Invalid Credentials
- Symptom: Entering correct username/password results in "Invalid credentials" or similar error.
- Troubleshooting:
- Password Reset: Try resetting the password using the "Forgot password" link (requires email (SMTP) to be configured correctly in
.env
). - Admin Password Reset (CLI): If admin login fails or email isn't set up, reset via command line: Follow the prompts to set a new password.
- Check
api
Logs: Look for errors during the login attempt. - Database Connection: Ensure the
api
container can connect to the database (check logs, verify.env
DB settings).
- Password Reset: Try resetting the password using the "Forgot password" link (requires email (SMTP) to be configured correctly in
3. Music Upload/Import Fails
- Symptom: Uploading via web UI fails, or CLI
import_files
scan shows errors. - Troubleshooting:
- Check
worker
andapi
Logs: Scans and imports are often handled by background workers. Check both logs for errors related to file processing, metadata extraction, or database insertion. - File Permissions: This is very common. Ensure the directory on the host server where music files reside (e.g.,
/opt/funkwhale-docker/data/music/
) and the files themselves are readable (and directories traversable) by the user ID that the Funkwhaleapi
andworker
containers run as (often UID 991 or 1000). Usesudo chown -R <UID>:<GID> /path/to/music
andsudo chmod -R u+rwX,go+rX /path/to/music
. Check the UID inside the container:sudo docker compose exec api id
. - Disk Space: Is the volume holding the music files or the database full?
df -h
- Upload Size Limit: If uploading via web UI, check
NGINX_MAX_BODY_SIZE
in.env
and potentially related Nginx (client_max_body_size
) and Funkwhale API settings. Check Nginx error logs for "client request body too large" errors. - Object Storage Issues: If using S3/MinIO, check
api
/worker
logs for S3 connection errors. Verify credentials, endpoint URL, bucket name, and permissions in.env
. Ensure Funkwhale containers can reach the S3 endpoint URL. Check bucket permissions/policies. - Corrupt Files/Unsupported Formats: An individual problematic file can sometimes halt or disrupt scanning. Check logs for mentions of specific filenames.
- Check
4. Music Playback Issues (Buffering, Stuttering, Not Starting)
- Symptom: Music doesn't play smoothly or fails to start.
- Troubleshooting:
- Check
nginx
Access Logs: Look at the requests for the audio files. Are they returning status200
(OK) or206
(Partial Content)? Are there errors? - Check
api
Logs: Any errors related to generating streaming URLs or accessing files? - Server Network Upload Speed: Is the server's upload bandwidth sufficient for the bitrate of the music being streamed, especially for multiple users? Run a speed test from the server.
- Client Network Download Speed: Is the user's internet connection fast enough?
- Server Resource Usage: Is the server overloaded (CPU/Disk I/O)? High disk I/O latency can cause stuttering. Use
htop
,iotop
. - Object Storage Performance: If using S3/MinIO, is the object storage responsive? Check its performance/latency.
- Browser/Client Issues: Try playback in a different browser or Subsonic client. Check browser developer console for errors.
- Check
5. Federation Problems
- Symptom: Cannot follow remote users, remote content not appearing, other instances cannot see yours.
- Troubleshooting:
- HTTPS and Domain: Federation requires a valid, publicly trusted HTTPS certificate and correct
FUNKWHALE_HOSTNAME
in.env
. Ensure your instance is accessible viahttps://your.funkwhale.domain
from the public internet. - Check
worker
Logs: Federation tasks run in the background. Look for errors related to sending/receiving ActivityPub messages, connecting to remote instances, or processing activities. - Check
api
Logs: May show errors related to fetching remote actor information or handling incoming requests. - Firewall: Ensure port 443 is open and correctly forwarded to the Nginx container.
- Reachability: Can your server resolve and connect to the remote instance's domain?
curl -v https://remote.instance.domain/.well-known/host-meta
(or similar ActivityPub discovery endpoints). - Remote Instance Issues: The problem might be on the other instance (offline, firewall, misconfiguration).
- Admin Federation Panel: Check
Administration -> Federation
for blocked instances or error queues (if available).
- HTTPS and Domain: Federation requires a valid, publicly trusted HTTPS certificate and correct
6. Let's Encrypt Certificate Renewal Failure
- Symptom: HTTPS becomes unavailable, browser shows certificate expired warnings.
- Troubleshooting:
- Check Certbot Logs: The renewal process is usually handled by Certbot running inside the
nginx
container (or a dedicated sidecar). Check the Nginx container logs around the time renewal should have happened (certificates are valid 90 days, renewal typically attempted around 60 days).sudo docker compose logs nginx | grep -i 'certbot\|renewal'
- Run Renewal Manually: Try running the renewal command manually inside the container (see Section 5 for example commands, adapt as needed): Observe the output for errors (e.g., connection timeouts, challenge failures).
- Port 80 Accessibility: The default HTTP-01 challenge requires your server to be reachable on port 80 from the public internet (Let's Encrypt servers need to connect). Ensure port 80 is open in your firewall and correctly mapped to the Nginx container. Sometimes temporary firewall rules or stopping conflicting services might be needed during renewal.
- DNS Issues: Ensure your domain still points correctly to the server's IP address.
- Rate Limits: If you've had many failed attempts, you might hit Let's Encrypt rate limits. Wait or use the
--staging
flag for testing.
- Check Certbot Logs: The renewal process is usually handled by Certbot running inside the
Workshop Diagnosing a 502 Bad Gateway Error
Goal: Simulate and troubleshoot a common 502 Bad Gateway error caused by stopping the backend API container.
Prerequisites: Running Funkwhale instance (Docker). Terminal access.
Steps:
-
Verify Normal Operation:
- Access your Funkwhale instance (
https://your.funkwhale.domain
) in your browser. Ensure it loads correctly. - Check container status:
(Confirm
api
,frontend
,nginx
, etc., are 'running' or 'Up')
- Access your Funkwhale instance (
-
Simulate the Failure:
- Manually stop only the API container:
- Wait a few seconds.
-
Observe the Symptom:
- Refresh your Funkwhale browser tab or try navigating to a new page within Funkwhale.
- You should now see an error page, likely displaying "502 Bad Gateway" (the exact appearance depends on Nginx/browser).
-
Troubleshoot - Step 1: Check Container Status:
- Run
sudo docker compose ps
again. - Observe: You should see that the
api
container now has a State ofexited
or similar, whilenginx
is likely stillrunning
. This immediately points to theapi
service as the problem.
- Run
-
Troubleshoot - Step 2: Check Nginx Logs:
- View the Nginx logs to see how it reacted:
- Observe: Look for recent error messages (often prefixed with
[error]
). You should see entries similar to:*123 connect() failed (111: Connection refused) while connecting to upstream, client: [client_ip], server: your.funkwhale.domain, request: "GET /api/v1/... HTTP/1.1", upstream: "http://[api_container_ip]:5000/api/v1/...", host: "your.funkwhale.domain"
This confirms Nginx tried to connect to theapi
service (upstream
) but was refused because the service wasn't running.
-
Troubleshoot - Step 3: Check API Logs (Why did it stop?):
- In this simulation, we stopped it. But in a real scenario, you'd check why it stopped:
- Observe: Since we stopped it gracefully, the logs might just show shutdown messages. In a real crash, you'd look for error messages or tracebacks occurring just before the container exited.
-
Resolve the Issue:
- Start the API container again:
- Wait a few seconds for it to initialize. Verify it's running:
sudo docker compose ps
.
-
Verify Resolution:
- Refresh your Funkwhale browser tab.
- The Funkwhale interface should now load correctly, and the 502 error should be gone.
Outcome: You have successfully simulated a common 502 error, used logs (nginx
, api
) and container status checks (docker compose ps
) to diagnose the root cause (stopped api
container), and resolved the issue by restarting the service. This demonstrates a basic but effective troubleshooting workflow.
15. Alternative Installation Methods (Bare Metal - Overview)
While Docker provides significant advantages in simplicity and dependency management, some users prefer or require a "bare metal" installation, meaning installing Funkwhale and its dependencies directly onto the host operating system without containerization.
Disclaimer: Bare metal installation is significantly more complex than using Docker, requires careful manual dependency management, and is more prone to conflicts with other software on the host. It demands a deeper understanding of Linux system administration, Python environments, web server configuration (Nginx/Apache), and database management (PostgreSQL). This section provides only a high-level overview and is not a step-by-step guide. Refer to the official Funkwhale documentation for detailed bare metal instructions if you choose this path.
Why Consider Bare Metal? (Potential Reasons)
- Resource Constraints: On extremely low-resource systems (e.g., very old Raspberry Pi models), the overhead of Docker might be a concern, though this is often minimal on modern systems.
- Existing Infrastructure: You might already have Nginx, PostgreSQL, and Redis running natively on the server for other applications and prefer to integrate Funkwhale into that existing stack.
- Deep Customization/Debugging: Direct access to all components without Docker layers can sometimes simplify very low-level debugging or customization (though it also increases complexity).
- Personal Preference/Learning: Some users simply prefer managing software directly on the host or want to learn the intricacies of the full stack.
Core Components and Dependencies
A bare metal Funkwhale installation typically involves manually installing and configuring:
- Python Environment:
- Specific Python version required by Funkwhale (e.g., Python 3.8+).
pip
(Python package installer).virtualenv
orvenv
(Essential for isolating Funkwhale's Python dependencies from system-wide packages).
- System Build Dependencies: Numerous development libraries needed to compile Python packages (e.g.,
build-essential
,libpq-dev
,libffi-dev
,libssl-dev
,libxml2-dev
,libxslt1-dev
, media processing libraries likeffmpeg
,libtag1-dev
, etc.). The exact list is long and OS-dependent. - PostgreSQL Server: Install and configure PostgreSQL, create a dedicated database and user for Funkwhale.
- Redis Server: Install and configure Redis (used for caching and Celery message broker).
- Nginx (or Apache): Install and configure a web server to act as a reverse proxy, handle SSL/TLS, and serve static files. Requires manual configuration similar to the Nginx setup within Docker, but applied directly to the host's Nginx setup.
- Certbot: Install Certbot manually for Let's Encrypt certificate management.
- Celery: Funkwhale's background task queue system. Needs to be run as a separate service.
- Funkwhale Application Code: Clone the Funkwhale source code repository (
git clone
). - Python Dependencies: Install all required Python packages listed in Funkwhale's
requirements.txt
(or similar) within the virtual environment usingpip
.
General Installation Flow (Conceptual)
- Prepare Server: Install OS, basic security, system build dependencies.
- Install Core Services: Install PostgreSQL, Redis, Nginx/Apache.
- Set up Database: Create Funkwhale database and user in PostgreSQL.
- Set up Python Environment: Install required Python version, create a virtual environment (e.g., in
/opt/funkwhale/env
). - Get Funkwhale Code: Clone the Funkwhale repository (e.g., to
/opt/funkwhale/app
). - Install Python Dependencies: Activate the virtual environment (
source /opt/funkwhale/env/bin/activate
) and runpip install -r requirements.txt
. - Configure Funkwhale: Create a configuration file (similar to
.env
but often a Python file likeconfig.py
or environment variables sourced by systemd) containing database credentials, Redis details, secret key, hostname, etc. - Database Migrations: Run Funkwhale's database migration command (
python manage.py migrate
) within the virtual environment. - Collect Static Files: Run
python manage.py collectstatic
to gather static assets (CSS, JS) into a designated directory. - Configure Web Server (Nginx/Apache): Create a virtual host configuration:
- Serve static files collected in the previous step.
- Proxy requests to the Funkwhale application (which needs to be run as a service, often using
gunicorn
oruwsgi
). - Configure SSL/TLS using Certbot.
- Configure Process Management (Systemd): Create systemd service units to manage:
- The Funkwhale web application process (e.g.,
gunicorn
running the Django app). - The Funkwhale Celery worker process (
celery
running background tasks). - Ensure these services start on boot and restart on failure.
- The Funkwhale web application process (e.g.,
- Configure Log Rotation: Set up
logrotate
for Funkwhale, Nginx, and Celery logs to prevent them from filling up the disk. - Initial Setup: Create the admin user (
python manage.py createsuperuser
). - Start Services: Enable and start the
nginx
/apache2
,postgresql
,redis-server
, and your custom Funkwhale systemd services.
Challenges ("Dependency Hell")
The biggest challenge is managing dependencies. System packages might conflict with Python package requirements, different Python packages might require conflicting versions of sub-dependencies, and ensuring all build tools and libraries are present for successful pip install
can be tedious. Updates to the OS or Funkwhale can break the installation if dependencies change. This is precisely the problem Docker solves by isolating the application and its dependencies.
Conclusion on Bare Metal
Unless you have a compelling reason and the necessary expertise and time for ongoing maintenance, the Docker installation method is strongly recommended for its simplicity, reproducibility, and easier updates. Bare metal offers ultimate control but comes at the cost of significantly increased complexity and maintenance effort.
Workshop Exploring Bare Metal Dependencies (Conceptual)
Goal: Understand the type and number of dependencies involved in a bare metal setup by examining Funkwhale's requirements and typical system prerequisites (without actually installing).
Prerequisites: Terminal access to a Linux system (Debian/Ubuntu preferred for this example). git
installed.
Steps:
-
Clone Funkwhale Repository: Clone the main Funkwhale backend repository to examine its requirements.
-
Examine Python Requirements: Funkwhale lists its direct Python dependencies in requirement files.
# View the main production requirements cat requirements/base.txt # View development requirements (often includes tools for testing, building) # cat requirements/dev.txt
- Observe: Note the number of packages listed (Django, Celery, psycopg2-binary, requests, Pillow, etc.). Each of these might, in turn, depend on other Python packages, creating a large dependency tree that
pip
manages. Also note potential version specifiers (e.g.,Django>=3.2,<3.3
).
- Observe: Note the number of packages listed (Django, Celery, psycopg2-binary, requests, Pillow, etc.). Each of these might, in turn, depend on other Python packages, creating a large dependency tree that
-
Examine System Dependency Documentation (Simulated):
- Imagine looking at the official Funkwhale bare metal installation guide (you can search for this on
docs.funkwhale.audio
). - You would typically find sections listing required
apt
(Debian/Ubuntu) oryum
/dnf
(Fedora/CentOS) packages. - Examples you would likely see:
python3 python3-pip python3-venv python3-dev
(Core Python tools)build-essential pkg-config
(Compiler toolchain)libpq-dev
(PostgreSQL development headers forpsycopg2
)libffi-dev libssl-dev
(Cryptography and foreign function interface headers)libxml2-dev libxslt1-dev
(XML/XSLT processing headers)ffmpeg libtag1-dev
(Audio/video processing and tagging libraries)gettext
(Internationalization tools)postgresql redis-server nginx certbot
(The main external services)
- Observe: Recognize that this list can be quite long and specific. Installing the wrong version or missing a single development header can cause
pip install
for certain Python packages to fail with cryptic compilation errors.
- Imagine looking at the official Funkwhale bare metal installation guide (you can search for this on
-
Consider Service Configuration:
- Mentally walk through configuring Nginx manually: creating server blocks, setting up
proxy_pass
to a Gunicorn/uWSGI socket or port, handling static files, configuring SSL with Certbot. - Think about writing systemd unit files: defining users, working directories, environment variables/config file paths, ExecStart commands (e.g.,
gunicorn funkwhale.config.wsgi ...
,celery -A funkwhale.config worker ...
), restart policies. - Consider PostgreSQL setup: creating users/databases via
psql
.
- Mentally walk through configuring Nginx manually: creating server blocks, setting up
-
Reflect on Updates:
- Imagine Funkwhale releases a new version requiring a newer Django version or a new system dependency. You would need to:
- Stop Funkwhale services.
- Update system dependencies (
apt upgrade ...
). - Activate the virtual environment.
- Pull the latest Funkwhale code (
git pull
). - Update Python dependencies (
pip install -r requirements.txt
). Resolve any new conflicts. - Run database migrations (
python manage.py migrate
). - Update static files (
python manage.py collectstatic
). - Potentially update Nginx or systemd configurations if required by the new version.
- Restart services and test thoroughly.
- Compare this to the Docker update process (usually: update
.env
if needed,docker compose pull
,docker compose up -d
).
- Imagine Funkwhale releases a new version requiring a newer Django version or a new system dependency. You would need to:
Outcome: By examining the requirement files and mentally simulating the configuration steps, you gain an appreciation for the number and variety of dependencies involved in a bare metal Funkwhale installation and the increased complexity compared to the containerized Docker approach, particularly concerning dependency management and updates.
Conclusion
Self-hosting Funkwhale empowers you to take full control of your music library, privacy, and listening experience. We've journeyed from the fundamental concepts and basic server preparation through installation with Docker, initial configuration, user management, library handling, and the unique possibilities offered by ActivityPub federation. We also delved into intermediate topics like securing your instance with HTTPS, implementing backup strategies, and advanced areas such as Nginx customization, scaling techniques, monitoring, and theming.
While the Docker-based installation significantly simplifies the process, running any self-hosted service requires ongoing attention – applying updates, monitoring resources, managing backups, and occasionally troubleshooting issues. The workshops provided practical steps to reinforce the theoretical knowledge, equipping you with the hands-on skills needed to manage your own Funkwhale pod successfully.
Whether you run a small private instance for personal use or a larger federated pod for a community, Funkwhale offers a rewarding alternative to mainstream streaming services. Embrace the freedom, privacy, and community aspects of decentralized music streaming! Remember to consult the official Funkwhale documentation and engage with its community for the latest information and support. Happy hosting!