Instance configuration

General configuration is achieved using two type of settings:

Environment variables

Those are located in your .env file, which you should have created during installation. A full list of available variables is given below.

Options from this file are heavily commented, and usually target lower level and technical aspects of your instance, such as database credentials.


You should restart all Funkwhale processes when you change the values on environment variables:

sudo systemctl restart


Some characters are unsafe to use in configuration variables that are URLs, such as the user and password in the database and SMTP sections. If those variables contain such characters, they must be urlencoded, for instance using the following command:

python3 -c 'import urllib.parse; print(urllib.parse.quote_plus("p@ssword"))

See as well

Instance settings

These settings are stored in the database and do not require a restart of your instance after modification. They typically relate to higher level configuration, such your instance description, signup policy and so on.

You can edit those settings directly from the web application, assuming you have the required permissions. The URL is /manage/settings, and you will also find a link to this page in the sidebar.

If you plan to use acoustid and external imports (e.g. with the YouTube backends), you should edit the corresponding settings in this interface.


If you have any issue with the web application, a management interface is also available for those settings from Django’s administration interface. It’s less user friendly, though, and we recommend you use the web app interface whenever possible.

The URL should be /api/admin/dynamic_preferences/globalpreferencemodel/ (prepend your domain in front of it, of course).

Configuration reference



Hostname of your Funkwhale pod, e.g.


Protocol end users will use to access your pod, either http or https.

Database and redis


URL to connect to the PostgreSQL database. Examples:

  • postgresql://funkwhale@:5432/funkwhale

  • postgresql://<user>:<password>@<host>:<port>/<database>

  • postgresql://funkwhale:passw0rd@localhost:5432/funkwhale_database


Max time, in seconds, before database connections are closed.


URL to your redis server. Examples:

  • redis://<host>:<port>/<database>

  • redis://

  • redis://:password@localhost:6379/0

for password auth (the extra semicolon is important) - redis:///run/redis/redis.sock?db=0 over unix sockets


If you want to use Redis over unix sockets, you’ll also need to update CELERY_BROKER_URL


URL to celery’s task broker. Defaults to CACHE_URL, so you shouldn’t have to tweak this, unless you want to use a different one, or use Redis sockets to connect.


  • redis://

  • redis+socket:///run/redis/redis.sock?virtual_host=0

Accounts and registration


Determine wether users need to verify their e-mail address before using the service. Enabling this can be useful to reduce spam or bots accounts, however, you’ll need to configure a mail server so that your users can receive the verification e-mails, using EMAIL_CONFIG.

Note that regardless of the setting value, superusers created through the command line will never require verification.

Note that regardless of the setting value, superusers created through the command line will never require verification.


Expiration delay, in days, for user invitations.


Wether to disable password validators (length, common words, similarity with username…) used during regitration.


List of usernames that will be unavailable during registration, given as a list of strings.


Wether to enable LDAP authentication.

See /installation/ldap for more information.

Media storage and serving


URL where media files are served. The default value should work fine on most configurations, but could can tweak this if you are hosting media files on a separate domain, or if you host Funkwhale on a non-standard port.

MEDIA_ROOT = /srv/funkwhale/data/media

Path where media files (such as album covers or audio tracks) are stored on your system. Ensure this directory actually exists.


Wether to proxy audio files through your reverse proxy. It’s recommended to keep this on, as a way to enforce access control, however, if you’re using S3 storage with AWS_QUERYSTRING_AUTH, it’s safe to disable it.


Wether to proxy attachment files hosted on third party pods and and servers. Keeping this to true is recommended, to reduce leaking browsing information of your users, and reduce the bandwidth used on remote pods.


Delay in seconds before uploaded but unattached attachements are pruned from the system.


Depending on the reverse proxy used in front of your funkwhale instance, the API will use different kind of headers to serve audio files

Allowed values: nginx, apache2

PROTECT_FILES_PATH = '/_protected'

Which path will be used to process the internal redirection to the reverse proxy DO NOT put a slash at the end.

You shouldn’t have to tweak this.

Audio acquisition


The path on your server where Funkwhale can import files using in-place import. It must be readable by the webserver and Funkwhale api and worker processes.

On docker installations, we recommend you use the default of /music for this value. For non-docker installation, you can use any absolute path. /srv/funkwhale/data/music is a safe choice if you don’t know what to use.


This path should not include any trailing slash.


You need to adapt your reverse proxy configuration to serve the directory pointed by MUSIC_DIRECTORY_PATH on /_protected/music URL.



When using Docker, the value of MUSIC_DIRECTORY_PATH in your containers may differ from the real path on your host. Assuming you have the following directive in your docker-compose.yml file:

  - /srv/funkwhale/data/music:/music:ro

Then, the value of MUSIC_DIRECTORY_SERVE_PATH should be /srv/funkwhale/data/music. This must be readable by the webserver.

On non-docker setup, you don’t need to configure this setting.


This path should not include any trailing slash.

S3 Storage


Whether to include signatures in S3 urls, as a way to enforce access-control.

Defaults to the inverse of PROXY_MEDIA.


Expiration delay, in seconds, of signatures generated when AWS_QUERYSTRING_AUTH is enabled.

AWS_ACCESS_KEY_ID = 'my_access_key'

Access-key ID for your S3 storage.

AWS_SECRET_ACCESS_KEY = 'my_secret_key'

Secret access key for your S3 storage.


Bucket name of your S3 storage.


Custom domain to use for your S3 storage.


If you use a S3-compatible storage such as minio, set the following variable to the full URL to the storage server. Example:




If you are using Amazon S3 to serve media directly, you will need to specify your region name in order to access files.


  • eu-west-2


An optional bucket subdirectory were you want to store the files. This is especially useful if you plan to use share the bucket with other services.

API configuration


Wether to enable throttling (also known as rate-limiting). Leaving this enabled is recommended especially on public pods, to improve the quality of service.

THROTTLING_RATES = {'anonymous-create': {'description': 'Anonymous POST requests', 'rate': '1000/day'}, 'anonymous-destroy': {'description': 'Anonymous DELETE requests on resource detail', 'rate': '1000/day'}, 'anonymous-list': {'description': 'Anonymous GET requests on resource lists', 'rate': '10000/day'}, 'anonymous-oauth-app': {'description': 'Anonymous OAuth app creation', 'rate': '10/day'}, 'anonymous-reports': {'description': 'Anonymous report submission', 'rate': '10/day'}, 'anonymous-retrieve': {'description': 'Anonymous GET requests on resource detail', 'rate': '10000/day'}, 'anonymous-update': {'description': 'Anonymous PATCH and PUT requests on resource detail', 'rate': '1000/day'}, 'anonymous-wildcard': {'description': 'Anonymous requests not covered by other limits', 'rate': '1000/h'}, 'authenticated-create': {'description': 'Authenticated POST requests', 'rate': '1000/hour'}, 'authenticated-destroy': {'description': 'Authenticated DELETE requests on resource detail', 'rate': '500/hour'}, 'authenticated-list': {'description': 'Authenticated GET requests on resource lists', 'rate': '10000/hour'}, 'authenticated-oauth-app': {'description': 'Authenticated OAuth app creation', 'rate': '10/hour'}, 'authenticated-reports': {'description': 'Authenticated report submission', 'rate': '100/day'}, 'authenticated-retrieve': {'description': 'Authenticated GET requests on resource detail', 'rate': '10000/hour'}, 'authenticated-update': {'description': 'Authenticated PATCH and PUT requests on resource detail', 'rate': '1000/hour'}, 'authenticated-wildcard': {'description': 'Authenticated requests not covered by other limits', 'rate': '2000/h'}, 'fetch': {'description': 'Fetch remote objects', 'rate': '200/d'}, 'login': {'description': 'Login', 'rate': '30/hour'}, 'oauth-authorize': {'description': 'OAuth app authorization', 'rate': '100/hour'}, 'oauth-revoke-token': {'description': 'OAuth token deletion', 'rate': '100/hour'}, 'oauth-token': {'description': 'OAuth token creation', 'rate': '100/hour'}, 'password-change': {'description': 'Password change (when authenticated)', 'rate': '20/h'}, 'password-reset': {'description': 'Password reset request', 'rate': '20/h'}, 'password-reset-confirm': {'description': 'Password reset confirmation', 'rate': '20/h'}, 'signup': {'description': 'Account creation', 'rate': '10/day'}, 'subsonic': {'description': 'All subsonic API requests', 'rate': '2000/hour'}, 'verify-email': {'description': 'Email address confirmation', 'rate': '20/h'}}

Throttling rates for specific endpoints and features of the app. You can tweak this if you are encountering to severe rate limiting issues or, on the contrary, if you want to reduce the consumption on some endpoints.


  • signup=5/d,password-reset=2/d,anonymous-reports=5/d

ADMIN_URL = '^api/admin/'

Path to the Django admin area.


  • ^api/admin/

  • ^api/mycustompath/


Wether to enforce HTTPS certificates verification when doing outgoing HTTP requests (typically with federation). Disabling this is not recommended.


Default timeout for external requests.



Delay, in minutes, before a remote object will be automatically refetched when accessed in the UI.


Delay, in seconds, between two manual fetch of the same remote object.



Maximum number of tags that can be associated with an object. Extra tags will be ignored.


Use this setting to change the MusicBrainz hostname, for instance to use a mirror. The hostname can also contain a port number.


  • mymusicbrainz.mirror

  • localhost:5000


How long to cache MusicBrainz results, in seconds.

Channels and podcasts


Delay, in seconds, between two fetch of RSS feeds.

Reducing this mean you’ll receive new episodes faster, but will require more resources.


Maximum number of RSS items to load in each podcast feed.


By default, only people who subscribe to a podcast RSS will have access to their episodes.

Switch to “instance” or “everyone” to change that.

Changing it only affect new podcasts.



Default format for transcoding when using Subsonic API.

Email configuration

EMAIL_CONFIG = consolemail://

SMTP configuration for sending e-mails. Possible values:

  • EMAIL_CONFIG=consolemail://: output e-mails to console (the default)

  • EMAIL_CONFIG=dummymail://: disable e-mail sending completely

On a production instance, you’ll usually want to use an external SMTP server:

  • EMAIL_CONFIG=smtp://

  • EMAIL_CONFIG=smtp+ssl://

  • EMAIL_CONFIG=smtp+tls://


If user or password contain special characters (eg. as user), be sure to urlencode them, using for example the command: python3 -c 'import urllib.parse; print(urllib.parse.quote_plus (""))' (returns

DEFAULT_FROM_EMAIL = Funkwhale <noreply@yourdomain>

Name and e-mail address used to send system e-mails.

Default: Funkwhale <noreply@yourdomain>


Both the forms Funkwhale <noreply@yourdomain> and noreply@yourdomain work.


Subject prefix for system e-mails.

Other settings


Delay after signup, in days, before the “support your pod” message is shown.


Delay after signup, in days, before the “support Funkwhale” message is shown.


Minimum required period, in seconds, for two downloads of the same track by the same IP or user to be recorded in statistics.

MARKDOWN_EXTENSIONS = ['nl2br', 'extra']

List of markdown extensions to enable.



Additional TLDs to support with our markdown linkifier.

User permissions

Funkwhale’s permission model works as follows:

  • Anonymous users cannot do anything unless configured specifically;

  • Logged-in users can use the application, but cannot do things that affect the whole instance;

  • Superusers can do anything.

To make things more granular and allow some delegation of responsibility, superusers can grant specific permissions to specific users. Available permissions are:

  • Manage instance-level settings: users with this permission can edit instance settings as described in Instance settings;

  • Manage library: users with this permission can import new music in the instance;

  • Manage library federation: users with this permission can ask to federate with other instances, and accept/deny federation requests from other instances.

There is no dedicated interface to manage users permissions, but superusers can login on the Django’s admin at /api/admin/ and grant permissions to users at /api/admin/users/user/.

Front-end settings

We offer a basic mechanism to customize the behavior and look and feel of Funkwhale’s Web UI. To use any of the options below, you will need to create a custom JSON configuration file and serve it on https://yourinstanceurl/settings.json.

On typical deployments, this url returns a 404 error, which is simply ignored.


First, create the settings file:

cd /srv/funkwhale/

# create a directory for your configuration file
# you can use a different name / path of course
mkdir custom

# populate the configuration file with default values
cat <<EOF > custom/settings.json
  "additionalStylesheets": [],
  "defaultServerUrl": null

Once the settings.json file is created, you will need to serve it from your reverse proxy.

If you are using nginx, add the following snippet to your vhost configuration:

location /settings.json {
    alias /srv/funkwhale/custom/settings.json;

On Apache, add the following to your vhost configuration:

Alias /settings.json /srv/funkwhale/custom/settings.json

Then, reload your reverse proxy.

At this point, visiting https://yourinstanceurl/settings.json should serve the content of the settings.json file.


The settings.json file must be a valid JSON file. If you have any issue, try linting the file with a tool such as to detect potential syntax issues.

Available configuration options

Your settings.json can contain the following options:



Example value



Array of URLs

["https://test/theme.css"] (default: [])

A list of stylesheets URL (absolute or relative) that the web UI should load. see the “Theming” section below for a detailed explanation



"" (default: null)

The URL of the API server this front-end should connect with. If null, the UI will use the value of VUE_APP_INSTANCE_URL (specified during build) or fallback to the current domain

Missing options or options with a null value in the settings.json file are ignored.


To theme your Funkwhale instance, you need:

  1. A CSS file for your theme, that can be loaded by the front-end;

  2. To update the value of additionalStylesheets in your settings.json file to point to your CSS file URL.

cd /srv/funkwhale/custom
nano settings.json
# append
# "additionalStylesheets": ["/front/custom/custom.css"]
# to the configuration or replace the existing value, if any

# create a basic theming file changing the background to red
cat <<EOF > custom.css
body {
  background-color: red;

The last step to make this work is to ensure your CSS file is served by the reverse proxy.

On nginx, add the following snippet to your vhost config:

location /custom {
    alias /srv/funkwhale/custom;

On Apache, use the following:

Alias /custom /srv/funkwhale/custom

<Directory "/srv/funkwhale/custom">
  Options FollowSymLinks
  AllowOverride None
  Require all granted

Once done, reload your reverse proxy, refresh Funkwhale in your web browser, and you should see a red background.


You can reference external urls as well in additionalStylesheets, simply use the full urls. Be especially careful with external urls as they may affect your users privacy.


Loading additional stylesheets and CSS rules can affect the performance and usability of your instance. If you encounter issues with the interfaces and use custom stylesheets, try to disable those to ensure the issue is not caused by your customizations.