Merge branch 'config-docs' into 'develop'

Documentation for .env variables

See merge request funkwhale/funkwhale!1095
This commit is contained in:
Agate 2020-04-20 13:48:19 +02:00
commit e812de28c8
6 changed files with 457 additions and 139 deletions

View File

@ -71,7 +71,7 @@ review_docs:
- cd docs
- apt-get update
- apt-get install -y graphviz
- pip install sphinx sphinx_rtd_theme
- pip install sphinx sphinx_rtd_theme django-environ django
script:
- ./build_docs.sh
cache:

View File

@ -1,13 +1,4 @@
# -*- coding: utf-8 -*-
"""
Django settings for funkwhale_api project.
For more information on this file, see
https://docs.djangoproject.com/en/dev/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/dev/ref/settings/
"""
from __future__ import absolute_import, unicode_literals
import datetime
@ -29,6 +20,9 @@ APPS_DIR = ROOT_DIR.path("funkwhale_api")
env = environ.Env()
LOGLEVEL = env("LOGLEVEL", default="info").upper()
"""
Default logging level for the Funkwhale processes""" # pylint: disable=W0105
LOGGING_CONFIG = None
logging.config.dictConfig(
{
@ -57,7 +51,10 @@ logging.config.dictConfig(
}
)
env_file = env("ENV_FILE", default=None)
ENV_FILE = env_file = env("ENV_FILE", default=None)
"""
Path to a .env file to load
"""
if env_file:
logger.info("Loading specified env file at %s", env_file)
# we have an explicitely specified env file
@ -85,6 +82,9 @@ else:
FUNKWHALE_PLUGINS_PATH = env(
"FUNKWHALE_PLUGINS_PATH", default="/srv/funkwhale/plugins/"
)
"""
Path to a directory containing Funkwhale plugins. These will be imported at runtime.
"""
sys.path.append(FUNKWHALE_PLUGINS_PATH)
FUNKWHALE_HOSTNAME = None
@ -99,7 +99,14 @@ if FUNKWHALE_HOSTNAME_PREFIX and FUNKWHALE_HOSTNAME_SUFFIX:
else:
try:
FUNKWHALE_HOSTNAME = env("FUNKWHALE_HOSTNAME")
"""
Hostname of your Funkwhale pod, e.g ``mypod.audio``
"""
FUNKWHALE_PROTOCOL = env("FUNKWHALE_PROTOCOL", default="https")
"""
Protocol end users will use to access your pod, either ``http`` or ``https``.
"""
except Exception:
FUNKWHALE_URL = env("FUNKWHALE_URL")
_parsed = urlsplit(FUNKWHALE_URL)
@ -112,6 +119,16 @@ FUNKWHALE_URL = "{}://{}".format(FUNKWHALE_PROTOCOL, FUNKWHALE_HOSTNAME)
FUNKWHALE_SPA_HTML_ROOT = env(
"FUNKWHALE_SPA_HTML_ROOT", default=FUNKWHALE_URL + "/front/"
)
"""
URL or path to the Web Application files. Funkwhale needs access to it so that
it can inject <meta> tags relevant to the given page (e.g page title, cover, etc.).
If a URL is specified, the index.html file will be fetched through HTTP. If a path is provided,
it will be accessed from disk.
Use something like ``/srv/funkwhale/front/dist/`` if the web processes shows request errors related to this.
"""
FUNKWHALE_SPA_HTML_CACHE_DURATION = env.int(
"FUNKWHALE_SPA_HTML_CACHE_DURATION", default=60 * 15
)
@ -148,7 +165,16 @@ FEDERATION_SERVICE_ACTOR_USERNAME = env(
)
# How many pages to fetch when crawling outboxes and third-party collections
FEDERATION_COLLECTION_MAX_PAGES = env.int("FEDERATION_COLLECTION_MAX_PAGES", default=5)
"""
Number of existing pages of content to fetch when discovering/refreshing an actor or channel.
More pages means more content will be loaded, but will require more resources.
"""
ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=[]) + [FUNKWHALE_HOSTNAME]
"""
List of allowed hostnames for which the Funkwhale server will answer.
"""
# APP CONFIGURATION
# ------------------------------------------------------------------------------
@ -223,12 +249,18 @@ LOCAL_APPS = (
PLUGINS = [p for p in env.list("FUNKWHALE_PLUGINS", default=[]) if p]
"""
List of Funkwhale plugins to load.
"""
if PLUGINS:
logger.info("Running with the following plugins enabled: %s", ", ".join(PLUGINS))
else:
logger.info("Running with no plugins")
ADDITIONAL_APPS = env.list("ADDITIONAL_APPS", default=[])
"""
List of Django apps to load in addition to Funkwhale plugins and apps.
"""
INSTALLED_APPS = (
DJANGO_APPS
+ THIRD_PARTY_APPS
@ -257,8 +289,11 @@ MIDDLEWARE = tuple(ADDITIONAL_MIDDLEWARES_BEFORE) + (
# DEBUG
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
DEBUG = env.bool("DJANGO_DEBUG", False)
DJANGO_DEBUG = DEBUG = env.bool("DJANGO_DEBUG", False)
"""
Whether to enable debugging info and pages. Never enable this on a production server,
as it can leak very sensitive information.
"""
# FIXTURE CONFIGURATION
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS
@ -272,25 +307,70 @@ FIXTURE_DIRS = (str(APPS_DIR.path("fixtures")),)
DEFAULT_FROM_EMAIL = env(
"DEFAULT_FROM_EMAIL", default="Funkwhale <noreply@{}>".format(FUNKWHALE_HOSTNAME)
)
"""
Name and email address used to send system emails.
Default: ``Funkwhale <noreply@yourdomain>``
.. note::
Both the forms ``Funkwhale <noreply@yourdomain>`` and
``noreply@yourdomain`` work.
"""
EMAIL_SUBJECT_PREFIX = env("EMAIL_SUBJECT_PREFIX", default="[Funkwhale] ")
"""
Subject prefix for system emails.
"""
SERVER_EMAIL = env("SERVER_EMAIL", default=DEFAULT_FROM_EMAIL)
EMAIL_CONFIG = env.email_url("EMAIL_CONFIG", default="consolemail://")
"""
SMTP configuration for sending emails. Possible values:
- ``EMAIL_CONFIG=consolemail://``: output emails to console (the default)
- ``EMAIL_CONFIG=dummymail://``: disable email sending completely
On a production instance, you'll usually want to use an external SMTP server:
- ``EMAIL_CONFIG=smtp://user@:password@youremail.host:25``
- ``EMAIL_CONFIG=smtp+ssl://user@:password@youremail.host:465``
- ``EMAIL_CONFIG=smtp+tls://user@:password@youremail.host:587``
.. note::
If ``user`` or ``password`` contain special characters (eg.
``noreply@youremail.host`` as ``user``), be sure to urlencode them, using
for example the command:
``python3 -c 'import urllib.parse; print(urllib.parse.quote_plus("noreply@youremail.host"))'``
(returns ``noreply%40youremail.host``)
"""
vars().update(EMAIL_CONFIG)
# DATABASE CONFIGURATION
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
DATABASE_URL = env.db("DATABASE_URL")
"""
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``
"""
DATABASES = {
# Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ
"default": env.db("DATABASE_URL")
"default": DATABASE_URL
}
DATABASES["default"]["ATOMIC_REQUESTS"] = True
DATABASES["default"]["CONN_MAX_AGE"] = env("DB_CONN_MAX_AGE", default=60 * 5)
DB_CONN_MAX_AGE = DATABASES["default"]["CONN_MAX_AGE"] = env(
"DB_CONN_MAX_AGE", default=60 * 5
)
"""
Max time, in seconds, before database connections are closed.
"""
MIGRATION_MODULES = {
# see https://github.com/jazzband/django-oauth-toolkit/issues/634
# swappable models are badly designed in oauth2_provider
@ -299,13 +379,6 @@ MIGRATION_MODULES = {
"sites": "funkwhale_api.contrib.sites.migrations",
}
#
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': 'db.sqlite3',
# }
# }
# GENERAL CONFIGURATION
# ------------------------------------------------------------------------------
# Local time zone for this installation. Choices can be found here:
@ -370,31 +443,79 @@ CRISPY_TEMPLATE_PACK = "bootstrap3"
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = env("STATIC_ROOT", default=str(ROOT_DIR("staticfiles")))
"""
Path were static files should be collected.
"""
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = env("STATIC_URL", default=FUNKWHALE_URL + "/staticfiles/")
DEFAULT_FILE_STORAGE = "funkwhale_api.common.storage.ASCIIFileSystemStorage"
PROXY_MEDIA = env.bool("PROXY_MEDIA", default=True)
"""
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 :attr:`AWS_QUERYSTRING_AUTH`,
it's safe to disable it.
"""
AWS_DEFAULT_ACL = None
AWS_QUERYSTRING_AUTH = env.bool("AWS_QUERYSTRING_AUTH", default=not PROXY_MEDIA)
"""
Whether to include signatures in S3 urls, as a way to enforce access-control.
Defaults to the inverse of :attr:`PROXY_MEDIA`.
"""
AWS_S3_MAX_MEMORY_SIZE = env.int(
"AWS_S3_MAX_MEMORY_SIZE", default=1000 * 1000 * 1000 * 20
)
AWS_QUERYSTRING_EXPIRE = env.int("AWS_QUERYSTRING_EXPIRE", default=3600)
"""
Expiration delay, in seconds, of signatures generated when :attr:`AWS_QUERYSTRING_AUTH` is enabled.
"""
AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID", default=None)
"""
Access-key ID for your S3 storage.
"""
if AWS_ACCESS_KEY_ID:
AWS_ACCESS_KEY_ID = AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY")
"""
Secret access key for your S3 storage.
"""
AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME")
"""
Bucket name of your S3 storage.
"""
AWS_S3_CUSTOM_DOMAIN = env("AWS_S3_CUSTOM_DOMAIN", default=None)
"""
Custom domain to use for your S3 storage.
"""
AWS_S3_ENDPOINT_URL = env("AWS_S3_ENDPOINT_URL", default=None)
"""
If you use a S3-compatible storage such as minio, set the following variable to
the full URL to the storage server. Example:
- ``https://minio.mydomain.com``
- ``https://s3.wasabisys.com``
"""
AWS_S3_REGION_NAME = env("AWS_S3_REGION_NAME", default=None)
"""If you are using Amazon S3 to serve media directly, you will need to specify your region
name in order to access files. Example:
- ``eu-west-2``
"""
AWS_S3_SIGNATURE_VERSION = "s3v4"
AWS_LOCATION = env("AWS_LOCATION", default="")
"""
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
"""
DEFAULT_FILE_STORAGE = "funkwhale_api.common.storage.ASCIIS3Boto3Storage"
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = (str(APPS_DIR.path("static")),)
@ -408,14 +529,25 @@ STATICFILES_FINDERS = (
# ------------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = env("MEDIA_ROOT", default=str(APPS_DIR("media")))
"""
Where media files (such as album covers or audio tracks) should be stored
on your system? (Ensure this directory actually exists)
"""
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = env("MEDIA_URL", default=FUNKWHALE_URL + "/media/")
"""
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.
"""
FILE_UPLOAD_PERMISSIONS = 0o644
ATTACHMENTS_UNATTACHED_PRUNE_DELAY = env.int(
"ATTACHMENTS_UNATTACHED_PRUNE_DELAY", default=3600 * 24
)
"""
Delay in seconds before uploaded but unattached attachements are pruned from the system.
"""
# URL Configuration
# ------------------------------------------------------------------------------
@ -441,6 +573,14 @@ ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION_ENFORCE = env.bool(
"ACCOUNT_EMAIL_VERIFICATION_ENFORCE", default=False
)
"""
Determine wether users need to verify their email 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 emails, using :attr:`EMAIL_CONFIG`.
Note that regardless of the setting value, superusers created through the command line will never require verification.
"""
ACCOUNT_EMAIL_VERIFICATION = (
"mandatory" if ACCOUNT_EMAIL_VERIFICATION_ENFORCE else "optional"
)
@ -472,6 +612,10 @@ OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = "users.RefreshToken"
# LDAP AUTHENTICATION CONFIGURATION
# ------------------------------------------------------------------------------
AUTH_LDAP_ENABLED = env.bool("LDAP_ENABLED", default=False)
"""
Wether to enable LDAP authentication. See :doc:`/installation/ldap` for more information.
"""
if AUTH_LDAP_ENABLED:
# Import the LDAP modules here; this way, we don't need the dependency unless someone
@ -541,8 +685,22 @@ if AUTH_LDAP_ENABLED:
AUTOSLUG_SLUGIFY_FUNCTION = "slugify.slugify"
CACHE_DEFAULT = "redis://127.0.0.1:6379/0"
CACHE_URL = env.cache_url("CACHE_URL", default=CACHE_DEFAULT)
"""
URL to your redis server. Examples:
- `redis://<host>:<port>/<database>`
- `redis://127.0.0.1:6379/0`
- `redis://:password@localhost:6379/0` for password auth (the extra semicolon is important)
- `redis:///run/redis/redis.sock?db=0` over unix sockets
.. note::
If you want to use Redis over unix sockets, you'll also need to update :attr:`CELERY_BROKER_URL`
"""
CACHES = {
"default": env.cache_url("CACHE_URL", default=CACHE_DEFAULT),
"default": CACHE_URL,
"local": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"LOCATION": "local-cache",
@ -567,7 +725,7 @@ CACHEOPS_ENABLED = bool(CACHEOPS_DURATION)
if CACHEOPS_ENABLED:
INSTALLED_APPS += ("cacheops",)
CACHEOPS_REDIS = env("CACHE_URL", default=CACHE_DEFAULT)
CACHEOPS_REDIS = CACHE_URL
CACHEOPS_PREFIX = lambda _: "cacheops" # noqa
CACHEOPS_DEFAULTS = {"timeout": CACHEOPS_DURATION}
CACHEOPS = {
@ -581,6 +739,15 @@ INSTALLED_APPS += ("funkwhale_api.taskapp.celery.CeleryConfig",)
CELERY_BROKER_URL = env(
"CELERY_BROKER_URL", default=env("CACHE_URL", default=CACHE_DEFAULT)
)
"""
URL to celery's task broker. Defaults to :attr:`CACHE_URL`, so you shouldn't have to tweak this, unless you want
to use a different one, or use Redis sockets to connect.
Exemple:
- `redis://127.0.0.1:6379/0`
- `redis+socket:///run/redis/redis.sock?virtual_host=0`
"""
# END CELERY
# Location of root django.contrib.admin URL, use {% url 'admin:index' %}
@ -667,7 +834,11 @@ AUTH_PASSWORD_VALIDATORS = [
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
if env.bool("DISABLE_PASSWORD_VALIDATORS", default=False):
DISABLE_PASSWORD_VALIDATORS = env.bool("DISABLE_PASSWORD_VALIDATORS", default=False)
"""
Wether to disable password validators (length, common words, similarity with username) used during regitration.
"""
if DISABLE_PASSWORD_VALIDATORS:
AUTH_PASSWORD_VALIDATORS = []
ACCOUNT_ADAPTER = "funkwhale_api.users.adapters.FunkwhaleAccountAdapter"
CORS_ORIGIN_ALLOW_ALL = True
@ -705,6 +876,11 @@ REST_FRAMEWORK = {
"NUM_PROXIES": env.int("NUM_PROXIES", default=1),
}
THROTTLING_ENABLED = env.bool("THROTTLING_ENABLED", default=True)
"""
Wether to enable throttling (also known as rate-limiting). Leaving this enabled is recommended
especially on public pods, to improve the quality of service.
"""
if THROTTLING_ENABLED:
REST_FRAMEWORK["DEFAULT_THROTTLE_CLASSES"] = env.list(
"THROTTLE_CLASSES",
@ -853,7 +1029,16 @@ THROTTLING_RATES = {
"description": "Fetch remote objects",
},
}
THROTTLING_RATES = THROTTLING_RATES
"""
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.
Example:
- ``signup=5/d,password-reset=2/d,anonymous-reports=5/d``
"""
BROWSABLE_API_ENABLED = env.bool("BROWSABLE_API_ENABLED", default=False)
if BROWSABLE_API_ENABLED:
@ -874,24 +1059,48 @@ USE_X_FORWARDED_PORT = True
# Wether we should use Apache, Nginx (or other) headers when serving audio files
# Default to Nginx
REVERSE_PROXY_TYPE = env("REVERSE_PROXY_TYPE", default="nginx")
"""
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``
"""
assert REVERSE_PROXY_TYPE in ["apache2", "nginx"], "Unsupported REVERSE_PROXY_TYPE"
# Which path will be used to process the internal redirection
# **DO NOT** put a slash at the end
PROTECT_FILES_PATH = env("PROTECT_FILES_PATH", default="/_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.
"""
# use this setting to tweak for how long you want to cache
# musicbrainz results. (value is in seconds)
MUSICBRAINZ_CACHE_DURATION = env.int("MUSICBRAINZ_CACHE_DURATION", default=300)
# Use this setting to change the musicbrainz hostname, for instance to
# use a mirror. The hostname can also contain a port number (so, e.g.,
# "localhost:5000" is a valid name to set).
"""
How long to cache MusicBrainz results, in seconds
"""
MUSICBRAINZ_HOSTNAME = env("MUSICBRAINZ_HOSTNAME", default="musicbrainz.org")
"""
Use this setting to change the musicbrainz hostname, for instance to
use a mirror. The hostname can also contain a port number.
Example:
- ``mymusicbrainz.mirror``
- ``localhost:5000``
"""
# Custom Admin URL, use {% url 'admin:index' %}
ADMIN_URL = env("DJANGO_ADMIN_URL", default="^api/admin/")
"""
Path to the Django admin area.
Exemples:
- `^api/admin/`
- `^api/mycustompath/`
"""
CSRF_USE_SESSIONS = True
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
@ -899,6 +1108,7 @@ SESSION_ENGINE = "django.contrib.sessions.backends.cache"
# XXX: deprecated, see #186
PLAYLISTS_MAX_TRACKS = env.int("PLAYLISTS_MAX_TRACKS", default=250)
ACCOUNT_USERNAME_BLACKLIST = [
"funkwhale",
"library",
@ -923,24 +1133,71 @@ ACCOUNT_USERNAME_BLACKLIST = [
"shared_inbox",
"actor",
] + env.list("ACCOUNT_USERNAME_BLACKLIST", default=[])
"""
List of usernames that will be unavailable during registration.
"""
EXTERNAL_REQUESTS_VERIFY_SSL = env.bool("EXTERNAL_REQUESTS_VERIFY_SSL", default=True)
"""
Wether to enforce HTTPS certificates verification when doing outgoing HTTP requests (typically with federation).
Disabling this is not recommended.
"""
EXTERNAL_REQUESTS_TIMEOUT = env.int("EXTERNAL_REQUESTS_TIMEOUT", default=10)
"""
Default timeout for external requests.
"""
# XXX: deprecated, see #186
API_AUTHENTICATION_REQUIRED = env.bool("API_AUTHENTICATION_REQUIRED", True)
MUSIC_DIRECTORY_PATH = env("MUSIC_DIRECTORY_PATH", default=None)
# on Docker setup, the music directory may not match the host path,
# and we need to know it for it to serve stuff properly
"""
The path on your server where Funkwhale can import files using :ref:`in-place import
<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.
.. note:: This path should not include any trailing slash
.. warning::
You need to adapt your :ref:`reverse-proxy configuration<reverse-proxy-setup>` to
serve the directory pointed by ``MUSIC_DIRECTORY_PATH`` on
``/_protected/music`` URL.
"""
MUSIC_DIRECTORY_SERVE_PATH = env(
"MUSIC_DIRECTORY_SERVE_PATH", default=MUSIC_DIRECTORY_PATH
)
"""
Default: :attr:`MUSIC_DIRECTORY_PATH`
When using Docker, the value of :attr:`MUSIC_DIRECTORY_PATH` in your containers
may differ from the real path on your host. Assuming you have the following directive
in your :file:`docker-compose.yml` file::
volumes:
- /srv/funkwhale/data/music:/music:ro
Then, the value of :attr:`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.
.. note:: This path should not include any trailing slash
"""
# When this is set to default=True, we need to reenable migration music/0042
# to ensure data is populated correctly on existing pods
MUSIC_USE_DENORMALIZATION = env.bool("MUSIC_USE_DENORMALIZATION", default=False)
USERS_INVITATION_EXPIRATION_DAYS = env.int(
"USERS_INVITATION_EXPIRATION_DAYS", default=14
)
"""
Expiration delay in days, for user invitations.
"""
VERSATILEIMAGEFIELD_RENDITION_KEY_SETS = {
"square": [
@ -964,40 +1221,84 @@ ACTOR_KEY_ROTATION_DELAY = env.int("ACTOR_KEY_ROTATION_DELAY", default=3600 * 48
SUBSONIC_DEFAULT_TRANSCODING_FORMAT = (
env("SUBSONIC_DEFAULT_TRANSCODING_FORMAT", default="mp3") or None
)
"""
Default format for transcoding when using Subsonic API.
"""
# extra tags will be ignored
TAGS_MAX_BY_OBJ = env.int("TAGS_MAX_BY_OBJ", default=30)
"""
Maximum number of tags that can be associated with an object. Extra tags will be ignored.
"""
FEDERATION_OBJECT_FETCH_DELAY = env.int(
"FEDERATION_OBJECT_FETCH_DELAY", default=60 * 24 * 3
)
"""
Number of minutes before a remote object will be automatically refetched when accessed in the UI.
"""
MODERATION_EMAIL_NOTIFICATIONS_ENABLED = env.bool(
"MODERATION_EMAIL_NOTIFICATIONS_ENABLED", default=True
)
"""
Whether to enable email notifications to moderators and pods admins.
"""
FEDERATION_AUTHENTIFY_FETCHES = True
FEDERATION_SYNCHRONOUS_FETCH = env.bool("FEDERATION_SYNCHRONOUS_FETCH", default=True)
FEDERATION_DUPLICATE_FETCH_DELAY = env.int(
"FEDERATION_DUPLICATE_FETCH_DELAY", default=60 * 50
)
# Delay in days after signup before we show the "support us" messages
"""
Delay, in seconds, between two manual fetch of the same remote object.
"""
INSTANCE_SUPPORT_MESSAGE_DELAY = env.int("INSTANCE_SUPPORT_MESSAGE_DELAY", default=15)
"""
Delay in days after signup before we show the "support your pod" message
"""
FUNKWHALE_SUPPORT_MESSAGE_DELAY = env.int("FUNKWHALE_SUPPORT_MESSAGE_DELAY", default=15)
"""
Delay in days after signup before we show the "support Funkwhale" message
"""
# XXX Stable release: remove
USE_FULL_TEXT_SEARCH = env.bool("USE_FULL_TEXT_SEARCH", default=True)
MIN_DELAY_BETWEEN_DOWNLOADS_COUNT = env.int(
"MIN_DELAY_BETWEEN_DOWNLOADS_COUNT", default=60 * 60 * 6
)
"""
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 = env.list("MARKDOWN_EXTENSIONS", default=["nl2br", "extra"])
"""
List of markdown extensions to enable.
Cf `<https://python-markdown.github.io/extensions/>`_
"""
LINKIFIER_SUPPORTED_TLDS = ["audio"] + env.list("LINKINFIER_SUPPORTED_TLDS", default=[])
"""
Additional TLDs to support with our markdown linkifier.
"""
EXTERNAL_MEDIA_PROXY_ENABLED = env.bool("EXTERNAL_MEDIA_PROXY_ENABLED", default=True)
# By default, only people who subscribe to a podcast RSS will have access to it
# switch to "instance" or "everyone" to change that
"""
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.
"""
PODCASTS_THIRD_PARTY_VISIBILITY = env("PODCASTS_THIRD_PARTY_VISIBILITY", default="me")
"""
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.
"""
PODCASTS_RSS_FEED_REFRESH_DELAY = env.int(
"PODCASTS_RSS_FEED_REFRESH_DELAY", default=60 * 60 * 24
)
"""
Delay in seconds between to fetch of RSS feeds. Reducing this mean you'll receive new episodes faster,
but will require more resources.
"""
# maximum items loaded through XML feed
PODCASTS_RSS_FEED_MAX_ITEMS = env.int("PODCASTS_RSS_FEED_MAX_ITEMS", default=250)
"""
Maximum number of RSS items to load in each podcast feed.
"""

View File

@ -1,5 +1,5 @@
FROM python:3.6
RUN apt-get update && apt-get install -y graphviz
RUN pip install sphinx livereload sphinx_rtd_theme
RUN pip install sphinx livereload sphinx_rtd_theme django-environ django
WORKDIR /app/docs

View File

@ -1,13 +1,18 @@
Instance configuration
======================
General configuration is achieved using two type of settings.
General configuration is achieved using two type of settings:
:ref:`environment variables <environment-variables>` and
:ref:`instance settings <instance-settings>`.
.. _environment-variables:
Environment variables
---------------------
Those are located in your ``.env`` file, which you should have created
during installation.
during installation. A full list of available variables can be seen
:ref:`below <environment-variables>`.
Options from this file are heavily commented, and usually target lower level
and technical aspects of your instance, such as database credentials.
@ -33,7 +38,7 @@ and technical aspects of your instance, such as database credentials.
Instance settings
-----------------
Those settings are stored in database and do not require a restart of your
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.
@ -42,7 +47,7 @@ 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
(e.g. with the YouTube backends), you should edit the corresponding
settings in this interface.
.. note::
@ -58,113 +63,114 @@ settings in this interface.
Configuration reference
-----------------------
.. _setting-ACCOUNT_EMAIL_VERIFICATION_ENFORCE:
Pod
^^^
``ACCOUNT_EMAIL_VERIFICATION_ENFORCE``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autodata:: config.settings.common.FUNKWHALE_HOSTNAME
:annotation:
.. autodata:: config.settings.common.FUNKWHALE_PROTOCOL
Determine wether users need to verify their email address before using the service. Enabling this can be useful
to reduce spam or bots accounts, however, you'll need to configure a SMTP server so that your users can receive the
verification emails.
Database and redis
^^^^^^^^^^^^^^^^^^
Note that regardless of the setting value, superusers created through the command line will never require verification.
.. autodata:: config.settings.common.DATABASE_URL
:annotation:
.. autodata:: config.settings.common.DB_CONN_MAX_AGE
.. autodata:: config.settings.common.CACHE_URL
:annotation:
.. autodata:: config.settings.common.CELERY_BROKER_URL
:annotation:
Default: ``false``
Accounts and registration
^^^^^^^^^^^^^^^^^^^^^^^^^
.. _setting-EMAIL_CONFIG:
.. autodata:: config.settings.common.ACCOUNT_EMAIL_VERIFICATION_ENFORCE
:annotation:
.. autodata:: config.settings.common.USERS_INVITATION_EXPIRATION_DAYS
:annotation:
.. autodata:: config.settings.common.DISABLE_PASSWORD_VALIDATORS
:annotation:
.. autodata:: config.settings.common.ACCOUNT_USERNAME_BLACKLIST
:annotation:
.. autodata:: config.settings.common.AUTH_LDAP_ENABLED
:annotation:
``EMAIL_CONFIG``
^^^^^^^^^^^^^^^^
Media storage and serving
^^^^^^^^^^^^^^^^^^^^^^^^^
Determine how emails are sent.
.. autodata:: config.settings.common.MEDIA_URL
:annotation: = https://mypod.audio/media/
.. autodata:: config.settings.common.MEDIA_ROOT
:annotation: = /srv/funkwhale/data/media
.. autodata:: config.settings.common.PROXY_MEDIA
:annotation: = true
.. autodata:: config.settings.common.EXTERNAL_MEDIA_PROXY_ENABLED
.. autodata:: config.settings.common.ATTACHMENTS_UNATTACHED_PRUNE_DELAY
:annotation: = true
.. autodata:: config.settings.common.REVERSE_PROXY_TYPE
.. autodata:: config.settings.common.PROTECT_FILES_PATH
Default: ``consolemail://``
Audio acquisition
^^^^^^^^^^^^^^^^^
Possible values:
.. autodata:: config.settings.common.MUSIC_DIRECTORY_PATH
.. autodata:: config.settings.common.MUSIC_DIRECTORY_SERVE_PATH
- ``consolemail://``: Output sent emails to stdout
- ``dummymail://``: Completely discard sent emails
- ``smtp://user:password@youremail.host:25``: Send emails via SMTP via youremail.host on port 25, without encryption, authenticating as user "user" with password "password"
- ``smtp+ssl://user:password@youremail.host:465``: Send emails via SMTP via youremail.host on port 465, using SSL encryption, authenticating as user "user" with password "password"
- ``smtp+tls://user:password@youremail.host:587``: Send emails via SMTP via youremail.host on port 587, using TLS encryption, authenticating as user "user" with password "password"
S3 Storage
^^^^^^^^^^
.. note::
.. autodata:: config.settings.common.AWS_QUERYSTRING_AUTH
.. autodata:: config.settings.common.AWS_QUERYSTRING_EXPIRE
.. autodata:: config.settings.common.AWS_ACCESS_KEY_ID
.. autodata:: config.settings.common.AWS_SECRET_ACCESS_KEY
.. autodata:: config.settings.common.AWS_STORAGE_BUCKET_NAME
.. autodata:: config.settings.common.AWS_S3_CUSTOM_DOMAIN
.. autodata:: config.settings.common.AWS_S3_ENDPOINT_URL
.. autodata:: config.settings.common.AWS_S3_REGION_NAME
.. autodata:: config.settings.common.AWS_LOCATION
If ``user`` or ``password`` contain special characters (eg.
``noreply@youremail.host`` as ``user``), be sure to urlencode them, using
for example the command:
``python3 -c 'import urllib.parse; print(urllib.parse.quote_plus("noreply@youremail.host"))'``
(returns ``noreply%40youremail.host``)
API configuration
^^^^^^^^^^^^^^^^^
.. autodata:: config.settings.common.THROTTLING_ENABLED
.. autodata:: config.settings.common.THROTTLING_RATES
.. autodata:: config.settings.common.ADMIN_URL
.. autodata:: config.settings.common.EXTERNAL_REQUESTS_VERIFY_SSL
.. autodata:: config.settings.common.EXTERNAL_REQUESTS_TIMEOUT
.. _setting-DEFAULT_FROM_EMAIL:
Federation
^^^^^^^^^^
``DEFAULT_FROM_EMAIL``
^^^^^^^^^^^^^^^^^^^^^^
.. autodata:: config.settings.common.FEDERATION_OBJECT_FETCH_DELAY
.. autodata:: config.settings.common.FEDERATION_DUPLICATE_FETCH_DELAY
The email address to use to send email.
Metadata
^^^^^^^^
Default: ``Funkwhale <noreply@yourdomain>``
.. autodata:: config.settings.common.TAGS_MAX_BY_OBJ
.. autodata:: config.settings.common.MUSICBRAINZ_HOSTNAME
.. autodata:: config.settings.common.MUSICBRAINZ_CACHE_DURATION
.. note::
Channels and podcasts
^^^^^^^^^^^^^^^^^^^^^
Both the forms ``Funkwhale <noreply@yourdomain>`` and
``noreply@yourdomain`` work.
.. autodata:: config.settings.common.PODCASTS_RSS_FEED_REFRESH_DELAY
.. autodata:: config.settings.common.PODCASTS_RSS_FEED_MAX_ITEMS
.. autodata:: config.settings.common.PODCASTS_THIRD_PARTY_VISIBILITY
Subsonic
^^^^^^^^
.. _setting-MUSIC_DIRECTORY_PATH:
.. autodata:: config.settings.common.SUBSONIC_DEFAULT_TRANSCODING_FORMAT
``MUSIC_DIRECTORY_PATH``
^^^^^^^^^^^^^^^^^^^^^^^^
Other settings
^^^^^^^^^^^^^^
Default: ``None``
The path on your server where Funkwhale can import files using :ref:`in-place import
<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.
.. note:: This path should not include any trailing slash
.. warning::
You need to adapt your :ref:`reverse-proxy configuration<reverse-proxy-setup>` to
serve the directory pointed by ``MUSIC_DIRECTORY_PATH`` on
``/_protected/music`` URL.
.. _setting-MUSIC_DIRECTORY_SERVE_PATH:
``MUSIC_DIRECTORY_SERVE_PATH``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Default: :ref:`setting-MUSIC_DIRECTORY_PATH`
When using Docker, the value of :ref:`setting-MUSIC_DIRECTORY_PATH` in your containers
may differ from the real path on your host. Assuming you have the following directive
in your :file:`docker-compose.yml` file::
volumes:
- /srv/funkwhale/data/music:/music:ro
Then, the value of :ref:`setting-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.
.. note:: This path should not include any trailing slash
.. _setting-REVERSE_PROXY_TYPE:
``REVERSE_PROXY_TYPE``
^^^^^^^^^^^^^^^^^^^^^^
Default: ``nginx``
The type of reverse-proxy behind which Funkwhale is served. Either ``apache2``
or ``nginx``. This is only used if you are using in-place import.
.. autodata:: config.settings.common.INSTANCE_SUPPORT_MESSAGE_DELAY
.. autodata:: config.settings.common.FUNKWHALE_SUPPORT_MESSAGE_DELAY
.. autodata:: config.settings.common.MIN_DELAY_BETWEEN_DOWNLOADS_COUNT
.. autodata:: config.settings.common.MARKDOWN_EXTENSIONS
.. autodata:: config.settings.common.LINKIFIER_SUPPORTED_TLDS
User permissions
----------------
@ -194,7 +200,7 @@ to users at ``/api/admin/users/user/``.
Front-end settings
------------------
We offer a basic mechanism to customize the behaviour and look and feel of Funkwhale's Web UI.
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``.
@ -296,7 +302,7 @@ On nginx, add the following snippet to your vhost config::
alias /srv/funkwhale/custom;
}
On apache, use the following one::
On apache, use the following::
Alias /custom /srv/funkwhale/custom

View File

@ -26,6 +26,16 @@ sys.path.insert(0, os.path.abspath("../api"))
import funkwhale_api # NOQA
FUNKWHALE_CONFIG = {
"FUNKWHALE_URL": "mypod.funkwhale",
"FUNKWHAL_PROTOCOL": "https",
"DATABASE_URL": "postgres://localhost:5432/db",
"AWS_ACCESS_KEY_ID": 'my_access_key',
"AWS_SECRET_ACCESS_KEY": 'my_secret_key',
"AWS_STORAGE_BUCKET_NAME": 'my_bucket',
}
for key, value in FUNKWHALE_CONFIG.items():
os.environ[key] = value
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
@ -35,8 +45,9 @@ import funkwhale_api # NOQA
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ["sphinx.ext.graphviz"]
extensions = ["sphinx.ext.graphviz", "sphinx.ext.autodoc"]
autodoc_mock_imports = ["celery", "django_auth_ldap", "ldap"]
add_module_names = False
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

View File

@ -6,5 +6,5 @@ call(["python", "-m", "sphinx", ".", "/tmp/_build"])
from livereload import Server, shell
server = Server()
server.watch(".", shell("python -m sphinx . /tmp/_build"))
server.watch("..", shell("python -m sphinx . /tmp/_build"))
server.serve(root="/tmp/_build/", liveport=35730, port=8001, host="0.0.0.0")