Self-hosted Apple Music downloader with a polished web UI.
ALACarte is a browser-based tool that downloads lossless audio from Apple Music, converts it to FLAC, and organizes it into a clean library structure you can point any media server at.
- Search & Discover: Full access to the Apple Music catalog (albums, artists, songs, playlists).
- Lossless & Hi-Res: Download ALAC streams and auto-convert to FLAC with embedded artwork and metadata.
- Lyrics Support: Fetch embedded lyrics and sidecar
.lrcfiles (requiresmedia-user-token). - Smart Queuing: Queue individual tracks, whole albums, playlists, or bulk-select entire artist discographies (filtered by LPs/EPs/Singles).
- Library Awareness: Duplicate prevention visually flags what is already in your library so you don't re-download.
- Explicit / clean filtering: Apple lists explicit and clean masters as separate albums. Pick your preference in Settings (or show both) to keep search results tidy.
- Follow Artists: Follow an artist to auto-download new releases as they drop. Choose to grab their current discography on follow or only watch for future releases. ALACarte checks on a self-tuning schedule (configurable in Settings) that scales with your roster size to stay well under Apple's daily API limits.
Output lands in /music/<Artist>/<Album>/01. Track.flac (or /music/<Artist>/Singles/ for individual songs). Playlist downloads are merged into the same artist/album library structure and also emit /music/Playlists/<Playlist>.m3u8 with relative paths so Jellyfin/Navidrome can import playlist order.
This tool is for personal archival use only. Downloading music you do not have a valid subscription/license for violates Apple's Terms of Service. You are responsible for ensuring your use complies with applicable terms and laws in your jurisdiction.
linux/amd64(x86_64) — the FairPlay wrapper binary and the upstream downloader image are amd64-only. On Apple Silicon Macs, Docker Desktop transparently emulates amd64 via Rosetta. On native arm64 Linux (Raspberry Pi, ARM cloud VPS), enableqemu-user-static/binfmt_miscto run amd64 containers, or use an x86_64 host.- Docker + Docker Compose
- An Apple Music paid subscription
git clonethis repo andcdinto it- Copy
.env.exampleto.envand setMUSIC_PATHto your music library folder - Run
docker compose up -d --build - Open
http://<your-host>:7373 - Grab the one-time setup token from logs (
docker compose logs alacarte-web) and use it on the welcome screen with your new username/password - Go to Settings → enter your Apple ID email, password, and preferred storefront
Upgrading an existing deployment:
- Pull latest changes and rebuild:
docker compose up -d --build - If your current install has no auth configured yet, open the UI and complete first-time setup with the one-time setup token from logs.
- If you already have auth configured, sign in normally.
No manual data migration is required for data/web/settings.json or existing encrypted Apple credentials.
ALACarte ships with a built-in single-password gate. The first time you visit the UI, you'll be prompted to set a username/password and the one-time setup token from server logs — every API endpoint and page is then locked behind it.
A few things to keep in mind:
- Don't expose this directly to the public internet. Several cloud providers ship hosts with permissive default firewalls. Verify your firewall, and put a reverse proxy / VPN / mesh network in front of the UI before opening it up to anything beyond your LAN.
/var/run/docker.sockis mounted into the web container so it can spawn the wrapper container during first-time Apple login. That effectively grants the web container root on the host — another reason not to expose it directly.- Tighten the bind to localhost only: set
WEB_BIND=127.0.0.1in.envif you front the app with a reverse proxy on the same machine and don't want the UI reachable on your LAN. - Already running your own auth? Set
AUTH_DISABLED=truein.envto skip the built-in password gate (e.g. when fronting with Authelia, Cloudflare Access, Tailscale, etc). - Rate limiting and lockouts are built in for setup/login/password-change routes (429 + Retry-After + temporary lockouts).
- Sessions support revoke-all from Settings → Account ("Sign out on all devices").
- Password hashing uses memory-hard scrypt (
N=131072, r=8, p=1). - Trust proxy and secure cookies: set
TRUST_PROXYcorrectly when running behind a reverse proxy so HTTPS detection and cookie security are accurate. - Existing users are preserved: current encrypted Apple credentials in
data/web/settings.jsoncontinue to decrypt after upgrading. - Change or reset: the password lives at
data/web/auth.json. Change it from Settings → Account, or reset by deleting that file and restarting the container — the next visit will prompt for a new one.
ALACarte needs to authenticate with Apple to obtain decryption tokens. This happens once, then the session persists across container restarts.
- Enter your credentials in Settings and click Save.
- If Apple requires 2FA, you'll see a prompt asking for the 6-digit code. If a trusted device only shows Allow / Not Me, generate a code from Settings → Apple ID → Sign-In & Security → Get Verification Code.
- Enter the code within ~2 minutes.
- When you see "Ready", you're good to search and download.
If Apple sign-in fails, check these first:
- Confirm the Apple ID has an active Apple Music subscription on
music.apple.com. - Confirm the Apple ID has signed into Apple Music at least once on a real Apple device or on the web app.
- Confirm DNS, firewall, VPN, and proxy rules allow the host to reach Apple's services.
- Confirm the storefront in Settings matches the Apple ID's region.
- Confirm you're running the latest image/build (newer builds include login parser fixes and richer wrapper diagnostics).
Wrapper response type 4 is a generic StoreServices failure, not a credential diagnosis. Use the server message and StoreServices error in the failure log to narrow it down before retrying; repeated attempts can trigger an Apple account lockout. If the failure log shows a StoreServices error with a very large negative number, that came from an older wrapper build — rebuild with docker compose build --no-cache wrapper to get the real error code.
- Jobs run one at a time — queuing many items won't speed things up, it just lines them up.
- Download speed is throttled by Apple and varies by time of day.
- After a download completes, each track is converted from ALAC to FLAC and moved into your library (although you can disable this in the settings).
- The queue survives page refreshes but not container restarts.
- If a job fails (network hiccup, decryption glitch), you can re-queue it manually.
IP rate-limiting and proxies Apple appears to rate-limit by IP if you query huge amounts of data at once. In my experience, this isn't a permanent ban, I got soft-blocked for about a day after downloading ~1500 songs. If you plan to archive massive collections, consider:
- Spreading large jobs across multiple days
- Running behind a VPN or proxy
- Using a container with separate networking
Storage - Lossless albums are ~300–600 MB each.
- By default, temporary staging is written to
/tmp/alacarte-stagingwhile jobs run. - You can switch staging location in Settings → Library output.
- Stale job staging folders older than 24 hours are pruned on app boot and every 6 hours afterwards.
- If your host's
/tmpis tmpfs (RAM-backed), large downloads can exhaust memory. Either bind-mount a disk path to/tmp/alacarte-stagingin your compose override, or toggle "Store temp staging inside music library" on. - If you intentionally point staging inside your music library, configure your scanner to ignore hidden directories.
Sharing a network with Jellyfin/Plex/etc. By default ALACarte creates its own alacarte-net Docker network. If you'd rather attach to an existing network (e.g. the one your media server already uses), set DOCKER_NETWORK=<name> and DOCKER_NETWORK_EXTERNAL=true in .env.
Local compose tweaks If you need to change things the .env variables don't cover (extra volumes, additional environment, etc.), drop a docker-compose.override.yml next to the main compose file. Docker Compose auto-merges it and it's gitignored, so you can run docker compose up normally without polluting the committed config.
Navidrome Integration ALACarte includes built-in support for triggering Subsonic API scans in Navidrome. Once you configure your Navidrome credentials in the Settings panel, ALACarte will instantly instruct your server to quick-scan the library the exact moment a download completes. No more waiting for hourly cron jobs!
| Problem | Likely cause | Fix |
|---|---|---|
| "Sign in required" health warning | Wrapper isn't authenticated | Go to Settings and complete the login flow |
| "Docker socket not available" | First-time login needs host access | For initial setup, run the container with -v /var/run/docker.sock:/var/run/docker.sock or see the login instructions in Settings |
| Downloads stuck at 0% | Apple token expired or wrapper down | Wait a moment; it will auto-retry. If still stuck, restart the stack |
| Tracks show "failed" | Temporary Apple/server hiccup | Re-queue the album; transient failures usually clear |
| FLAC files are truncated | MP4Box runtime issue | Rebuild the container image and redeploy |
ALACarte runs on a shared Docker network with three primary components:
- web: This repository. It wraps the downloader CLI as a child process and serves the React SPA on port
7373. - amdp: The underlying downloader binary, included at build time.
- wrapper: A FairPlay decryption daemon that handles the DRM removal, included at build time.
Built upon:
The UI design was heavily inspired by the beautiful Abyss theme, which was then customized and expanded from the ground up for this project.
AGPL-3.0 — see LICENSE
This tool interacts with Apple Music services. You are responsible for ensuring your use complies with Apple's Terms of Service and applicable laws in your jurisdiction.


