diff --git a/arty.yml b/arty.yml index 04650c0..1e2f3b6 100644 --- a/arty.yml +++ b/arty.yml @@ -155,15 +155,8 @@ envs: MEDIA_FILESTASH_IMAGE: machines/filestash:latest MEDIA_FILESTASH_TRAEFIK_HOST: filestash.media.pivoine.art MEDIA_FILESTASH_CANARY: true - MEDIA_KOEL_IMAGE: phanan/koel:latest - MEDIA_KOEL_TRAEFIK_HOST: koel.media.pivoine.art - MEDIA_KOEL_DB_NAME: koel - MEDIA_KOEL_DEBUG: false - MEDIA_KOEL_MEMORY_LIMIT: 512 - MEDIA_KOEL_STREAMING_METHOD: x-sendfile - MEDIA_AMPACHE_IMAGE: ampache/ampache:latest - MEDIA_AMPACHE_TRAEFIK_HOST: ampache.media.pivoine.art - MEDIA_AMPACHE_DB_NAME: ampache + MEDIA_NAVIDROME_IMAGE: deluan/navidrome:latest + MEDIA_NAVIDROME_TRAEFIK_HOST: navidrome.media.pivoine.art # PairDrop DROP_TRAEFIK_ENABLED: true DROP_COMPOSE_PROJECT_NAME: drop diff --git a/core/postgres/init/01-init-databases.sh b/core/postgres/init/01-init-databases.sh index 3311e12..bd95a4e 100644 --- a/core/postgres/init/01-init-databases.sh +++ b/core/postgres/init/01-init-databases.sh @@ -41,14 +41,6 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-E SELECT 'CREATE DATABASE asciinema' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'asciinema')\\gexec - -- Koel music streaming database - SELECT 'CREATE DATABASE koel' - WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'koel')\\gexec - - -- Ampache music streaming database - SELECT 'CREATE DATABASE ampache' - WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'ampache')\\gexec - -- Grant privileges to all databases GRANT ALL PRIVILEGES ON DATABASE directus TO $POSTGRES_USER; GRANT ALL PRIVILEGES ON DATABASE umami TO $POSTGRES_USER; @@ -58,13 +50,11 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-E GRANT ALL PRIVILEGES ON DATABASE mattermost TO $POSTGRES_USER; GRANT ALL PRIVILEGES ON DATABASE tandoor TO $POSTGRES_USER; GRANT ALL PRIVILEGES ON DATABASE asciinema TO $POSTGRES_USER; - GRANT ALL PRIVILEGES ON DATABASE koel TO $POSTGRES_USER; - GRANT ALL PRIVILEGES ON DATABASE ampache TO $POSTGRES_USER; -- Log success SELECT 'Compose databases initialized:' AS status; SELECT datname FROM pg_database - WHERE datname IN ('directus', 'umami', 'n8n', 'linkwarden', 'joplin', 'mattermost', 'tandoor', 'asciinema', 'koel', 'ampache') + WHERE datname IN ('directus', 'umami', 'n8n', 'linkwarden', 'joplin', 'mattermost', 'tandoor', 'asciinema') ORDER BY datname; EOSQL @@ -81,6 +71,4 @@ echo " • joplin - Note-taking server database" echo " • mattermost - Chat platform database" echo " • tandoor - Recipe manager database" echo " • asciinema - Terminal recording server database" -echo " • koel - Music streaming server database" -echo " • ampache - Music streaming server database" echo "" diff --git a/media/compose.yaml b/media/compose.yaml index 0427ec3..f4813ec 100644 --- a/media/compose.yaml +++ b/media/compose.yaml @@ -62,127 +62,37 @@ services: - 'traefik.docker.network=${NETWORK_NAME}' - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' - # Koel - Music streaming server - koel: - image: ${MEDIA_KOEL_IMAGE:-phanan/koel:latest} - container_name: ${MEDIA_COMPOSE_PROJECT_NAME}_koel + # Navidrome - Music streaming server with public sharing + navidrome: + image: ${MEDIA_NAVIDROME_IMAGE:-deluan/navidrome:latest} + container_name: ${MEDIA_COMPOSE_PROJECT_NAME}_navidrome restart: unless-stopped - depends_on: - - koel_init volumes: - - koel_covers:/var/www/html/public/img/covers - - koel_search_index:/var/www/html/storage/search-indexes + - navidrome_data:/data - /mnt/hidrive/users/valknar/Music:/music:ro environment: TZ: ${TIMEZONE:-Europe/Berlin} - APP_NAME: Koel - APP_ENV: production - APP_DEBUG: ${MEDIA_KOEL_DEBUG:-false} - APP_URL: https://${MEDIA_KOEL_TRAEFIK_HOST} - APP_KEY: ${MEDIA_KOEL_APP_KEY} - LOG_CHANNEL: stderr - DB_CONNECTION: pgsql - DB_HOST: ${CORE_DB_HOST} - DB_PORT: ${CORE_DB_PORT} - DB_DATABASE: ${MEDIA_KOEL_DB_NAME} - DB_USERNAME: ${DB_USER} - DB_PASSWORD: ${DB_PASSWORD} - MEMORY_LIMIT: ${MEDIA_KOEL_MEMORY_LIMIT:-512M} - STREAMING_METHOD: ${MEDIA_KOEL_STREAMING_METHOD:-x-sendfile} - # Media and storage configuration - MEDIA_PATH: /music - STORAGE_DRIVER: local - # Proxy configuration - TRUSTED_PROXIES: '*' - FORCE_HTTPS: 'true' + ND_SCANSCHEDULE: 1h + ND_LOGLEVEL: info + ND_SESSIONTIMEOUT: 24h + ND_BASEURL: "" networks: - compose_network labels: - 'traefik.enable=${MEDIA_TRAEFIK_ENABLED}' # HTTP to HTTPS redirect - - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-koel-redirect-web-secure.redirectscheme.scheme=https' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-koel-web.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-koel-redirect-web-secure' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-koel-web.rule=Host(`${MEDIA_KOEL_TRAEFIK_HOST}`)' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-koel-web.entrypoints=web' + - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-redirect-web-secure.redirectscheme.scheme=https' + - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-redirect-web-secure' + - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web.rule=Host(`${MEDIA_NAVIDROME_TRAEFIK_HOST}`)' + - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web.entrypoints=web' # HTTPS router - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-koel-web-secure.rule=Host(`${MEDIA_KOEL_TRAEFIK_HOST}`)' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-koel-web-secure.tls.certresolver=resolver' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-koel-web-secure.entrypoints=web-secure' - - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-koel-web-secure-compress.compress=true' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-koel-web-secure.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-koel-web-secure-compress,security-headers@file' + - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web-secure.rule=Host(`${MEDIA_NAVIDROME_TRAEFIK_HOST}`)' + - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web-secure.tls.certresolver=resolver' + - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web-secure.entrypoints=web-secure' + - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web-secure-compress.compress=true' + - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web-secure.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web-secure-compress,security-headers@file' # Service - - 'traefik.http.services.${MEDIA_COMPOSE_PROJECT_NAME}-koel-web-secure.loadbalancer.server.port=80' - - 'traefik.docker.network=${NETWORK_NAME}' - # Watchtower - - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' - - # Koel initialization container - koel_init: - image: ${MEDIA_KOEL_IMAGE:-phanan/koel:latest} - container_name: ${MEDIA_COMPOSE_PROJECT_NAME}_koel_init - restart: "no" - user: "33:33" - command: bash -c "php artisan koel:init --no-interaction && php artisan koel:admin --email=${ADMIN_EMAIL} --password=${ADMIN_PASSWORD} --no-interaction" - volumes: - - koel_covers:/var/www/html/public/img/covers - - koel_search_index:/var/www/html/storage/search-indexes - environment: - TZ: ${TIMEZONE:-Europe/Berlin} - APP_NAME: Koel - APP_ENV: production - APP_DEBUG: ${MEDIA_KOEL_DEBUG:-false} - APP_URL: https://${MEDIA_KOEL_TRAEFIK_HOST} - APP_KEY: ${MEDIA_KOEL_APP_KEY} - LOG_CHANNEL: stderr - DB_CONNECTION: pgsql - DB_HOST: ${CORE_DB_HOST} - DB_PORT: ${CORE_DB_PORT} - DB_DATABASE: ${MEDIA_KOEL_DB_NAME} - DB_USERNAME: ${DB_USER} - DB_PASSWORD: ${DB_PASSWORD} - # Media and storage configuration - MEDIA_PATH: /music - STORAGE_DRIVER: local - # Proxy configuration - TRUSTED_PROXIES: '*' - FORCE_HTTPS: 'true' - networks: - - compose_network - - # Ampache - Music streaming server with public sharing - ampache: - image: ${MEDIA_AMPACHE_IMAGE:-ampache/ampache:latest} - container_name: ${MEDIA_COMPOSE_PROJECT_NAME}_ampache - restart: unless-stopped - volumes: - - ampache_config:/var/www/config - - ampache_log:/var/log/ampache - - /mnt/hidrive/users/valknar/Music:/media:ro - environment: - TZ: ${TIMEZONE:-Europe/Berlin} - DB_HOST: ${CORE_DB_HOST} - DB_PORT: ${CORE_DB_PORT} - DB_NAME: ${MEDIA_AMPACHE_DB_NAME} - DB_USERNAME: ${DB_USER} - DB_PASSWORD: ${DB_PASSWORD} - AMPACHE_WEB_PATH: https://${MEDIA_AMPACHE_TRAEFIK_HOST} - networks: - - compose_network - labels: - - 'traefik.enable=${MEDIA_TRAEFIK_ENABLED}' - # HTTP to HTTPS redirect - - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-redirect-web-secure.redirectscheme.scheme=https' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-ampache-redirect-web-secure' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web.rule=Host(`${MEDIA_AMPACHE_TRAEFIK_HOST}`)' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web.entrypoints=web' - # HTTPS router - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web-secure.rule=Host(`${MEDIA_AMPACHE_TRAEFIK_HOST}`)' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web-secure.tls.certresolver=resolver' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web-secure.entrypoints=web-secure' - - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web-secure-compress.compress=true' - - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web-secure.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web-secure-compress,security-headers@file' - # Service - - 'traefik.http.services.${MEDIA_COMPOSE_PROJECT_NAME}-ampache-web-secure.loadbalancer.server.port=80' + - 'traefik.http.services.${MEDIA_COMPOSE_PROJECT_NAME}-navidrome-web-secure.loadbalancer.server.port=4533' - 'traefik.docker.network=${NETWORK_NAME}' # Watchtower - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' @@ -194,14 +104,8 @@ volumes: name: ${MEDIA_COMPOSE_PROJECT_NAME}_jellyfin_cache filestash_data: name: ${MEDIA_COMPOSE_PROJECT_NAME}_filestash_data - koel_covers: - name: ${MEDIA_COMPOSE_PROJECT_NAME}_koel_covers - koel_search_index: - name: ${MEDIA_COMPOSE_PROJECT_NAME}_koel_search_index - ampache_config: - name: ${MEDIA_COMPOSE_PROJECT_NAME}_ampache_config - ampache_log: - name: ${MEDIA_COMPOSE_PROJECT_NAME}_ampache_log + navidrome_data: + name: ${MEDIA_COMPOSE_PROJECT_NAME}_navidrome_data networks: compose_network: