,

Funkwhale auf VPS installieren

Lesedauer 6 Minuten

Inhaltsverzeichnis

Hinweis
Einige Screenshots zeigen das Backend unseres Schwesterunternehmens dogado. Die gezeigten Schritte können jedoch auch im easyname-Backend durchgeführt werden.

0. Überblick

1. Funkwhale installieren

1.1 Einleitung

Funkwhale ist ein freies soziales Netzwerk zum Teilen von Audio. Die Besonderheit von Funkwhale gegenüber anderen großen Netzwerken ist, dass es selbst gehostet werden kann.

1.2 Infos zu yml Dateien

Bei yml Dateien ist es sehr wichtig, dass die Zeilen alle richtig eingerückt sind. Die Zeilen MÜSSEN immer mit der Leertaste eingerückt werden. Es dürfen KEINE Tabs enthalten sein. Du kannst den nachfolgenden Code immer online „überprüfen“ lassen. Die meisten Fehler entstehen nämlich durch die falsche Formatierung. Ein Dienst zum Überprüfen ist zum Beispiel: https://codebeautify.org/yaml-validator

1.3 Vorbereitung

Diese Anleitung basiert auf dem aktuellen Debian 11 Betriebssystem. Funkwhale werden wir unter Docker realisieren. Dies ermöglicht uns später sehr schnelle Updates und eine schnelle Installation.

Um Funkwhale neben anderen Diensten auf unserem Server betreiben zu können, nutzen wir hier den Reverse Proxy Traefik. Die Anleitung dazu findest du hier: https://www.easyname.at/blog/vps/anwendungen/traefik-reverseproxy-auf-vps-installieren/

Diese Anleitung passt auf die obige Traefik Anleitung. Daher lässt sich diese Anleitung nur 1:1 nutzen, wenn du Traefik nach der obigen Anleitung installiert hat.

1.3.1 Verzeichnis anlegen

Zuerst legen wir uns ein Verzeichnis an, in welchem wir später alle Daten von Funkwhale speichern wollen.

mkdir -p /opt/containers/funkwhale/{front,media,music,static} 

Den Pfad kannst du gerne anpassen. Dann kannst du diese Anleitung aber nicht mehr 1:1 nutzen.

1.3.2 Docker Compose Datei erstellen

Nun legen wir uns noch eine Docker Compose Datei an. Diese ist der „Bauplan“ für Funkwhale. Dazu gibst du folgendes in der Konsole ein:

nano /opt/containers/funkwhale/docker-compose.yml 

Nun kopierst du folgenden Inhalt:

version: "3" 

services: 

  postgres: 

    restart: unless-stopped 

    networks: 

      - default 

    env_file: .env 

    environment: 

      - "POSTGRES_HOST_AUTH_METHOD=trust" 

    image: postgres:14 

    volumes: 

      - ./data/postgres:/var/lib/postgresql/data 

  redis: 

    restart: unless-stopped 

    networks: 

      - default 

    env_file: .env 

    image: redis:6 

    volumes: 

      - ./data/redis:/data 

  celeryworker: 

    restart: unless-stopped 

    image: funkwhale/funkwhale:${FUNKWHALE_VERSION:-latest} 

    networks: 

      - default 

    depends_on: 

      - postgres 

      - redis 

    env_file: .env 

    # Celery workers handle background tasks (such file imports or federation 

    # messaging). The more processes a worker gets, the more tasks 

    # can be processed in parallel. However, more processes also means 

    # a bigger memory footprint. 

    # By default, a worker will span a number of process equal to your number 

    # of CPUs. You can adjust this, by explicitly setting the --concurrency 

    # flag: 

    #   celery -A funkwhale_api.taskapp worker -l INFO --concurrency=4 

    command: celery -A funkwhale_api.taskapp worker -l INFO --concurrency=${CELERYD_CONCURRENCY-0} 

    environment: 

      - C_FORCE_ROOT=true 

    volumes: 

      - "${MUSIC_DIRECTORY_SERVE_PATH}:${MUSIC_DIRECTORY_PATH}:ro" 

      - "${MEDIA_ROOT}:${MEDIA_ROOT}" 

  celerybeat: 

    restart: unless-stopped 

    image: funkwhale/funkwhale:${FUNKWHALE_VERSION:-latest} 

    networks: 

      - default 

    depends_on: 

      - postgres 

      - redis 

    env_file: .env 

    command: celery -A funkwhale_api.taskapp beat --pidfile= -l INFO 

  api: 

    restart: unless-stopped 

    image: funkwhale/funkwhale:${FUNKWHALE_VERSION:-latest} 

    networks: 

      - default 

    depends_on: 

      - postgres 

      - redis 

    env_file: .env 

    volumes: 

      - "${MUSIC_DIRECTORY_SERVE_PATH}:${MUSIC_DIRECTORY_PATH}:ro" 

      - "${MEDIA_ROOT}:${MEDIA_ROOT}" 

      - "${STATIC_ROOT}:${STATIC_ROOT}" 

      - "${FUNKWHALE_FRONTEND_PATH}:/frontend" 

    ports: 

      - "5000" 

  nginx: 

    restart: unless-stopped 

    image: nginx 

    networks: 

      - default 

      - proxy 

    depends_on: 

      - api 

    env_file: 

      - .env 

    environment: 

      # Override those variables in your .env file if needed 

      - "NGINX_MAX_BODY_SIZE=${NGINX_MAX_BODY_SIZE-100M}" 

    volumes: 

      - ./funkwhale.template:/etc/nginx/conf.d/funkwhale.template:ro 

      - ./funkwhale_proxy.conf:/etc/nginx/funkwhale_proxy.conf:ro 

      - "${MUSIC_DIRECTORY_SERVE_PATH}:${MUSIC_DIRECTORY_PATH-/music}:ro" 

      - "${MEDIA_ROOT}:${MEDIA_ROOT}:ro" 

      - "${STATIC_ROOT}:${STATIC_ROOT}:ro" 

      - "${FUNKWHALE_FRONTEND_PATH}:/frontend:ro" 

    command: > 

        sh -c "envsubst \"`env | awk -F = '{printf \" $$%s\", $$1}'`\" 

        < /etc/nginx/conf.d/funkwhale.template 

        > /etc/nginx/conf.d/default.conf 

        && cat /etc/nginx/conf.d/default.conf 

        && nginx -g 'daemon off;'" 

    labels: 

      - "traefik.enable=true" 

      - "traefik.http.routers.funkwhale.entrypoints=http" 

      - "traefik.http.routers.funkwhale.rule=Host(`funkwhale.euredomain.de`)" 

      - "traefik.http.middlewares.funkwhale-https-redirect.redirectscheme.scheme=https" 

      - "traefik.http.routers.funkwhale.middlewares=funkwhale-https-redirect" 

      - "traefik.http.routers.funkwhale-secure.entrypoints=https" 

      - "traefik.http.routers.funkwhale-secure.rule=Host(`funkwhale.euredomain.de`)" 

      - "traefik.http.routers.funkwhale-secure.tls=true" 

      - "traefik.http.routers.funkwhale-secure.tls.certresolver=http" 

      - "traefik.http.routers.funkwhale-secure.service=funkwhale" 

      - "traefik.http.services.funkwhale.loadbalancer.server.port=80" 

      - "traefik.docker.network=proxy" 

      - "traefik.http.routers.funkwhale-secure.middlewares=secHeaders@file" 

networks: 

  proxy: 

    external: true 

Nun müssen wir noch einiges anpassen.

1.3.3 Hostname anpassen

Zuerst musst du noch den Hostnamen anpassen, über welchen später Funkwhale erreichbar sein soll.

Diese beiden Zeilen musst du anpassen.

    - "traefik.http.routers.funkwhale.rule=Host(`funkwhale.euredomain.de`)" 

    - "traefik.http.routers.funkwhale-secure.rule=Host(`funkwhale.euredomain.de`)" 

In meinem Fall also:

    - "traefik.http.routers.funkwhale.rule=Host(`funkwhale.testbereich.net`)" 

    - "traefik.http.routers.funkwhale-secure.rule=Host(`funkwhale.testbereich.net`)" 

1.3.4 funkwhale_proxy.conf erstellen

Nun erstellen wir uns noch eine weitere Konfigurationsdatei. Dazu gibst du folgendes ein:

nano /opt/containers/funkwhale/funkwhale_proxy.conf 

Folgenden Code kopierst du in die Datei:

# global proxy conf 

proxy_set_header Host $host; 

proxy_set_header X-Real-IP $remote_addr; 

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 

proxy_set_header X-Forwarded-Proto $scheme; 

proxy_set_header X-Forwarded-Host $host:$server_port; 

proxy_set_header X-Forwarded-Port $server_port; 

proxy_redirect off; 

# websocket support 

proxy_http_version 1.1; 

proxy_set_header Upgrade $http_upgrade; 

proxy_set_header Connection $connection_upgrade; 

1.3.5 funkwhale.template erstellen

Nun erstellen wir uns die nächste Konfigurationsdatei. Gib dazu folgendes ein:

nano /opt/containers/funkwhale/funkwhale.template 

Jetzt kopierst du folgenden Code:

upstream funkwhale-api { 

    # depending on your setup, you may want to update this 

    server api:5000; 

} 

# required for websocket support 

map $http_upgrade $connection_upgrade { 

    default upgrade; 

    ''      close; 

} 

server { 

    listen 80; 

    server_name ${FUNKWHALE_HOSTNAME}; 

    # TLS 

    # Feel free to use your own configuration for SSL here or simply remove the 

    # lines and move the configuration to the previous server block if you 

    # don't want to run funkwhale behind https (this is not recommended) 

    # have a look here for let's encrypt configuration: 

    # https://certbot.eff.org/all-instructions/#debian-9-stretch-nginx 

    root /frontend; 

    # If you are using S3 to host your files, remember to add your S3 URL to the 

    # media-src and img-src headers (e.g. img-src 'self' https://<your-S3-URL> data:) 

    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:"; 

    add_header Referrer-Policy "strict-origin-when-cross-origin"; 

    add_header X-Frame-Options "SAMEORIGIN" always; 

    location / { 

        include /etc/nginx/funkwhale_proxy.conf; 

        # this is needed if you have file import via upload enabled 

        client_max_body_size ${NGINX_MAX_BODY_SIZE}; 

        proxy_pass   http://funkwhale-api/; 

    } 

    location /front/ { 

        add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:"; 

        add_header Referrer-Policy "strict-origin-when-cross-origin"; 

        add_header Service-Worker-Allowed "/"; 

        alias /frontend/; 

        expires 30d; 

        add_header Pragma public; 

        add_header Cache-Control "public, must-revalidate, proxy-revalidate"; 

    } 

    location /front/embed.html { 

        add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:"; 

        add_header Referrer-Policy "strict-origin-when-cross-origin"; 

        add_header X-Frame-Options "" always; 

        alias /frontend/embed.html; 

        expires 30d; 

        add_header Pragma public; 

        add_header Cache-Control "public, must-revalidate, proxy-revalidate"; 

    } 

    location /federation/ { 

        include /etc/nginx/funkwhale_proxy.conf; 

        proxy_pass   http://funkwhale-api/federation/; 

    } 

    # You can comment this if you do not plan to use the Subsonic API 

    location /rest/ { 

        include /etc/nginx/funkwhale_proxy.conf; 

        proxy_pass   http://funkwhale-api/api/subsonic/rest/; 

    } 

    location /.well-known/ { 

        include /etc/nginx/funkwhale_proxy.conf; 

        proxy_pass   http://funkwhale-api/.well-known/; 

    } 

    location /media/ { 

        alias ${MEDIA_ROOT}/; 

    } 

    # this is an internal location that is used to serve 

    # audio files once correct permission / authentication 

    # has been checked on API side 

    location /_protected/media { 

        internal; 

        alias   ${MEDIA_ROOT}; 

    } 

    # Comment the previous location and uncomment this one if you're storing 

    # media files in a S3 bucket 

    # location ~ /_protected/media/(.+) { 

    #     internal; 

    #     # Needed to ensure DSub auth isn't forwarded to S3/Minio, see #932 

    #     proxy_set_header Authorization ""; 

    #     proxy_pass $1; 

    # } 

    location /_protected/music { 

        # this is an internal location that is used to serve 

        # audio files once correct permission / authentication 

        # has been checked on API side 

        # Set this to the same value as your MUSIC_DIRECTORY_PATH setting 

        internal; 

        alias   ${MUSIC_DIRECTORY_PATH}; 

    } 

    location /staticfiles/ { 

        # django static files 

        alias ${STATIC_ROOT}/; 

    } 

} 

1.3.6 env Konfigurationsdatei erstellen

Nun erstellen wir uns die letzte Konfigurationsdatei. In dieser müssen wir auch einige Änderungen vornehmen. Zum Erstellen der Datei gibst du folgendes ein:

cd /opt/containers/funkwhale 

curl -L -o .env "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/1.2.2/deploy/env.prod.sample" 

chmod 600 .env 

Nun musst du noch die Versionsnummer in der Datei anpassen. Dazu führst du folgenden Code aus.

sed -i "s/FUNKWHALE_VERSION=latest/FUNKWHALE_VERSION=1.2.2/" .env 

Jetzt musst du dir noch einen Key generieren, welchen wir gleich in der Konfiguration benötigen. Dazu gibst du folgendes ein:

openssl rand -base64 45 

Das Ergebnis sieht bei mir so aus:

Funkwhale - env Konfigurationsdatei erstellen

Nun müssen wir noch einiges anpassen. Dazu öffnest du die Datei mit folgendem Befehl:

nano .env 

Nun musst du folgende Zeilen anpassen:

vorher:

FUNKWHALE_HOSTNAME=yourdomain.funkwhale 

MEDIA_ROOT=/srv/funkwhale/data/media 

STATIC_ROOT=/srv/funkwhale/data/static 

DJANGO_SECRET_KEY= 

MUSIC_DIRECTORY_SERVE_PATH=/srv/funkwhale/data/music 

FUNKWHALE_FRONTEND_PATH=/srv/funkwhale/front/dist 

nachher:

FUNKWHALE_HOSTNAME=funkwhale.testbereich.net 

MEDIA_ROOT=/opt/containers/funkwhale/media 

STATIC_ROOT=/opt/containers/funkwhale/static 

DJANGO_SECRET_KEY=xbFRVxp663q3zkmbEdKWG3Dxvxzbx2pCL0PB01aL+tuPxnOuiZJUrHhcoCPX 

MUSIC_DIRECTORY_SERVE_PATH=/opt/containers/funkwhale/music 

FUNKWHALE_FRONTEND_PATH=/opt/containers/funkwhale/front 

Wichtig ist, dass der „FUNKWHALE_HOSTNAME“ mit der URL übereinstimmt, welche du in der Docker Compose Datei festgelegt hast. Der „DJANGO_SECRET_KEY“ ist der Key, den du eben generiert hast.

1.3.7 Images downloaden

Nun laden wir uns alle Images herunter, die wir später benötigen. Dazu gibst du folgendes ein:

docker compose pull 

1.3.8 Datenbank initiieren

Dazu gibst du folgendes ein:

docker compose up -d postgres 

docker compose run --rm api python manage.py migrate 

Dies sollte dann so aussehen:

Datenbank initiieren für funkwhale

1.3.9 Admin Benutzer erstellen

Nun erstellen wir unseren Admin Benutzer. Dazu gibst du folgendes ein:

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

So sieht der Dialog bei mir aus. Die ganzen „gelben Hinweise“ kannst du ignorieren.

Admin Benutzer erstellen

2. Funkwhale starten

Nun kannst du Funkwhale starten. Dazu gibst du folgendes ein:

docker compose -f /opt/containers/funkwhale/docker-compose.yml up -d 

Nach einigen Minuten sollte Funkwhale im Browser zur Verfügung stehen. Dazu gehst du auf die Domain, welche du in der Docker Compose Konfiguration eingegeben hast. Bei mir ist dies: https://funkwhale.testbereich.net

Jetzt solltest du folgendes sehen:

Willkommen bei funkwhale

Hier kannst du dich nun mit deinem eben erstellen Benutzer anmelden.

Mit erstelltem Benutzer bei funkwhale anmelden

Anschließend bist du Teil des sozialen Netzwerks und kannst mit anderen Personen Musik austauschen.

Funkwhale Benutzeroberfläche

easyname ist ein erfolgreicher und bekannter österreichischer Anbieter von Cloud-Services, Domains sowie Webhosting bis hin zur Server-Infrastruktur und gehört seit 2020 zur dogado group.
Das Unternehmen ist seit 2006 in Österreich erfolgreich am Markt und inzwischen auch in vielen anderen Ländern weltweit tätig. Sowohl das Team als auch die gehosteten Daten befinden sich in Österreich.

easyname liegt die Datensicherheit besonders am Herzen und stellt daher zu jedem Hosting-Paket auch kostenlose SSL-Zertifikate zur Verfügung. Mit intuitiven Tools zur Erstellung von Websites und Webshops und mit Easy Install Apps wie WordPress, Joomla oder PrestaShop können alle easyname-Kunden schnell in die Online-Welt einsteigen.