4.4 KiB
mcma-bootstrap
Interactive installer for MCMA (My Cool Music App) — a self-hosted music
service. One command asks a few questions, writes a .env.deploy and a
docker-compose.yml, pulls the images, runs database migrations, creates the
first admin, and verifies the stack is healthy.
Zero dependencies beyond bash 4+, Docker, and Docker Compose v2. No jq, no Python, no yq. Secrets are generated for you and never printed.
Quick start
make deploy
That's it. The wizard walks you through:
- Language (English / Русский)
- Which services to run (backend is required; web UI optional)
- Image tag (
latestor a pinned version) - Database — built-in Postgres or an external one
- Redis — built-in or external
- Media storage — local directory, built-in MinIO (S3), or external S3
- Network — bundled Caddy proxy (plain HTTP, or automatic HTTPS for a domain), or no bundled proxy when you publish ports / run your own
- The first administrator account
- An optional ML service URL
Then it generates the config, pulls images, migrates, seeds the admin, starts everything, and waits for the API health check before declaring success.
Commands
make deploy # run the installer (fresh install, or update/reconfigure menu)
make update # pull fresh images of the current tag, migrate, restart
make up # start the stack from the existing config
make down # stop the stack (data volumes are kept)
make logs # tail logs from all services
make status # container status + API health
make clean # stop and remove generated config (prompts before deleting data)
What gets generated
| File | Purpose | Committed? |
|---|---|---|
.env.deploy |
All settings + generated secrets (0600) | No |
docker-compose.yml |
The stack, assembled from your choices | No |
Caddyfile |
Reverse-proxy routing (if proxy enabled) | No |
All three are in .gitignore. Re-running make deploy over an existing install
offers to update images or reconfigure (backing up the old config first); it
never silently overwrites.
Architecture notes
- One backend image, two roles.
git.ollyhearn.ru/olly/mcma-backendruns the API (uvicorn, port 8000) and the background worker (arq app.workers.arq_worker.WorkerSettings) — same image, different command. - The web UI and API must be same-origin.
git.ollyhearn.ru/olly/mcma-webuiis a prebuilt static SPA, and the backend sends no CORS headers — so the UI and API have to share an origin. By default the installer puts Caddy in front as the single entrypoint, routing/api/*,/health*and/rest/*to the backend and everything else to the UI (plain HTTP on a port, or automatic HTTPS for a domain). The UI's browser-facing API base URL is set at container start fromPUBLIC_API_BASE_URL(injected intowindow.__APP_CONFIG__, no rebuild needed), defaulting to the same-origin/api/v1. If you run your own reverse proxy, pick the "no bundled proxy" option: the installer publishes the UI and API ports and lets you set that base URL. A backend-only deploy publishes the API port directly. - Startup is ordered and fails loud. Backing services come up and become
healthy → migrations run → the first admin is created → app services start →
the API
/healthendpoint is polled. The backend is never started over a database that failed to migrate.
Private registry
The images live in a private registry. If make deploy reports unauthorized
while pulling, log in first:
docker login git.ollyhearn.ru
Creating an admin later
If you skipped admin creation during setup:
docker compose --project-name mcma --env-file .env.deploy -f docker-compose.yml \
run --rm --no-deps api mcma create-admin <username>
Layout
mcma-bootstrap/
├── Makefile # thin entrypoint → deploy.sh
├── deploy.sh # wizard + lifecycle orchestrator
├── lib/ # bash modules (ui, i18n, checks, secrets, generators, lifecycle)
├── templates/
│ ├── compose/ # per-service compose fragments, glued by choice
│ └── env/env.template # base .env with @TOKEN@ placeholders
└── i18n/ # ru / en string tables