Files
Цвылев Александр Вадимович 01b4267964 chore: sloppyslop working state — bump submodules + env/ignore/CLAUDE docs
Point mcma-backend + mcma-webui at their sloppyslop tips (lyrics, transcoding,
admin/storage/maintenance/instance UI, batch metadata, NowPlaying+lyrics).
Includes the CORS note in .env.example, TODO/ ignore, and the project CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 21:41:54 +03:00

5.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this repo is

mcma-compose is the dev-orchestration superproject for mycoolmusicapp — a self-hosted music app. It contains no application code of its own: docker-compose.yml, nginx.conf, Makefile, and .env.example. The actual code lives in two git submodules:

  • mcma-backend/ — Python / FastAPI (async), arq background workers, Alembic migrations.
  • mcma-webui/ — TypeScript / React, built with Rsbuild.

Both submodules are pulled from ssh://git@git.ollyhearn.ru:49239 (see .gitmodules). They may be empty — clone with git clone --recurse-submodules, or run git submodule update --init in an existing checkout, before you can touch or build app code.

The stack

make up builds and starts six services (see docker-compose.yml):

Service Image / context Role
db postgres:16-alpine PostgreSQL, data in ./data/pgdata
redis redis:7-alpine arq broker + cache, data in ./data/redisdata
api mcma-backend FastAPI via uvicorn --reload
worker mcma-backend arq app.workers.arq_worker.WorkerSettings background jobs
webui mcma-webui Rsbuild dev server with HMR
nginx nginx:1.27-alpine single entrypoint, reverse proxy

Key architectural points that span multiple files:

  • nginx is the only public port. It routes /api/ and /health → api:8000, everything else (including the /rsbuild-hmr websocket) → webui:3000. The browser never talks to webui directly; HMR is proxied through nginx, which is why compose sets RSBUILD_HMR_CLIENT_PORT to NGINX_PORT.
  • The entrypoint is http://localhost:8881, not :80. Compose maps ${NGINX_PORT:-8881}:80 (README says :80, but the .env.example default is 8881). api:8000 is also exposed directly for docs/debugging (/docs).
  • Source is bind-mounted into api, worker, and webui, so edits in the submodules hot-reload with no rebuild. Named-volume mounts (/app/.venv, /app/node_modules) shadow the host dir to preserve the image's installed deps — if you change dependencies you must rebuild (make build).
  • api and worker share the same image and both need db + redis healthy before starting.
  • DATABASE_URL / REDIS_URL are overridden inside compose to use service names (db, redis). The localhost values in .env are only the fallback for host-run processes.
  • Persistent state and media live under ./data/ (gitignored): pgdata, redisdata, media, transcode-cache, and youtube (drop a yt-dlp cookies.txt here — optional).

Commands

Everything runs inside the containers via the Makefile, which wraps docker compose exec. The stack must be up (make up) before test/lint/migrate/shell targets work. Run make help for the full list.

make up            # create .env from .env.example, build images, start the whole stack
make build         # rebuild images (with cache); needed after dependency changes
make rebuild       # rebuild with --no-cache
make down          # stop + remove containers
make clean         # down -v — DESTROYS db/redis volumes
make logs-api      # tail a single service's logs (also logs, logs-webui)
make sh-api        # bash into api (also sh-webui, db-shell, redis-cli)

Migrations (Alembic, run in the api container):

make migrate                        # alembic upgrade head
make makemigration m="add_tracks"   # autogenerate a revision
make downgrade                      # roll back one

Quality — these shell out to the tools inside each container:

make test          # test-api (pytest) + test-webui (npm test)
make test-api      # pytest        — for a single test: make sh-api, then `pytest path::test`
make test-webui    # npm test
make lint          # ruff check .   (api) + npm run lint (webui)
make fmt           # ruff format .  (api) + npm run format (webui)

There is no dev docker-compose for prod. Prod images are built straight from each submodule's dockerfiles/Dockerfile.prod:

make prod-build    # builds mcma-backend:prod and mcma-webui:prod

Environment

.env is a single combined file at the repo root, created from .env.example by make env / make up (never committed; it's gitignored). It is injected into api, worker, and webui. Backend features degrade gracefully when optional keys are unset:

  • ACOUSTID_API_KEY + MUSICBRAINZ_OWNER_EMAIL — enable AcoustID/MusicBrainz metadata enrichment.
  • YOUTUBE_ENABLED / YOUTUBE_COOKIES_PATH — YouTube Music source via yt-dlp.
  • ALLOW_REGISTRATION (backend) must be kept in sync with PUBLIC_ENABLE_REGISTRATION (frontend).

Working across submodules

When a change touches app behavior, the code is in mcma-backend/ or mcma-webui/ — commit there first, then the superproject records the new submodule commit. Recent superproject history is mostly chore: bump mcma-backend/mcma-webui commits that pin updated submodule SHAs.