A federated and self-hosted music sharing service
  • Python 58.3%
  • TypeScript 24.6%
  • Vue 16.4%
  • Shell 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Fabio Manganiello b580f2856d
Some checks failed
continuous-integration/drone/push Build is failing
feat: add bulk add-to-library/playlist for selected tracks
- AddToCollectionDialog supports multiple track ids and count labels
- Replace bulk edit buttons with EntityActions-based action menu
- Add i18n strings and tests for bulk add flows
2026-09-06 00:45:30 +02:00
.drone chore(drone): drop multi-arch platform flag from buildx 2026-08-30 23:47:12 +02:00
config/systemd feat: add systemd units and installer; extend config lookup 2026-09-05 16:44:25 +02:00
docker fix(docker): preserve client port in proxy Host header 2026-08-31 02:10:01 +02:00
docs feat: add systemd units and installer; extend config lookup 2026-09-05 16:44:25 +02:00
frontend feat: add bulk add-to-library/playlist for selected tracks 2026-09-06 00:45:30 +02:00
scripts feat(pwa): add PWA support 2026-09-03 00:40:16 +02:00
songhive refactor(cli): split _create_admin_parser into smaller methods 2026-09-05 17:52:58 +02:00
tests feat: add systemd units and installer; extend config lookup 2026-09-05 16:44:25 +02:00
.codacy.yaml ci(codacy): Be more specific about skipping tests folder 2026-08-21 01:16:48 +02:00
.dockerignore chore(docker): add compose stack and image build 2026-08-22 00:19:58 +02:00
.drone.yml chore(ci): increase pytest parallel workers to 6 2026-08-31 01:04:05 +02:00
.gitignore chore(gitignore): Ignore .vite directories 2026-08-26 03:12:50 +02:00
.pre-commit-config.yaml chore(pre-commit): add eslint autofix hook for frontend sources 2026-08-25 00:01:26 +02:00
AGENTS.md fix(db): reset async engine after Celery task event loops 2026-08-31 01:01:18 +02:00
alembic.ini feat(db): add Alembic migrations support 2026-08-23 17:14:17 +02:00
CHANGELOG.md Bump version: 0.0.14 → 0.0.15 2026-09-02 23:48:35 +02:00
config.toml.example feat(external-libraries): add local adapter and source deletion 2026-09-02 03:15:26 +02:00
docker-compose.yml feat(external-libraries): add local adapter and source deletion 2026-09-02 03:15:26 +02:00
Dockerfile perf(docker): replace apt ffmpeg with static mwader/static-ffmpeg binary 2026-08-30 23:43:44 +02:00
install.sh feat: add systemd units and installer; extend config lookup 2026-09-05 16:44:25 +02:00
LICENSE Initial commit 2026-08-16 18:45:56 +02:00
pyproject.toml Bump version: 0.0.14 → 0.0.15 2026-09-02 23:48:35 +02:00
pytest.ini test(coverage): Exclude songhive/migrations from coverage report 2026-08-23 23:50:05 +02:00
README.md feat: add systemd units and installer; extend config lookup 2026-09-05 16:44:25 +02:00
requirements-dev.txt perf(tests): speed up test suite execution 2026-08-22 16:18:02 +02:00
requirements.txt chore(deps): add aiosqlite dependency 2026-09-04 17:38:19 +02:00
setup.cfg feat(external-libraries): add local adapter and source deletion 2026-09-02 03:15:26 +02:00

Songhive

Build Status Coverage Badge Codacy Badge CodeFactor Github stars Github forks Last Commit License

A federated and self-hosted music sharing service, built with ActivityPub federation support.

Overview

Songhive is a music streaming platform similar to Funkwhale, with a focus on better federation. It allows users to upload, organize, and stream their music library while federating with other instances (including Mastodon) via ActivityPub.

Features

  • Music Library: Upload and organize artists, albums, and tracks
  • Streaming: Audio streaming with on-the-fly transcoding (MP3, OGG, FLAC, AAC, Opus)
  • Metadata Enrichment: Fetch metadata from external services
  • Federation: ActivityPub support via pubby — federate with Mastodon and other AP-compatible services
  • Playlists & Radios: Create playlists and dynamic radio stations
  • Multi-user: User registration, profiles, and admin management
  • OAuth2 Provider: Third-party app authorization
  • Subsonic API: Compatibility layer for Subsonic clients
  • Flexible Storage: Local filesystem or S3-compatible object storage
  • External Libraries: Attach external music storage (e.g. cloud adapters) to Songhive libraries; index, stream, and write metadata back to the provider. See docs/ARCHITECTURE.md#external-libraries.

Architecture

  • Backend: FastAPI (REST API) + Tornado (WebSocket, streaming, process server)
  • Models: Pydantic (validation) + SQLAlchemy (async ORM)
  • Tasks: Celery + Redis (background import, transcoding, federation delivery)
  • Frontend: Vue.js 3 + TypeScript + Pinia

See docs/ARCHITECTURE.md for detailed architecture documentation.

Installation

Songhive can be run either as a complete Docker stack or installed locally with pip.

Docker

The Docker Compose setup builds the frontend and backend images, starts PostgreSQL and Redis, and wires everything together behind an Nginx reverse proxy. The songhive, worker, postgres and redis services all run as the same non-root UID/GID as the host user, so the files in ./volumes are owned by you and are easy to access from the host.

Latest image

# Run the docker-compose bootstrap script
curl -fsSL https://git.fabiomanganiello.com/songhive/raw/branch/main/docker/bootstrap.sh | sh

From a local checkout

# Clone the repository
git clone https://git.fabiomanganiello.com/songhive
# Or from GitHub: git clone https://github.com/blacklight/songhive
cd songhive

# Set the UID/GID to match the host user (the same value is used by all
# rootless services and by the setup step that fixes volume permissions).
export PUID=$(id -u)
export PGID=$(id -g)

# Build the images
docker compose build

pip

This path is useful for local development or running on an existing Python host. A published package is also available on PyPI and ships the built web UI, so the frontend does not need to be built manually when installing from PyPI.

Prerequisites:

  • Python >= 3.10
  • PostgreSQL (a SQLite database will also work, but it's not recommended for large installations)
  • Redis/Valkey
  • ffmpeg
  • Node.js and npm (for the frontend)

Latest stable package

# Install from PyPI
pip install songhive

From a local checkout

Or, clone the repository and install in editable mode for development

git clone https://git.fabiomanganiello.com/songhive
# Or from GitHub: git clone https://github.com/blacklight/songhive
cd songhive

# Optional: create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

pip install -e .

# Build the web UI (outputs to songhive/static/)
cd frontend
npm install
npm run build
cd ..

nginx setup

If you are planning to serve Songhive behind a reverse proxy, you can reuse the nginx.conf used by the Docker setup.

Configuration

Getting the default configuration

  • If you installed Songhive through the docker-compose bootstrap script, then config.toml should be already downloaded under the same folder as docker-compose.yml.

  • If you built Songhive from a local checkout, then copy the example configuration file:

    cp config.toml.example config.toml
    
  • Otherwise, download the latest config.toml:

    wget https://git.fabiomanganiello.com/songhive/raw/branch/main/config.toml.example
    

The application looks for config.toml in this order: the path given with --config or the SONGHIVE_CONFIG environment variable, then ./config.toml, then $XDG_CONFIG_HOME/songhive/config.toml (or ~/.config/songhive/config.toml), and finally /etc/songhive/config.toml.

Base configuration

Set at least the following values in config.toml:

[auth]
secret_key = "..."  # Generate with: python -c "import secrets; print(secrets.token_urlsafe(64))"

[storage]
local_path = "/path/to/writable/media"  # e.g. ./data/media

[server]
cors_origins = ["*"]  # Replace with your frontend origin(s) in production

[federation]
enabled = false  # Set a real instance_domain to enable federation
# instance_domain = "music.example.com"

From environment variables

All the config.toml configuration entries can be overridden via environment variables.

For example:

[database]
url = "postgresql+asyncpg://songhive:songhive@localhost:5432/songhive"

becomes:

SONGHIVE_DATABASE__URL="postgresql+asyncpg://songhive:songhive@localhost:5432/songhive"

Running the service

Docker installation

cd /path/to/your/songhive/installation
docker compose up -d

Then take down the stack with:

docker compose down

pip installation

SONGHIVE_CONFIG="/path/to/your/songhive/installation/config.toml"
songhive -c "$SONGHIVE_CONFIG"

Celery

This is only required in a non-Docker setup. The Docker stack already runs a separate container for the Celery workers.

Start the Celery worker in a second terminal:

celery -A songhive.tasks worker -B -l info

Local library watchdog

If you are using the built-in local external-library provider, start the filesystem watcher in another terminal or under a supervisor such as systemd:

songhive watch-external-libraries

The Docker stack runs this as a separate watcher container. The watcher is kept as a standalone process rather than a child of the web server so that a single host has exactly one watchdog, even when the web server is scaled to multiple workers.

systemd service

Songhive ships with systemd unit files under config/systemd/ and an install.sh script that sets up a virtual environment, copies the example config, installs the units, and creates the required directories.

The master songhive.service unit pulls in three units:

  • songhive-server.service — the main web server
  • songhive-celery.service — the Celery worker and scheduler
  • songhive-watch-extlib.service — the external-library watchdog

Run the installer as root for a system-wide service:

sudo ./install.sh

This creates /opt/songhive (the virtual environment), /etc/songhive, /var/lib/songhive, /var/cache/songhive, and /var/log/songhive, installs the units to /etc/systemd/system/, and reminds you to copy /etc/songhive/config.toml.example to /etc/songhive/config.toml and edit it. Then start and enable the service:

sudo systemctl start songhive.service
sudo systemctl enable songhive.service

Run the installer as a normal user for a user service:

./install.sh

This creates a virtual environment under ~/.local/share/virtualenvs/songhive, copies the example config to ~/.config/songhive/, creates ~/.local/share/songhive, ~/.cache/songhive, and ~/.local/state/songhive, and installs the units to ~/.config/systemd/user/. Copy ~/.config/songhive/config.toml.example to ~/.config/songhive/config.toml, edit it, then start the user service:

systemctl --user start songhive.service
systemctl --user enable songhive.service

Creating the admin user

Docker installation

cd /path/to/your/songhive/installation
docker compose exec songhive songhive admin create-user \
    --username admin \
    --email admin@example.com \
    --password secret \
    --admin

pip installation

SONGHIVE_CONFIG="/path/to/your/songhive/installation/config.toml"
songhive -c "$SONGHIVE_CONFIG" admin create-user \
    --username admin \
    --email admin@example.com \
    --password secret \
    --admin

Testing the installation

Open:

Development

# Run tests
python -m pytest

# Run linting
python -m flake8 songhive tests

# Format code
python -m black .

# Start Celery worker
celery -A songhive.tasks worker -l info

Frontend

cd frontend
npm install
npm run dev     # Development server
npm run build   # Production build (outputs to songhive/static/)

API

REST API available at /api/v1/:

Endpoint Description
/api/v1/auth/ Authentication (login, register, refresh)
/api/v1/auth/api-tokens/ API token management (create, list, revoke)
/api/v1/users/ User profiles
/api/v1/artists/ Artists
/api/v1/albums/ Albums
/api/v1/tracks/ Tracks
/api/v1/playlists/ Playlists
/api/v1/libraries/ User libraries
/api/v1/favorites/ Favorites
/api/v1/history/ Listening history
/api/v1/radios/ Dynamic radios
/api/v1/stream/{id} Audio streaming
/api/v1/admin/ Admin endpoints

WebSocket: /ws/events (real-time notifications)

Federation: /.well-known/webfinger, /ap/actor, /ap/inbox, /ap/outbox

License

AGPL-3.0