How to Self-Host Black Candy with Docker Compose

What Is Black Candy?

Black Candy is a self-hosted music streaming server that turns your personal music collection into a private streaming service. It replaces cloud services like Spotify or Apple Music for users who want to stream their own library from anywhere. Built with Ruby on Rails, it features a clean web UI plus companion iOS and Android apps for mobile listening. Official site.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 1 GB of free disk space for the application, plus storage for your music library
  • 512 MB of RAM minimum (1 GB recommended)
  • A domain name (optional, for remote access)

Docker Compose Configuration

Create a directory for Black Candy and a docker-compose.yml file:

mkdir -p ~/black-candy && cd ~/black-candy
services:
  blackcandy:
    image: ghcr.io/blackcandy-org/blackcandy:v3.1.0
    container_name: blackcandy
    ports:
      - "3000:80"
    volumes:
      - blackcandy_data:/app/storage
      - /path/to/your/music:/media_data:ro
    environment:
      - MEDIA_PATH=/media_data
      - SECRET_KEY_BASE=change-this-to-a-random-64-char-string
      - DB_ADAPTER=postgresql
      - DB_URL=postgres://blackcandy:changeme@blackcandy-db:5432/blackcandy
      - CABLE_DB_URL=postgres://blackcandy:changeme@blackcandy-db:5432/blackcandy_cable
      - QUEUE_DB_URL=postgres://blackcandy:changeme@blackcandy-db:5432/blackcandy_queue
      - CACHE_DB_URL=postgres://blackcandy:changeme@blackcandy-db:5432/blackcandy_cache
    depends_on:
      blackcandy-db:
        condition: service_healthy
    restart: unless-stopped

  blackcandy-db:
    image: postgres:16-alpine
    container_name: blackcandy-db
    volumes:
      - blackcandy_pgdata:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=blackcandy
      - POSTGRES_PASSWORD=changeme
      - POSTGRES_DB=blackcandy
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U blackcandy"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  blackcandy_data:
  blackcandy_pgdata:

Important: Change SECRET_KEY_BASE to a random string (use openssl rand -hex 32) and update POSTGRES_PASSWORD plus all DB_URL passwords to match.

Replace /path/to/your/music with the actual path to your music library on the host.

Start the stack:

docker compose up -d

Initial Setup

  1. Open http://your-server-ip:3000 in your browser
  2. Log in with the default admin credentials: [email protected] / foobar
  3. Change the admin password immediately under account settings
  4. Black Candy automatically scans the media directory and imports your library
  5. Wait for the initial media sync to complete — progress appears in the web UI

Configuration

SettingDescription
MEDIA_PATHDirectory inside the container where music files are mounted
SECRET_KEY_BASESession encryption key — must be set for persistent sessions
DB_ADAPTERsqlite for simple setups, postgresql for multi-user or large libraries
FORCE_SSLSet to true when behind an HTTPS reverse proxy
WEB_CONCURRENCYNumber of Puma workers — defaults to auto-detect based on CPU cores

Black Candy supports SQLite for simpler deployments. Remove the blackcandy-db service and set DB_ADAPTER=sqlite to use the built-in database. PostgreSQL is recommended for libraries with 10,000+ tracks or multiple concurrent users.

Mobile Apps

Black Candy has dedicated mobile apps:

  • iOS: Available on the App Store — search “Black Candy Music”
  • Android: Available on Google Play — search “Black Candy”

Point the app to your server URL (e.g., https://music.yourdomain.com) and log in with your credentials.

Reverse Proxy

Place Black Candy behind a reverse proxy for HTTPS access. Set FORCE_SSL=true in the environment when using SSL termination.

Example Nginx Proxy Manager configuration:

  • Scheme: http
  • Forward Hostname: blackcandy (or your container name)
  • Forward Port: 80

See Reverse Proxy Setup for full configuration guides.

Backup

Back up these volumes:

  • blackcandy_data — application data, album art cache, SQLite database (if used)
  • blackcandy_pgdata — PostgreSQL database (if using PostgreSQL)

Your music files are mounted read-only and should be backed up separately.

See Backup Strategy for automated backup approaches.

Troubleshooting

Media Not Appearing After Upload

Symptom: New music files added to the media directory don’t show up. Fix: Trigger a manual media sync from the admin panel. Black Candy syncs on startup but doesn’t watch for filesystem changes in real time. Restart the container after adding files: docker compose restart blackcandy.

Permission Denied Errors on Volumes

Symptom: Container fails to start with permission errors on /app/storage. Fix: Black Candy runs as UID 1000 inside the container. Ensure the storage volume is writable: sudo chown -R 1000:1000 /path/to/storage.

High Memory Usage During Large Library Scan

Symptom: Container uses excessive RAM during initial import of large libraries (50,000+ tracks). Fix: v3.1.0 introduced parallel media sync which uses more memory. For very large libraries, increase container memory limits or import in batches by starting with a subset of your music directory.

Mobile App Cannot Connect

Symptom: iOS or Android app shows connection error. Fix: Ensure the server URL includes the protocol (https:// or http://). If behind a reverse proxy, verify WebSocket support is enabled — Black Candy uses Action Cable for real-time updates.

Resource Requirements

  • RAM: ~200 MB idle, ~500 MB during media sync
  • CPU: Low — music streaming is I/O bound, not CPU intensive
  • Disk: ~100 MB for application data, plus your music library size

Verdict

Black Candy is the simplest self-hosted music streaming server you can run. It lacks the advanced features of Navidrome (subsonic API, smart playlists, Last.fm scrobbling) but makes up for it with a polished web UI and native mobile apps. Choose Black Candy if you want a no-fuss personal streaming server. Choose Navidrome if you need subsonic client compatibility or advanced music management features.

Frequently Asked Questions

Does Black Candy support the Subsonic API?

No. Unlike Navidrome and gonic, Black Candy doesn’t implement the Subsonic API. This means third-party Subsonic clients (DSub, Symfonium, play:Sub) won’t work with it. You’re limited to Black Candy’s own web UI and its official mobile apps. If Subsonic client compatibility matters, use Navidrome instead.

Can Black Candy transcode music on the fly?

Yes. Black Candy transcodes audio to the appropriate format for the client’s browser or mobile app. This is handled automatically — you don’t need to pre-convert your library. The server does the transcoding work, so CPU usage increases during playback on lower-powered hardware.

Does Black Candy have mobile apps?

Yes. Black Candy has official iOS and Android apps that connect to your self-hosted server. They support offline caching for listening without an internet connection. The apps are basic compared to commercial streaming apps but cover playback, queue management, and library browsing.

How does Black Candy organize my music library?

Black Candy scans your music directory and reads metadata tags (artist, album, title, genre) from the files. It organizes the library by artist and album in its UI. It doesn’t modify or rename your files — the file system structure doesn’t matter as long as the metadata tags are correct. Use beets to fix tags before importing if your library has inconsistent metadata.

Can multiple users share a Black Candy instance?

Yes. Black Candy supports multiple user accounts, each with their own playlists and favorites. Create accounts through the admin panel. All users share the same music library — there’s no per-user library separation. This makes it ideal for families or roommates sharing a music collection.

How much storage does Black Candy need?

Black Candy itself uses ~100 MB for the application and PostgreSQL database. Your music library is the main storage consumer — roughly 1 GB per 200 songs (at 320 kbps MP3) or 1 GB per 30 songs (FLAC). A typical 10,000-song library in mixed formats needs 30-50 GB.

Comments