Merge branch 'chore/2406-compose-modularity-scope' into 'develop'
Chore: stabilise development environment manifests + documentation Closes #2406 See merge request funkwhale/funkwhale!2897
This commit is contained in:
commit
0beee1bd05
|
@ -0,0 +1,9 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
30
.env.example
30
.env.example
|
@ -1,16 +1,20 @@
|
||||||
# api + celeryworker
|
COMPOSE_BAKE=true
|
||||||
|
|
||||||
|
# api + worker
|
||||||
DEBUG=True
|
DEBUG=True
|
||||||
|
FORCE=True
|
||||||
DEFAULT_FROM_EMAIL=hello@funkwhale.test
|
DEFAULT_FROM_EMAIL=hello@funkwhale.test
|
||||||
|
|
||||||
FUNKWHALE_DOMAIN=funkwhale.test
|
FUNKWHALE_DOMAIN=funkwhale.test
|
||||||
FUNKWHALE_PROTOCOL=https
|
FUNKWHALE_PROTOCOL=https
|
||||||
|
|
||||||
DJANGO_SECRET_KEY=dev
|
DJANGO_SECRET_KEY=dev
|
||||||
DJANGO_ALLOWED_HOSTS=.funkwhale.test,nginx
|
DJANGO_ALLOWED_HOSTS=.funkwhale.test,web
|
||||||
DJANGO_SETTINGS_MODULE=config.settings.local
|
DJANGO_SETTINGS_MODULE=config.settings.local
|
||||||
|
|
||||||
DATABASE_URL=postgresql://postgres@postgres/postgres
|
DATABASE_URL=postgresql://postgres@postgres/postgres
|
||||||
CACHE_URL=redis://redis:6379/0
|
CACHE_URL=redis://redis:6379/0
|
||||||
|
CELERY_BROKER_URL=redis://redis:6379/1
|
||||||
EMAIL_CONFIG=smtp://mailpit.funkwhale.test:1025
|
EMAIL_CONFIG=smtp://mailpit.funkwhale.test:1025
|
||||||
|
|
||||||
FORCE_HTTPS_URLS=True
|
FORCE_HTTPS_URLS=True
|
||||||
|
@ -20,17 +24,18 @@ C_FORCE_ROOT=true
|
||||||
PYTHONDONTWRITEBYTECODE=true
|
PYTHONDONTWRITEBYTECODE=true
|
||||||
PYTHONTRACEMALLOC=0
|
PYTHONTRACEMALLOC=0
|
||||||
|
|
||||||
|
# app
|
||||||
|
|
||||||
|
HOST=0.0.0.0
|
||||||
|
VUE_PORT=8080
|
||||||
|
|
||||||
# api
|
# api
|
||||||
|
|
||||||
FUNKWHALE_SPA_HTML_ROOT=http://nginx/
|
FUNKWHALE_SPA_HTML_ROOT=http://app:${VUE_PORT}
|
||||||
LDAP_ENABLED=False
|
LDAP_ENABLED=False
|
||||||
BROWSABLE_API_ENABLED=True
|
BROWSABLE_API_ENABLED=True
|
||||||
|
|
||||||
# celeryworker
|
# api + web
|
||||||
|
|
||||||
CELERYD_CONCURRENCY=0
|
|
||||||
|
|
||||||
# api + nginx
|
|
||||||
|
|
||||||
STATIC_ROOT=/staticfiles
|
STATIC_ROOT=/staticfiles
|
||||||
MEDIA_ROOT=/data/media
|
MEDIA_ROOT=/data/media
|
||||||
|
@ -38,19 +43,14 @@ MEDIA_ROOT=/data/media
|
||||||
# api + Typesense
|
# api + Typesense
|
||||||
TYPESENSE_API_KEY=apikey
|
TYPESENSE_API_KEY=apikey
|
||||||
|
|
||||||
# front
|
# web
|
||||||
|
|
||||||
HOST=0.0.0.0
|
|
||||||
VUE_PORT=8080
|
|
||||||
|
|
||||||
# nginx
|
|
||||||
|
|
||||||
NGINX_MAX_BODY_SIZE=10G
|
NGINX_MAX_BODY_SIZE=10G
|
||||||
|
|
||||||
FUNKWHALE_API_HOST=api
|
FUNKWHALE_API_HOST=api
|
||||||
FUNKWHALE_API_PORT=5000
|
FUNKWHALE_API_PORT=5000
|
||||||
|
|
||||||
FUNKWHALE_FRONT_IP=front
|
FUNKWHALE_FRONT_HOST=app
|
||||||
FUNKWHALE_FRONT_PORT=${VUE_PORT}
|
FUNKWHALE_FRONT_PORT=${VUE_PORT}
|
||||||
|
|
||||||
# postgres
|
# postgres
|
||||||
|
|
|
@ -30,7 +30,7 @@ services:
|
||||||
- "FUNKWHALE_API_IP=host.docker.internal"
|
- "FUNKWHALE_API_IP=host.docker.internal"
|
||||||
- "FUNKWHALE_API_HOST=host.docker.internal"
|
- "FUNKWHALE_API_HOST=host.docker.internal"
|
||||||
- "FUNKWHALE_API_PORT=5000"
|
- "FUNKWHALE_API_PORT=5000"
|
||||||
- "FUNKWHALE_FRONT_IP=host.docker.internal"
|
- "FUNKWHALE_FRONT_HOST=host.docker.internal"
|
||||||
- "FUNKWHALE_FRONT_PORT=8080"
|
- "FUNKWHALE_FRONT_PORT=8080"
|
||||||
- "FUNKWHALE_HOSTNAME=${FUNKWHALE_HOSTNAME-host.docker.internal}"
|
- "FUNKWHALE_HOSTNAME=${FUNKWHALE_HOSTNAME-host.docker.internal}"
|
||||||
- "FUNKWHALE_PROTOCOL=https"
|
- "FUNKWHALE_PROTOCOL=https"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Exclude everything and allow only the necessary files
|
# Exclude everything and allow only the necessary files
|
||||||
*
|
*
|
||||||
!/docker/
|
|
||||||
!/config/
|
!/config/
|
||||||
!/funkwhale_api/
|
!/funkwhale_api/
|
||||||
|
!/entrypoint.sh
|
||||||
!/manage.py
|
!/manage.py
|
||||||
!/poetry.lock
|
!/poetry.lock
|
||||||
!/pyproject.toml
|
!/pyproject.toml
|
||||||
|
|
|
@ -103,6 +103,7 @@ ARG PIP_NO_CACHE_DIR=1
|
||||||
RUN set -eux; \
|
RUN set -eux; \
|
||||||
apk add --no-cache \
|
apk add --no-cache \
|
||||||
bash \
|
bash \
|
||||||
|
curl \
|
||||||
ffmpeg \
|
ffmpeg \
|
||||||
gettext \
|
gettext \
|
||||||
jpeg-dev \
|
jpeg-dev \
|
||||||
|
@ -132,6 +133,5 @@ RUN --mount=type=cache,target=~/.cache/pip; \
|
||||||
set -eux; \
|
set -eux; \
|
||||||
pip3 install --no-deps --editable .
|
pip3 install --no-deps --editable .
|
||||||
|
|
||||||
ENV IS_DOCKER_SETUP=true
|
ADD --chown=0:0 --chmod=0755 ./entrypoint.sh /
|
||||||
|
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||||
CMD ["./docker/server.sh"]
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ ENV PATH="/venv/bin:$PATH"
|
||||||
RUN --mount=type=cache,target=/var/lib/apt/lists \
|
RUN --mount=type=cache,target=/var/lib/apt/lists \
|
||||||
apt update; \
|
apt update; \
|
||||||
apt install -y \
|
apt install -y \
|
||||||
|
curl \
|
||||||
ffmpeg \
|
ffmpeg \
|
||||||
gettext \
|
gettext \
|
||||||
libjpeg-dev \
|
libjpeg-dev \
|
||||||
|
@ -68,4 +69,5 @@ WORKDIR /app
|
||||||
COPY . /app
|
COPY . /app
|
||||||
RUN poetry install --extras typesense
|
RUN poetry install --extras typesense
|
||||||
|
|
||||||
CMD ["./docker/server.sh"]
|
ADD --chown=0:0 --chmod=0755 ./entrypoint.sh /
|
||||||
|
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import logging.config
|
import logging.config
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from urllib.parse import urlparse, urlsplit
|
from urllib.parse import urlparse, urlsplit
|
||||||
|
|
||||||
|
@ -36,8 +35,8 @@ Available levels:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
IS_DOCKER_SETUP = env.bool("IS_DOCKER_SETUP", False)
|
# allows makemigrations and superuser creation
|
||||||
|
FORCE = env.bool("FORCE", False)
|
||||||
|
|
||||||
if env("FUNKWHALE_SENTRY_DSN", default=None) is not None:
|
if env("FUNKWHALE_SENTRY_DSN", default=None) is not None:
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
|
@ -393,31 +392,6 @@ vars().update(EMAIL_CONFIG)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
|
||||||
|
|
||||||
# The `_database_url_docker` variable will only by used as default for DATABASE_URL
|
|
||||||
# in the context of a docker deployment.
|
|
||||||
_database_url_docker = None
|
|
||||||
if IS_DOCKER_SETUP and env.str("DATABASE_URL", None) is None:
|
|
||||||
warnings.warn(
|
|
||||||
DeprecationWarning(
|
|
||||||
"the automatically generated 'DATABASE_URL' configuration in the docker "
|
|
||||||
"setup is deprecated, please configure either the 'DATABASE_URL' "
|
|
||||||
"environment variable or the 'DATABASE_HOST', 'DATABASE_USER' and "
|
|
||||||
"'DATABASE_PASSWORD' environment variables instead"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
_DOCKER_DATABASE_HOST = "postgres"
|
|
||||||
_DOCKER_DATABASE_PORT = 5432
|
|
||||||
_DOCKER_DATABASE_USER = env.str("POSTGRES_ENV_POSTGRES_USER", "postgres")
|
|
||||||
_DOCKER_DATABASE_PASSWORD = env.str("POSTGRES_ENV_POSTGRES_PASSWORD", "")
|
|
||||||
_DOCKER_DATABASE_NAME = _DOCKER_DATABASE_USER
|
|
||||||
|
|
||||||
_database_url_docker = (
|
|
||||||
f"postgres:"
|
|
||||||
f"//{_DOCKER_DATABASE_USER}:{_DOCKER_DATABASE_PASSWORD}"
|
|
||||||
f"@{_DOCKER_DATABASE_HOST}:{_DOCKER_DATABASE_PORT}"
|
|
||||||
f"/{_DOCKER_DATABASE_NAME}"
|
|
||||||
)
|
|
||||||
|
|
||||||
DATABASE_HOST = env.str("DATABASE_HOST", "localhost")
|
DATABASE_HOST = env.str("DATABASE_HOST", "localhost")
|
||||||
"""
|
"""
|
||||||
The hostname of the PostgreSQL server. Defaults to ``localhost``.
|
The hostname of the PostgreSQL server. Defaults to ``localhost``.
|
||||||
|
@ -440,8 +414,7 @@ The name of the PostgreSQL database. Defaults to ``funkwhale``.
|
||||||
"""
|
"""
|
||||||
DATABASE_URL = env.db(
|
DATABASE_URL = env.db(
|
||||||
"DATABASE_URL",
|
"DATABASE_URL",
|
||||||
_database_url_docker # This is only set in the context of a docker deployment.
|
(
|
||||||
or (
|
|
||||||
f"postgres:"
|
f"postgres:"
|
||||||
f"//{DATABASE_USER}:{DATABASE_PASSWORD}"
|
f"//{DATABASE_USER}:{DATABASE_PASSWORD}"
|
||||||
f"@{DATABASE_HOST}:{DATABASE_PORT}"
|
f"@{DATABASE_HOST}:{DATABASE_PORT}"
|
||||||
|
@ -838,11 +811,7 @@ if AUTH_LDAP_ENABLED:
|
||||||
# SLUGLIFIER
|
# SLUGLIFIER
|
||||||
AUTOSLUG_SLUGIFY_FUNCTION = "slugify.slugify"
|
AUTOSLUG_SLUGIFY_FUNCTION = "slugify.slugify"
|
||||||
|
|
||||||
CACHE_URL_DEFAULT = "redis://127.0.0.1:6379/0"
|
CACHE_URL = env.str("CACHE_URL", default="redis://127.0.0.1:6379/0")
|
||||||
if IS_DOCKER_SETUP:
|
|
||||||
CACHE_URL_DEFAULT = "redis://redis:6379/0"
|
|
||||||
|
|
||||||
CACHE_URL = env.str("CACHE_URL", default=CACHE_URL_DEFAULT)
|
|
||||||
"""
|
"""
|
||||||
The URL of your redis server. For example:
|
The URL of your redis server. For example:
|
||||||
|
|
||||||
|
@ -1527,10 +1496,7 @@ TYPESENSE_PROTOCOL = env("TYPESENSE_PROTOCOL", default="http")
|
||||||
"""Typesense listening protocol"""
|
"""Typesense listening protocol"""
|
||||||
TYPESENSE_HOST = env(
|
TYPESENSE_HOST = env(
|
||||||
"TYPESENSE_HOST",
|
"TYPESENSE_HOST",
|
||||||
default="typesense" if IS_DOCKER_SETUP else "localhost",
|
default="localhost",
|
||||||
)
|
)
|
||||||
"""
|
"""Typesense hostname. Defaults to `localhost`."""
|
||||||
Typesense hostname. Defaults to `localhost` on non-Docker deployments and to `typesense` on
|
|
||||||
Docker deployments.
|
|
||||||
"""
|
|
||||||
TYPESENSE_NUM_TYPO = env("TYPESENSE_NUM_TYPO", default=5)
|
TYPESENSE_NUM_TYPO = env("TYPESENSE_NUM_TYPO", default=5)
|
||||||
|
|
|
@ -152,6 +152,3 @@ REST_FRAMEWORK.update(
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# allows makemigrations and superuser creation
|
|
||||||
FORCE = env("FORCE", default=1)
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -eux
|
|
||||||
|
|
||||||
funkwhale-manage collectstatic --noinput
|
|
||||||
funkwhale-manage migrate
|
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
exec gunicorn config.asgi:application \
|
|
||||||
--workers "${FUNKWHALE_WEB_WORKERS-1}" \
|
|
||||||
--worker-class uvicorn.workers.UvicornWorker \
|
|
||||||
--bind 0.0.0.0:"${FUNKWHALE_API_PORT}" \
|
|
||||||
${GUNICORN_ARGS-}
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
case "${1}" in
|
||||||
|
gunicorn)
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
exec gunicorn config.asgi:application \
|
||||||
|
--workers "${FUNKWHALE_WEB_WORKERS:-1}" \
|
||||||
|
--worker-class uvicorn.workers.UvicornWorker \
|
||||||
|
--bind 0.0.0.0:"${FUNKWHALE_API_PORT}" \
|
||||||
|
${GUNICORN_ARGS:-}
|
||||||
|
;;
|
||||||
|
migrate)
|
||||||
|
funkwhale-manage migrate
|
||||||
|
;;
|
||||||
|
collectstatic)
|
||||||
|
funkwhale-manage collectstatic --noinput
|
||||||
|
;;
|
||||||
|
uvicorn)
|
||||||
|
exec uvicorn \
|
||||||
|
--reload config.asgi:application \
|
||||||
|
--host 0.0.0.0 \
|
||||||
|
--port 5000 \
|
||||||
|
--reload-dir config/ \
|
||||||
|
--reload-dir funkwhale_api/
|
||||||
|
;;
|
||||||
|
develop)
|
||||||
|
${0} migrate
|
||||||
|
${0} collectstatic
|
||||||
|
${0} uvicorn
|
||||||
|
;;
|
||||||
|
develop-worker)
|
||||||
|
export CELERYD_CONCURRENCY=0
|
||||||
|
watchmedo auto-restart \
|
||||||
|
--patterns="*.py" \
|
||||||
|
--recursive \
|
||||||
|
-- \
|
||||||
|
celery \
|
||||||
|
-A funkwhale_api.taskapp worker \
|
||||||
|
-B \
|
||||||
|
-l debug \
|
||||||
|
-s /tmp/celerybeat-schedule \
|
||||||
|
--concurrency=${CELERYD_CONCURRENCY}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
exec "${@}"
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -0,0 +1 @@
|
||||||
|
Chore: refactor development environment manifests (#2406)
|
|
@ -1,4 +1,11 @@
|
||||||
name: funkwhale-net
|
name: funkwhale-net
|
||||||
|
networks:
|
||||||
|
web:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
x-networks: &networks
|
||||||
|
- web
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- path: compose/net.dnsmasq.yml
|
- path: compose/net.dnsmasq.yml
|
||||||
- path: compose/net.traefik.yml
|
- path: compose/net.traefik.yml
|
||||||
|
@ -12,4 +19,14 @@ include:
|
||||||
# Comment out the following line if you have other containers
|
# Comment out the following line if you have other containers
|
||||||
# present on the docker0 network.
|
# present on the docker0 network.
|
||||||
- path: compose/net.helpers.docker0.yml
|
- path: compose/net.helpers.docker0.yml
|
||||||
- path: compose/net.verify.yml
|
services:
|
||||||
|
verify-external-connectivity:
|
||||||
|
extends:
|
||||||
|
file: compose/net.verify.yml
|
||||||
|
service: verify-external-connectivity
|
||||||
|
networks: *networks
|
||||||
|
verify-internal-connectivity:
|
||||||
|
extends:
|
||||||
|
file: compose/net.verify.yml
|
||||||
|
service: verify-internal-connectivity
|
||||||
|
networks: *networks
|
||||||
|
|
89
compose.yml
89
compose.yml
|
@ -4,59 +4,19 @@ networks:
|
||||||
external: true
|
external: true
|
||||||
|
|
||||||
x-django: &django
|
x-django: &django
|
||||||
environment:
|
depends_on:
|
||||||
- DEBUG
|
postgres:
|
||||||
- DEFAULT_FROM_EMAIL
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
- DJANGO_SETTINGS_MODULE
|
condition: service_healthy
|
||||||
- DJANGO_SECRET_KEY
|
|
||||||
|
|
||||||
- EXTERNAL_REQUESTS_VERIFY_SSL
|
|
||||||
|
|
||||||
- "FORCE_HTTPS_URLS=${FORCE_HTTPS_URLS:-False}"
|
|
||||||
- FUNKWHALE_PROTOCOL
|
|
||||||
- "FUNKWHALE_HOSTNAME=${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}"
|
|
||||||
|
|
||||||
- DATABASE_URL
|
|
||||||
- CACHE_URL
|
|
||||||
- EMAIL_CONFIG
|
|
||||||
- TYPESENSE_API_KEY
|
|
||||||
|
|
||||||
- "STATIC_URL=${FUNKWHALE_PROTOCOL}://${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}/static/"
|
|
||||||
- "MEDIA_URL=${FUNKWHALE_PROTOCOL}://${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}/media/"
|
|
||||||
|
|
||||||
- STATIC_ROOT
|
|
||||||
- MEDIA_ROOT
|
|
||||||
|
|
||||||
- FUNKWHALE_SPA_HTML_ROOT
|
|
||||||
- LDAP_ENABLED
|
|
||||||
- BROWSABLE_API_ENABLED
|
|
||||||
- "MUSIC_DIRECTORY_PATH=${MUSIC_DIRECTORY_PATH:-/music}"
|
|
||||||
|
|
||||||
- C_FORCE_ROOT
|
|
||||||
- PYTHONDONTWRITEBYTECODE
|
|
||||||
- PYTHONTRACEMALLOC
|
|
||||||
|
|
||||||
dns: 172.17.0.1
|
dns: 172.17.0.1
|
||||||
dns_search: funkwhale.test
|
dns_search: funkwhale.test
|
||||||
|
|
||||||
services:
|
services:
|
||||||
front:
|
app:
|
||||||
build:
|
extends:
|
||||||
context: ./front
|
file: ./compose/app.vue.yml
|
||||||
dockerfile: Dockerfile.dev
|
service: app
|
||||||
ports:
|
|
||||||
- "${VUE_PORT:-8080}:${VUE_PORT:-8080}"
|
|
||||||
environment:
|
|
||||||
- HOST
|
|
||||||
- VUE_PORT
|
|
||||||
volumes:
|
|
||||||
- "./front:/app"
|
|
||||||
- "/app/node_modules"
|
|
||||||
- "./po:/po"
|
|
||||||
networks:
|
|
||||||
- internal
|
|
||||||
command: "yarn dev --host"
|
|
||||||
|
|
||||||
api:
|
api:
|
||||||
extends:
|
extends:
|
||||||
|
@ -64,41 +24,30 @@ services:
|
||||||
service: api
|
service: api
|
||||||
<<: *django
|
<<: *django
|
||||||
|
|
||||||
celeryworker:
|
worker:
|
||||||
extends:
|
extends:
|
||||||
file: ./compose/app.django.yml
|
file: ./compose/app.django.yml
|
||||||
service: celeryworker
|
service: worker
|
||||||
<<: *django
|
<<: *django
|
||||||
|
|
||||||
nginx:
|
web:
|
||||||
extends:
|
extends:
|
||||||
file: ./compose/app.nginx.yml
|
file: ./compose/app.nginx.yml
|
||||||
service: nginx
|
service: web
|
||||||
environment:
|
depends_on:
|
||||||
- "MUSIC_DIRECTORY_PATH=${MUSIC_DIRECTORY_PATH:-/music}"
|
app:
|
||||||
- "FUNKWHALE_HOSTNAME=${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}"
|
condition: service_healthy
|
||||||
|
api:
|
||||||
- FUNKWHALE_PROTOCOL
|
condition: service_healthy
|
||||||
|
|
||||||
- FUNKWHALE_API_HOST
|
|
||||||
- FUNKWHALE_API_PORT
|
|
||||||
|
|
||||||
- FUNKWHALE_FRONT_IP
|
|
||||||
- FUNKWHALE_FRONT_PORT
|
|
||||||
|
|
||||||
- NGINX_MAX_BODY_SIZE
|
|
||||||
|
|
||||||
- STATIC_ROOT
|
|
||||||
- "MEDIA_ROOT=${MEDIA_ROOT:-/data/media}"
|
|
||||||
networks:
|
networks:
|
||||||
- web
|
- web
|
||||||
- internal
|
- internal
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
|
|
||||||
- "traefik.http.routers.test-funkwhale-${COMPOSE_PROJECT_NAME:-funkwhale}-web.rule=Host(`${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}`)"
|
- "traefik.http.routers.test-funkwhale-${COMPOSE_PROJECT_NAME:-funkwhale}-web.rule=Host(`${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}`)"
|
||||||
- "traefik.http.routers.test-funkwhale-${COMPOSE_PROJECT_NAME:-funkwhale}-web.entrypoints=web"
|
- "traefik.http.routers.test-funkwhale-${COMPOSE_PROJECT_NAME:-funkwhale}-web.entrypoints=web"
|
||||||
|
- "traefik.http.routers.test-funkwhale-${COMPOSE_PROJECT_NAME:-funkwhale}-web.middlewares=redirect-scheme@file"
|
||||||
|
|
||||||
- "traefik.http.routers.test-funkwhale-${COMPOSE_PROJECT_NAME:-funkwhale}-webs.rule=Host(`${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}`)"
|
- "traefik.http.routers.test-funkwhale-${COMPOSE_PROJECT_NAME:-funkwhale}-webs.rule=Host(`${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}`)"
|
||||||
- "traefik.http.routers.test-funkwhale-${COMPOSE_PROJECT_NAME:-funkwhale}-webs.entrypoints=webs"
|
- "traefik.http.routers.test-funkwhale-${COMPOSE_PROJECT_NAME:-funkwhale}-webs.entrypoints=webs"
|
||||||
|
|
|
@ -1,20 +1,49 @@
|
||||||
x-django: &django
|
x-django: &django
|
||||||
image: funkwhale-api
|
image: funkwhale-api
|
||||||
|
init: true
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
volumes:
|
volumes:
|
||||||
- ../api:/app
|
- ../api:/app
|
||||||
- ../.env:/app/.env
|
|
||||||
- "${MUSIC_DIRECTORY_SERVE_PATH:-../.state/music}:/music:ro"
|
- "${MUSIC_DIRECTORY_SERVE_PATH:-../.state/music}:/music:ro"
|
||||||
- "../.state/plugins:/srv/funkwhale/plugins"
|
- "../.state/plugins:/srv/funkwhale/plugins"
|
||||||
- "../.state/staticfiles:/staticfiles"
|
- "../.state/staticfiles:/staticfiles"
|
||||||
- "../.state/media:/protected/media"
|
- "../.state/media:/protected/media"
|
||||||
- "../.state/${COMPOSE_PROJECT_NAME:-funkwhale}/media:/data/media"
|
- "../.state/${COMPOSE_PROJECT_NAME:-funkwhale}/media:/data/media"
|
||||||
depends_on:
|
environment:
|
||||||
postgres:
|
- DEBUG
|
||||||
condition: service_healthy
|
- FORCE
|
||||||
redis:
|
- DEFAULT_FROM_EMAIL
|
||||||
condition: service_healthy
|
|
||||||
networks:
|
- DJANGO_SETTINGS_MODULE
|
||||||
- internal
|
- DJANGO_SECRET_KEY
|
||||||
|
|
||||||
|
- EXTERNAL_REQUESTS_VERIFY_SSL
|
||||||
|
|
||||||
|
- "FORCE_HTTPS_URLS=${FORCE_HTTPS_URLS:-False}"
|
||||||
|
- FUNKWHALE_PROTOCOL
|
||||||
|
- "FUNKWHALE_HOSTNAME=${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}"
|
||||||
|
|
||||||
|
- DATABASE_URL
|
||||||
|
- CACHE_URL
|
||||||
|
- CELERY_BROKER_URL
|
||||||
|
- EMAIL_CONFIG
|
||||||
|
- TYPESENSE_API_KEY
|
||||||
|
|
||||||
|
- "STATIC_URL=${FUNKWHALE_PROTOCOL}://${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}/static/"
|
||||||
|
- "MEDIA_URL=${FUNKWHALE_PROTOCOL}://${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}/media/"
|
||||||
|
|
||||||
|
- STATIC_ROOT
|
||||||
|
- MEDIA_ROOT
|
||||||
|
|
||||||
|
- FUNKWHALE_SPA_HTML_ROOT
|
||||||
|
- LDAP_ENABLED
|
||||||
|
- BROWSABLE_API_ENABLED
|
||||||
|
- "MUSIC_DIRECTORY_PATH=${MUSIC_DIRECTORY_PATH:-/music}"
|
||||||
|
|
||||||
|
- C_FORCE_ROOT
|
||||||
|
- PYTHONDONTWRITEBYTECODE
|
||||||
|
- PYTHONTRACEMALLOC
|
||||||
|
|
||||||
services:
|
services:
|
||||||
api:
|
api:
|
||||||
|
@ -22,28 +51,28 @@ services:
|
||||||
build:
|
build:
|
||||||
context: ../api
|
context: ../api
|
||||||
dockerfile: Dockerfile.debian
|
dockerfile: Dockerfile.debian
|
||||||
|
command: develop
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test:
|
||||||
[
|
[
|
||||||
"CMD-SHELL",
|
"CMD-SHELL",
|
||||||
'docker compose logs api | grep -q "Uvicorn running on" || exit 0',
|
"curl -o /dev/null -s -w '%{http_code}' http://localhost:5000/api/v1 | grep '301' || exit 1",
|
||||||
]
|
]
|
||||||
interval: 3s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 3
|
retries: 3
|
||||||
command: >
|
start_period: 60s
|
||||||
sh -c "
|
|
||||||
funkwhale-manage collectstatic --no-input &&
|
|
||||||
uvicorn --reload config.asgi:application --host 0.0.0.0 --port 5000 --reload-dir config/ --reload-dir funkwhale_api/
|
|
||||||
"
|
|
||||||
|
|
||||||
celeryworker:
|
worker:
|
||||||
<<: *django
|
<<: *django
|
||||||
command: >
|
command: develop-worker
|
||||||
sh -c '
|
healthcheck:
|
||||||
pip install watchdog[watchmedo] &&
|
test:
|
||||||
watchmedo auto-restart --patterns="*.py" --recursive -- celery -A funkwhale_api.taskapp worker -l debug -B --concurrency=${CELERYD_CONCURRENCY}
|
[
|
||||||
'
|
"CMD-SHELL",
|
||||||
depends_on:
|
"celery -A funkwhale_api.taskapp status | grep 'OK' || exit 1",
|
||||||
api:
|
]
|
||||||
condition: service_healthy
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 30s
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
services:
|
services:
|
||||||
nginx:
|
web:
|
||||||
image: nginx
|
image: nginx
|
||||||
depends_on:
|
networks:
|
||||||
- api
|
- internal
|
||||||
- front
|
environment:
|
||||||
|
- "MUSIC_DIRECTORY_PATH=${MUSIC_DIRECTORY_PATH:-/music}"
|
||||||
|
- "FUNKWHALE_HOSTNAME=${COMPOSE_PROJECT_NAME:-funkwhale}.${FUNKWHALE_DOMAIN}"
|
||||||
|
|
||||||
|
- FUNKWHALE_PROTOCOL
|
||||||
|
|
||||||
|
- FUNKWHALE_API_HOST
|
||||||
|
- FUNKWHALE_API_PORT
|
||||||
|
|
||||||
|
- FUNKWHALE_FRONT_HOST
|
||||||
|
- FUNKWHALE_FRONT_PORT
|
||||||
|
|
||||||
|
- NGINX_MAX_BODY_SIZE
|
||||||
|
|
||||||
|
- STATIC_ROOT
|
||||||
|
- "MEDIA_ROOT=${MEDIA_ROOT:-/data/media}"
|
||||||
volumes:
|
volumes:
|
||||||
- "${MUSIC_DIRECTORY_SERVE_PATH:-../.state/music}:${MUSIC_DIRECTORY_PATH:-/music}:ro"
|
- "${MUSIC_DIRECTORY_SERVE_PATH:-../.state/music}:${MUSIC_DIRECTORY_PATH:-/music}:ro"
|
||||||
|
|
||||||
|
@ -14,5 +29,8 @@ services:
|
||||||
- ../.state/staticfiles:/usr/share/nginx/html/staticfiles:ro
|
- ../.state/staticfiles:/usr/share/nginx/html/staticfiles:ro
|
||||||
- ../.state/media:/protected/media:ro
|
- ../.state/media:/protected/media:ro
|
||||||
- ../.state/${COMPOSE_PROJECT_NAME:-funkwhale}/media:/data/media:ro
|
- ../.state/${COMPOSE_PROJECT_NAME:-funkwhale}/media:/data/media:ro
|
||||||
networks:
|
healthcheck:
|
||||||
- internal
|
test: 'curl -o /dev/null -s -w "%{http_code}" http://localhost:80/ | grep "200" || exit 1'
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
|
|
@ -2,9 +2,20 @@ services:
|
||||||
typesense:
|
typesense:
|
||||||
environment:
|
environment:
|
||||||
- TYPESENSE_API_KEY
|
- TYPESENSE_API_KEY
|
||||||
image: typesense/typesense:27.1
|
image: typesense/typesense:28.0
|
||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
volumes:
|
volumes:
|
||||||
- ../.state/${COMPOSE_PROJECT_NAME:-funkwhale}/typesense/data:/data
|
- ../.state/${COMPOSE_PROJECT_NAME:-funkwhale}/typesense/data:/data
|
||||||
command: --data-dir /data --api-key=$${TYPESENSE_API_KEY} --enable-cors
|
command: --data-dir /data --api-key=$${TYPESENSE_API_KEY} --enable-cors
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD",
|
||||||
|
"bash",
|
||||||
|
"-c",
|
||||||
|
"exec 3<>/dev/tcp/localhost/8108 && printf 'GET /health HTTP/1.1\\r\\nConnection: close\\r\\n\\r\\n' >&3 && head -n1 <&3 | grep '200' && exec 3>&-",
|
||||||
|
]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: funkwhale-app
|
||||||
|
build:
|
||||||
|
context: ../front
|
||||||
|
dockerfile: Dockerfile.dev
|
||||||
|
command: "yarn dev --host"
|
||||||
|
ports:
|
||||||
|
- "${VUE_PORT:-8080}:${VUE_PORT:-8080}"
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
volumes:
|
||||||
|
- "../front:/app"
|
||||||
|
- "/app/node_modules"
|
||||||
|
environment:
|
||||||
|
- HOST
|
||||||
|
- VUE_PORT
|
|
@ -4,7 +4,7 @@ upstream funkwhale-api {
|
||||||
}
|
}
|
||||||
|
|
||||||
upstream funkwhale-front {
|
upstream funkwhale-front {
|
||||||
server ${FUNKWHALE_FRONT_IP}:${FUNKWHALE_FRONT_PORT};
|
server ${FUNKWHALE_FRONT_HOST}:${FUNKWHALE_FRONT_PORT};
|
||||||
}
|
}
|
||||||
|
|
||||||
# Required for websocket support.
|
# Required for websocket support.
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
redirect-scheme:
|
||||||
|
redirectScheme:
|
||||||
|
scheme: https
|
||||||
|
permanent: false
|
|
@ -18,6 +18,6 @@ services:
|
||||||
depends_on:
|
depends_on:
|
||||||
minio: {}
|
minio: {}
|
||||||
|
|
||||||
celeryworker:
|
worker:
|
||||||
depends_on:
|
depends_on:
|
||||||
minio: {}
|
minio: {}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
x-verify: &verify
|
x-verify: &verify
|
||||||
init: true
|
init: true
|
||||||
image: "busybox"
|
image: "busybox"
|
||||||
network_mode: bridge
|
|
||||||
dns: 172.17.0.1
|
dns: 172.17.0.1
|
||||||
dns_search: funkwhale.test
|
dns_search: funkwhale.test
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,13 @@ Funkwhale can be run in Docker containers for local development. You can work on
|
||||||
::::
|
::::
|
||||||
|
|
||||||
6. Activate the pre-commit hook:
|
6. Activate the pre-commit hook:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pre-commit install
|
pre-commit install
|
||||||
```
|
```
|
||||||
|
|
||||||
7. Finally, initialise the environment:
|
7. Finally, initialise the environment:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
@ -50,16 +53,18 @@ Funkwhale provides a `compose.yml` file following the default file naming conven
|
||||||
To set up your Docker environment:
|
To set up your Docker environment:
|
||||||
|
|
||||||
1. Create a network for federation support via the web proxy:
|
1. Create a network for federation support via the web proxy:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker network create web
|
docker network create web
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Then build the application containers. Run this command any time there are upstream changes or dependency changes to ensure you're up-to-date.
|
2. Then build the application containers. Run this command any time there are upstream changes or dependency changes to ensure you're up-to-date.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker compose build
|
docker compose build
|
||||||
```
|
```
|
||||||
|
|
||||||
## Set up auxiliary services
|
## Set up network services
|
||||||
|
|
||||||
To support ActivityPub in the local development environment, we use a
|
To support ActivityPub in the local development environment, we use a
|
||||||
combination of auxiliary services that provide DNS-based discovery, local email delivery and web/TLS termination. This also has the benefit that we can talk to
|
combination of auxiliary services that provide DNS-based discovery, local email delivery and web/TLS termination. This also has the benefit that we can talk to
|
||||||
|
@ -85,9 +90,11 @@ The services bind to the following ports on the default Docker bridge network:
|
||||||
1. Create a wildcard certificate for the Common Name (CN) `funkwhale.test` and
|
1. Create a wildcard certificate for the Common Name (CN) `funkwhale.test` and
|
||||||
the Subject Alternative Name (SAN) `*.funkwhale.test` which will be
|
the Subject Alternative Name (SAN) `*.funkwhale.test` which will be
|
||||||
installed into your system and browser trust stores with:
|
installed into your system and browser trust stores with:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkcert -install -cert-file compose/var/test.crt -key-file compose/var/test.key "funkwhale.test" "*.funkwhale.test"
|
mkcert -install -cert-file compose/var/test.crt -key-file compose/var/test.key "funkwhale.test" "*.funkwhale.test"
|
||||||
```
|
```
|
||||||
|
|
||||||
It will be used by Træefik to secure connections, which is needed for
|
It will be used by Træefik to secure connections, which is needed for
|
||||||
ActivityPub to work locally.
|
ActivityPub to work locally.
|
||||||
|
|
||||||
|
@ -257,43 +264,113 @@ Review the configuration:
|
||||||
docker compose config
|
docker compose config
|
||||||
```
|
```
|
||||||
|
|
||||||
### Set up local data for development
|
## Set up example data for development
|
||||||
|
|
||||||
You can create local data to mimic a live environment.
|
You can create local data to simulate a live environment. We are providing a procedure to create fake data to populate the database. The following command creates 25 artists with random albums, tracks, and metadata.
|
||||||
|
|
||||||
Add some fake data to populate the database. The following command creates 25 artists with random albums, tracks, and metadata.
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
command="from funkwhale_api.music import fake_data; fake_data.create_data()"
|
docker compose run --rm -T api \
|
||||||
echo $command | docker compose run --rm -T api funkwhale-manage shell -i python
|
funkwhale-manage shell -i python \
|
||||||
|
<<< \
|
||||||
|
"from funkwhale_api.music import fake_data; fake_data.create_data()"
|
||||||
```
|
```
|
||||||
|
|
||||||
This will launch a development funkwhale instance with a super user having `COMPOSE_PROJECT_NAME` as username and `funkwhale` as password. Libraries, listenings and music data will be associated with the superuser :
|
The generated tracks do not contain any audio and are here for testing purposes of metadata handling only.
|
||||||
|
|
||||||
|
## Set up local documentation
|
||||||
|
|
||||||
|
To build the documentation locally run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export COMPOSE_PROJECT_NAME=node1 ; export VUE_PORT=8882 ; docker compose run --rm api funkwhale-manage migrate ; echo "from funkwhale_api.music import fake_data; fake_data.create_data(super_user_name=\"$COMPOSE_PROJECT_NAME\")" | docker compose run --rm -T api funkwhale-manage shell -i python
|
docker compose -f compose.docs.yml up -d
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```{note}
|
The documentation is then accessible at <https://docs.funkwhale.test>. The OpenAPI schema is available at <https://openapi.funkwhale.test>. The UI component library will be served at <https://ui.funkwhale.test>.
|
||||||
Username `funkwhale` is not permitted. You need to export COMPOSE_PROJECT_NAME to make sure it's different from `funkwhale`
|
|
||||||
|
Fallback ports are available for the documentation at <http://localhost:8001/>, for the OpenAPI schema at <http://localhost:8002/> and for the UI component library at <http://localhost:8003/>.
|
||||||
|
|
||||||
|
Maintain their life cycle with similar commands to those used to
|
||||||
|
[set up network services (point 2.)](#set-up-network-services).
|
||||||
|
|
||||||
|
## Lifecycle
|
||||||
|
|
||||||
|
Your local Funkwhale development environment will undergo various lifecycles
|
||||||
|
during its existence. This is due to the immutable nature of containers and the
|
||||||
|
way how we selectively apply state to them.
|
||||||
|
|
||||||
|
Make yourself familiar with the following lifecycle commands to get an
|
||||||
|
impression of the phase changes that happen in your local deployment.
|
||||||
|
|
||||||
|
::::{tab-set}
|
||||||
|
|
||||||
|
:::{tab-item} Application lifecycle
|
||||||
|
|
||||||
|
Build the application images, which will be used to create containers later.
|
||||||
|
This is often also needed after switching a branch or pulling new commits.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose build
|
||||||
```
|
```
|
||||||
|
|
||||||
### Lifecycle
|
> Selectively rebuild container images.
|
||||||
|
>
|
||||||
|
> ```sh
|
||||||
|
> docker compose build api
|
||||||
|
> ```
|
||||||
|
|
||||||
|
Start the whole composition detached (`-d`) in the background:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
List running containers:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
> You can use the `-f` flag behind the `compose` command to target alternative
|
||||||
|
> compositions:
|
||||||
|
>
|
||||||
|
> ```sh
|
||||||
|
> docker compose -f compose.net.yml ps
|
||||||
|
> docker compose -f compose.docs.yml ps -a
|
||||||
|
> ```
|
||||||
|
|
||||||
Recycle individual containers:
|
Recycle individual containers:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker compose rm -sf api celeryworker; docker compose up -d api celeryworker
|
docker compose up -d --force-recreate app api
|
||||||
```
|
```
|
||||||
|
|
||||||
Once you're done with the containers, you can stop them all:
|
> Alternative, if the previous does not work as expected:
|
||||||
|
>
|
||||||
|
> ```sh
|
||||||
|
> docker compose rm -sf api worker; docker compose up -d api worker
|
||||||
|
> ```
|
||||||
|
|
||||||
|
Once you're done for the day, you can stop them all:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker compose stop
|
docker compose stop
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to destroy your containers, run the following:
|
List all containers, including expectedly or unexpectedly exited ones:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose ps -a
|
||||||
|
```
|
||||||
|
|
||||||
|
**The following commands are destructive.**
|
||||||
|
|
||||||
|
Stop running containers and remove all of them, but keep the network:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose rm -sf
|
||||||
|
```
|
||||||
|
|
||||||
|
If you want to destroy your containers and the network, run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker compose down
|
docker compose down
|
||||||
|
@ -305,22 +382,62 @@ Destroy all state of your containers:
|
||||||
docker compose down --volumes
|
docker compose down --volumes
|
||||||
```
|
```
|
||||||
|
|
||||||
Remove all state of all Funkwhale-related containers, incl. from additional
|
**Remove all state of all Funkwhale containers**, incl. from any additional
|
||||||
instances:
|
instance:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
rm -rf .state/
|
rm -rf .state/
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running multiple instances
|
:::
|
||||||
|
|
||||||
|
:::{tab-item} Container engine lifecycle
|
||||||
|
|
||||||
|
Your container engine, often Docker or Podman, over time will accumulate state.
|
||||||
|
This state comes in form of images, networks and containers. Due to the nature
|
||||||
|
of immutable infrastructure, assets are often replaced with newer generations.
|
||||||
|
|
||||||
|
For images this means that old ones pile up, while new ones are being used with
|
||||||
|
current containers.
|
||||||
|
|
||||||
|
Delete dangling images regularly.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker image prune
|
||||||
|
```
|
||||||
|
|
||||||
|
Delete all unused images, which are not used by any container, regularly.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker image prune -a
|
||||||
|
```
|
||||||
|
|
||||||
|
Delete all unused networks regularly.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker network prune
|
||||||
|
```
|
||||||
|
|
||||||
|
In case you run into trouble, as a last resort you can always reset the state of
|
||||||
|
your container engine completely.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker system prune -a
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::::
|
||||||
|
|
||||||
|
## Running multiple instances
|
||||||
|
|
||||||
Set up as many different projects as you need. Make sure the
|
Set up as many different projects as you need. Make sure the
|
||||||
`COMPOSE_PROJECT_NAME` and `VUE_PORT` variables are unique per instance.
|
`COMPOSE_PROJECT_NAME` and `VUE_PORT` variables are unique per instance.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export COMPOSE_PROJECT_NAME=node2
|
export COMPOSE_PROJECT_NAME=node1
|
||||||
# VUE_PORT this has to be unique for each instance
|
# VUE_PORT this has to be unique for each instance
|
||||||
export VUE_PORT=1234
|
export VUE_PORT=8081
|
||||||
docker compose run --rm api funkwhale-manage fw users create --superuser
|
docker compose run --rm api funkwhale-manage fw users create --superuser
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
@ -333,23 +450,29 @@ You can access your project at `https://{COMPOSE_PROJECT_NAME}.funkwhale.test`.
|
||||||
You may as well address the different Compose projects by using ad hoc
|
You may as well address the different Compose projects by using ad hoc
|
||||||
environment variables:
|
environment variables:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
COMPOSE_PROJECT_NAME=node1 VUE_PORT=1234 docker compose run --rm api funkwhale-manage fw users create --superuser
|
COMPOSE_PROJECT_NAME=node1 VUE_PORT=8081 docker compose run --rm api funkwhale-manage fw users create --superuser
|
||||||
COMPOSE_PROJECT_NAME=node1 VUE_PORT=1234 docker compose up -d
|
COMPOSE_PROJECT_NAME=node1 VUE_PORT=8081 docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
The `node1` instance will be available at [https://node1.funkwhale.test](https://node1.funkwhale.test).
|
The `node1` instance will be available at [https://node1.funkwhale.test](https://node1.funkwhale.test).
|
||||||
|
|
||||||
```
|
```sh
|
||||||
COMPOSE_PROJECT_NAME=node2 VUE_PORT=1235 docker compose run --rm api funkwhale-manage fw users create --superuser
|
COMPOSE_PROJECT_NAME=node2 VUE_PORT=8082 docker compose run --rm api funkwhale-manage fw users create --superuser
|
||||||
COMPOSE_PROJECT_NAME=node2 VUE_PORT=1235 docker compose up -d
|
COMPOSE_PROJECT_NAME=node2 VUE_PORT=8082 docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
The `node2` instance will be available at [https://node2.funkwhale.test](https://node2.funkwhale.test).
|
The `node2` instance will be available at [https://node2.funkwhale.test](https://node2.funkwhale.test).
|
||||||
|
|
||||||
Proceed freely with different sets of values for `COMPOSE_PROJECT_NAME` and
|
Proceed freely with different sets of non-overlapping values for `COMPOSE_PROJECT_NAME` and
|
||||||
`VUE_PORT`.
|
`VUE_PORT`.
|
||||||
|
|
||||||
|
As a rule of thumb, remember to:
|
||||||
|
|
||||||
|
- Prepend `COMPOSE_PROJECT_NAME=node1 VUE_PORT=8081` to the lifecycle commands `up` and `run` to execute containers of additional instances.
|
||||||
|
- Prepend `COMPOSE_PROJECT_NAME=node1` to any other `docker compose` command to work with the indicated instance.
|
||||||
|
|
||||||
|
By example, this mechanic also applies to the [set up of example data for development](#set-up-example-data-for-development) above.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::::{tab-set}
|
::::{tab-set}
|
||||||
|
@ -408,19 +531,60 @@ to learn how else you may interact directly with containers, when needed.
|
||||||
|
|
||||||
::::
|
::::
|
||||||
|
|
||||||
## Local documentation
|
## Updating local environments
|
||||||
|
|
||||||
To build the documentation locally run:
|
During development you will find yourself switching between branches and pulling new configuration from your remotes, at least from `develop` and your feature branches.
|
||||||
|
|
||||||
|
If the `.env.example` file changed, you need to make sure all are present in your current environment `.env`.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker compose -f compose.docs.yml up -d
|
diff .env .env.example
|
||||||
```
|
```
|
||||||
|
|
||||||
The documentation is then accessible at [https://docs.funkwhale.test](https://docs.funkwhale.test). The OpenAPI schema is available at [https://openapi.funkwhale.test](https://openapi.funkwhale.test).
|
In most cases when (a) changes are present and (b) you did not customise or modify the setup, then you are able to simply copy the new version.
|
||||||
|
|
||||||
Fallback ports are available for the documentation at
|
```sh
|
||||||
[http://localhost:8001/](http://localhost:8001/) and for the OpenAPI schema at
|
cp .env.example .env
|
||||||
[http://localhost:8002/](http://localhost:8002/).
|
```
|
||||||
|
|
||||||
Maintain their life cycle with similar commands to those used to
|
In presence of customisations, you need to adapt the values manually to the example.
|
||||||
[set up auxiliary services (point 2.)](#set-up-auxiliary-services).
|
|
||||||
|
If any of the `Dockerfile` manifests changed, you need to rebuild the (affected) containers.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose build
|
||||||
|
```
|
||||||
|
|
||||||
|
Then recreate the application containers.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose up -d --force-recreate
|
||||||
|
```
|
||||||
|
|
||||||
|
For the additional instances, this reads:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
COMPOSE_PROJECT_NAME=node1 VUE_PORT=8081 docker compose up -d --force-recreate
|
||||||
|
```
|
||||||
|
|
||||||
|
The build images from the primary instance will be reused here, since they
|
||||||
|
carry the same name and are expected to be at the same revision.
|
||||||
|
|
||||||
|
## Seeding additional instances
|
||||||
|
|
||||||
|
We provide a convenience method to initialise the additional Funkwhale instances with fake seed data altogether with a super user having `COMPOSE_PROJECT_NAME` as username and `funkwhale` as password. Libraries, listenings and music data will be associated to that superuser.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
COMPOSE_PROJECT_NAME=node1 docker compose run --rm -T api \
|
||||||
|
funkwhale-manage shell -i python \
|
||||||
|
<<< \
|
||||||
|
"from os import getenv; from funkwhale_api.music import fake_data; fake_data.create_data(super_user_name=getenv('FUNKWHALE_HOSTNAME').split('.')[0])"
|
||||||
|
```
|
||||||
|
|
||||||
|
```{note}
|
||||||
|
The username `funkwhale` is not permitted, since it violates the password constraint of not being equal to the password. Therefore you need to export the `COMPOSE_PROJECT_NAME` to make sure the method is only run in cases where it will be different from `funkwhale`.
|
||||||
|
|
||||||
|
This step does not apply to the default instance when running `docker compose` without specifying a `COMPOSE_PROJECT_NAME`.
|
||||||
|
|
||||||
|
In this case follow the manual steps from above. First create a super user as described in [set up application services](#set-up-application-services) and then continue with the [set up of example data for development](#set-up-example-data-for-development).
|
||||||
|
```
|
||||||
|
|
|
@ -11,4 +11,7 @@ RUN yarn install
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
CMD ["yarn", "serve"]
|
CMD [ "yarn", "serve" ]
|
||||||
|
|
||||||
|
HEALTHCHECK --start-period=30s --interval=10s --timeout=5s \
|
||||||
|
CMD wget --no-verbose --tries=1 --spider http://localhost:${VUE_PORT}/ || exit 1
|
||||||
|
|
|
@ -19,7 +19,7 @@ upstream funkwhale-api {
|
||||||
{% if config.proxy_frontend %}
|
{% if config.proxy_frontend %}
|
||||||
|
|
||||||
upstream funkwhale-front {
|
upstream funkwhale-front {
|
||||||
server ${FUNKWHALE_FRONT_IP}:${FUNKWHALE_FRONT_PORT};
|
server ${FUNKWHALE_FRONT_HOST}:${FUNKWHALE_FRONT_PORT};
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue