Finished Funkwhale implementation

This commit is contained in:
Kevin Veen-Birkenbach 2025-07-02 02:07:41 +02:00
parent 28b41382d2
commit 2ccfdf0de6
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
10 changed files with 140 additions and 48 deletions

View File

@ -62,7 +62,7 @@ ldap:
surname: "sn"
ssh_public_key: "sshPublicKey"
# Password to access dn.bind
bind_credential: "{{applications.ldap.credentials.administrator_database_password}}"
bind_credential: "{{ applications.ldap.credentials.administrator_database_password }}"
server:
domain: "{{applications.ldap.hostname if applications.ldap.network.docker | bool else domains.ldap}}" # Mapping for public or locale access
port: "{{_ldap_server_port}}"

View File

@ -4,4 +4,61 @@
```bash
docker-compose down && docker volume rm funkwhale_data
```
```
## create admin account
```bash
docker compose exec -T api funkwhale-manage fw users create --superuser
```
## ldap debugging
```bash
docker compose exec -T api funkwhale-manage shell
import logging
logging.basicConfig(level=logging.DEBUG)
from django.contrib.auth import authenticate
user = authenticate(username="kevinveenbirkenbach", password="DEINPASSWORT")
print(user)
#######
from django_auth_ldap.backend import LDAPBackend
from django_auth_ldap.config import LDAPSearch
from ldap import initialize
# Zugriff auf deine Funkwhale-Einstellungen
import django.conf
settings = django.conf.settings
# Verbindung aufbauen
conn = initialize(settings.AUTH_LDAP_SERVER_URI)
conn.simple_bind_s(settings.AUTH_LDAP_BIND_DN, settings.AUTH_LDAP_BIND_PASSWORD)
# Benutzername einsetzen
username = "kevinveenbirkenbach"
# Search-Filter einsetzen
search_filter = settings.AUTH_LDAP_USER_SEARCH.search_filter.format(username)
base_dn = settings.AUTH_LDAP_USER_SEARCH.base_dn
scope = settings.AUTH_LDAP_USER_SEARCH.scope
# Suche durchführen
results = conn.search_s(base_dn, scope, search_filter)
print(results)
##########
from django.conf import settings
print("LDAP Server URI:", settings.AUTH_LDAP_SERVER_URI)
print("Bind DN:", settings.AUTH_LDAP_BIND_DN)
print("Bind Password:", settings.AUTH_LDAP_BIND_PASSWORD)
print("Search Base:", settings.AUTH_LDAP_USER_SEARCH.base_dn)
print("Search Filter:", settings.AUTH_LDAP_USER_SEARCH.search_filter)
print("User Attr Map:", settings.AUTH_LDAP_USER_ATTR_MAP)
```

View File

@ -18,4 +18,5 @@ galaxy_info:
documentation: https://s.veen.world/cymais
logo:
class: "fa-solid fa-music"
dependencies: []
run_after:
- docker-ldap

View File

@ -1,5 +1,4 @@
services:
# @todo Test which containers can be removed crom cental_database networks
{% include 'roles/docker-central-database/templates/services/' + database_type + '.yml.j2' %}
{% include 'templates/docker/services/redis.yml.j2' %}
@ -14,53 +13,51 @@ services:
# flag:
# celery -A funkwhale_api.taskapp worker -l INFO --concurrency=4
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
image: "{{ applications[application_id].images.api }}"
image: "{{ applications | get_docker_image(application_id,'api') }}"
command: celery -A funkwhale_api.taskapp worker -l INFO --concurrency={{celeryd_concurrency}}
environment:
- C_FORCE_ROOT=true
volumes:
- "data:{{media_root}}"
- "music:{{music_directory_path}}:ro"
- "data:{{funkwhale_media_root}}"
- "music:{{funkwhale_music_directory_path}}:ro"
{% include 'templates/docker/container/depends-on-database-redis.yml.j2' %}
{% include 'templates/docker/container/networks.yml.j2' %}
celerybeat:
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
image: "{{ applications[application_id].images.api }}"
image: "{{ applications | get_docker_image(application_id,'api') }}"
command: celery -A funkwhale_api.taskapp beat --pidfile= -l INFO
{% include 'templates/docker/container/depends-on-database-redis.yml.j2' %}
{% include 'templates/docker/container/networks.yml.j2' %}
api:
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
image: "{{ applications[application_id].images.api }}"
image: "{{ applications | get_docker_image(application_id,'api') }}"
volumes:
- "music:{{music_directory_path}}:ro"
- "data:{{media_root}}"
- "static_root:{{static_root}}"
- "music:{{funkwhale_music_directory_path}}:ro"
- "data:{{funkwhale_media_root}}"
- "funkwhale_static_root:{{funkwhale_static_root}}"
ports:
- "5000" # Exposes API just in local docker network to be used by front container
- "{{ funkwhale_docker_api_port }}"
{% include 'templates/docker/container/depends-on-database-redis.yml.j2' %}
{% include 'templates/docker/container/networks.yml.j2' %}
front:
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
image: "{{ applications[application_id].images.front }}"
image: "{{ applications | get_docker_image(application_id,'front') }}"
depends_on:
- api
environment:
# Override those variables in your .env file if needed
- "NGINX_MAX_BODY_SIZE=100M"
volumes:
- "data:{{media_root}}:ro"
#- "{{static_root}}:{{static_root}}:ro"
- "data:{{funkwhale_media_root}}:ro"
#- "{{funkwhale_static_root}}:{{funkwhale_static_root}}:ro"
ports:
# override those variables in your .env file if needed
- "127.0.0.1:{{ports.localhost.http[application_id]}}:80"
typesense:
{% include 'roles/docker-compose/templates/services/base.yml.j2' %}
image: "{{ applications[application_id].images.typesense }}"
image: "{{ applications[application_id].docker.images.typesense }}"
volumes:
- ./typesense/data:/data
command: --data-dir /data --enable-cors
@ -69,7 +66,7 @@ services:
{% include 'templates/docker/compose/volumes.yml.j2' %}
data:
static_root:
funkwhale_static_root:
redis:
music:

View File

@ -17,11 +17,7 @@
#
# Docker only
# -----------
MUSIC_DIRECTORY_PATH={{music_directory_path}}
# Assuming that the following variable isn't used anymore.
# @todo remove it if this is true
FUNKWHALE_VERSION={{applications.funkwhale.version}}
MUSIC_DIRECTORY_PATH={{funkwhale_music_directory_path}}
# End of docker-only configuration
@ -32,7 +28,7 @@ FUNKWHALE_VERSION={{applications.funkwhale.version}}
FUNKWHALE_API_IP=127.0.0.1
# Assuming that the following variable isn't used anymore.
# @todo remove it if this is true
FUNKWHALE_API_PORT={{ports.localhost.http[application_id]}}:
FUNKWHALE_API_PORT={{ funkwhale_docker_api_port }}
# The number of web workers to start in parallel. Higher means you can handle
# more concurrent requests, but also leads to higher CPU/Memory usage
@ -46,6 +42,9 @@ FUNKWHALE_PROTOCOL={{ web_protocol }}
# Log level (debug, info, warning, error, critical)
LOGLEVEL={% if enable_debug | bool %}debug{% else %}error{% endif %}
# Could be that this is redundant
DJANGO_LOGLEVEL={% if enable_debug | bool %}debug{% else %}error{% endif %}
# Configure e-mail sending using this variale
# By default, funkwhale will output e-mails sent to stdout
# here are a few examples for this setting
@ -86,12 +85,12 @@ CELERYD_CONCURRENCY={{celeryd_concurrency}}
# Where media files (such as album covers or audio tracks) should be stored
# on your system?
# (Ensure this directory actually exists)
MEDIA_ROOT={{media_root}}
MEDIA_ROOT={{funkwhale_media_root}}
# Where static files (such as API css or icons) should be compiled
# on your system?
# (Ensure this directory actually exists)
STATIC_ROOT={{static_root}}
STATIC_ROOT={{funkwhale_static_root}}
# which settings module should django use?
# You don't have to touch this unless you really know what you're doing
@ -106,14 +105,17 @@ DJANGO_SECRET_KEY={{applications[application_id].credentials.django_secret}}
# using a LDAP directory.
# Have a look at https://docs.funkwhale.audio/installation/ldap.html for
# detailed instructions.
# Commit: https://gitea.fudaoyuan.icu/Github/funkwhale/commit/4ce46ff2a000646a3dbab80f0ca9fd8d7f8ae24c
LDAP_ENABLED = True
LDAP_SERVER_URI = "{{ ldap.server.uri }}"
LDAP_BIND_DN = "{{ ldap.dn.administrator.data }}"
LDAP_BIND_PASSWORD = "{{ ldap.bind_credential }}"
#LDAP_SEARCH_FILTER = "{{ ldap.filters.users.login | replace('%' ~ ldap.attributes.user_id, '{0}') }}"
LDAP_START_TLS = False
LDAP_ROOT_DN = "{{ldap.dn.root}}"
#LDAP_USER_ATTR_MAP = "first_name:{{ ldap.attributes.firstname }}, last_name:{{ ldap.attributes.surname }}, username:{{ ldap.attributes.user_id }}, email:{{ ldap.attributes.mail }}"
LDAP_ENABLED = True
LDAP_SERVER_URI = "{{ldap.server.uri}}"
LDAP_BIND_DN = "{{ldap.dn.administrator.data}}"
LDAP_BIND_PASSWORD = "{{ldap.bind_credential}}"
LDAP_SEARCH_FILTER = "(|(cn={0})(mail={0}))"
LDAP_START_TLS = False
LDAP_ROOT_DN = "{{ldap.dn.root}}"
{% endif %}
FUNKWHALE_FRONTEND_PATH=/srv/funkwhale/front/dist

View File

@ -1,17 +1,36 @@
images:
api: "funkwhale/api:1.4.0"
front: "funkwhale/front:1.4.0"
typesense: "typesense/typesense"
docker:
versions:
api: "1.4.0"
front: "1.4.0"
typesense: "typesense/typesense"
images:
api: "funkwhale/api"
front: "funkwhale/front"
typesense: "typesense/typesense"
features:
matomo: true
css: true
css: false
portfolio_iframe: true
ldap: true
central_database: true
oauth2: false # Doesn't make sense to activate it atm, because login is possible on homepage
credentials:
domains:
canonical:
- "audio.{{ primary_domain }}"
aliases:
- "music.{{ primary_domain }}"
- "sound.{{ primary_domain }}"
- "sound.{{ primary_domain }}"
csp:
flags:
style-src:
unsafe-inline: true
whitelist:
font-src:
- "data:"
oauth2_proxy:
application: "front"
port: "80"
acl:
blacklist:
- "/login"

View File

@ -1,7 +1,8 @@
application_id: "funkwhale"
nginx_docker_reverse_proxy_extra_configuration: "client_max_body_size 512M;"
database_type: "postgres"
media_root: "/srv/funkwhale/data/"
static_root: "{{media_root}}static"
funkwhale_media_root: "/srv/funkwhale/data/"
funkwhale_static_root: "{{funkwhale_media_root}}static"
celeryd_concurrency: 1
music_directory_path: "/music"
funkwhale_music_directory_path: "/music"
funkwhale_docker_api_port: 5000

View File

@ -2,16 +2,16 @@
# @See https://hub.docker.com/r/bitnami/openldap
# GENERAL
## Database
LDAP_ADMIN_USERNAME= {{applications[application_id].users.administrator.username}} # LDAP database admin user.
LDAP_ADMIN_PASSWORD= {{applications[application_id].credentials.administrator_database_password}} # LDAP database admin password.
## Admin (Data)
LDAP_ADMIN_USERNAME= {{applications[application_id].users.administrator.username}} # LDAP database admin user.
LDAP_ADMIN_PASSWORD= {{ldap.bind_credential}} # LDAP database admin password.
## Users
LDAP_USERS= ' ' # Comma separated list of LDAP users to create in the default LDAP tree. Default: user01,user02
LDAP_PASSWORDS= ' ' # Comma separated list of passwords to use for LDAP users. Default: bitnami1,bitnami2
LDAP_ROOT= {{ldap.dn.root}} # LDAP baseDN (or suffix) of the LDAP tree. Default: dc=example,dc=org
## Admin
## Admin (Config)
LDAP_ADMIN_DN= {{ldap.dn.administrator.data}}
LDAP_CONFIG_ADMIN_ENABLED= yes
LDAP_CONFIG_ADMIN_USERNAME= {{applications[application_id].users.administrator.username}}

View File

@ -33,3 +33,17 @@
token_auth: "{{ matomo_auth_token }}"
return_content: yes
status_code: 200
- name: Exclude CSP-CheckerBot user agent in Matomo
uri:
url: "{{ matomo_index_php_url }}"
method: POST
body_format: form-urlencoded
body:
module: API
method: SitesManager.setGlobalExcludedUserAgents
excludedUserAgents: "CSP-CheckerBot"
format: json
token_auth: "{{ matomo_auth_token }}"
return_content: yes
status_code: 200

View File

@ -4,6 +4,7 @@ images:
features:
central_database: true
oidc: true
matomo: true
csp:
flags:
script-src-elem: