# DISTRIBUTION PLAN — SonicForge Studio (Alpha → Beta → Production) Mục tiêu: phân phối ứng dụng cho người dùng **không chia sẻ mã nguồn**, có pipeline cập nhật liên tục. Áp dụng cho backend Python/FastAPI + frontend JS (Babel precompiled). --- ## 1. TÁCH BÍ MẬT — FILE .env | Biến | Dùng cho | Bắt buộc | |---|---|---| | `REDIS_URL` | Redis/Celery broker | ✓ | | `CELERY_BROKER_URL` / `CELERY_RESULT_BACKEND` | Celery | ✓ | | `OPENAI_API_BASE` / `OPENAI_API_KEY` | LLM server-side (client KHÔNG thấy key — `aiGateway.js` chỉ gọi proxy server) | ✓ | | `SECRET_KEY` | Auth token (app/core/auth.py) | ✓ (mặc định trống → phải set) | | `DEFAULT_ADMIN_PASSWORD` | Admin mặc định | thay đổi ở production | - File `.env.example` đã tạo (commit được). `.env` thật KHÔNG commit (đã vào `.dockerignore`). - **Nguyên tắc:** client JS không bao giờ chứa secret — mọi API key nằm server (env) hoặc proxy. ## 2. BUILD IMAGE — KHÔNG CHIA SẺ MÃ NGUỒN ### 2.1 Chặn source khỏi image (`.dockerignore` — đã tạo) Loại khỏi build context: `.git`, `app/static/js/app.jsx` (source JSX), `wiki.md`, `plans/`, `*.patch`, `.env`, `tests/`, `node_modules`, backup... ### 2.2 Frontend — chỉ ship bản precompiled - Build JS: `node build.mjs` (Babel → `app.precompiled.js` minified) — **CHỈ bản minified vào image**, source `.jsx` bị `.dockerignore` chặn. - Bump `?v=` (cache-bust) mỗi bản phát hành — user cập nhật không dính cache cũ. ### 2.3 Backend Python — giới hạn đọc source - Python không biên dịch native mặc định → `.py` vẫn đọc được trong image. 3 lớp bảo vệ: 1. **Registry riêng tư** (GHCR / Docker Hub private / Harbor) — image KHÔNG public — người dùng chỉ nhận qua pull có auth. 2. **Secret chỉ qua env** — không hardcode gì trong image. 3. *(Tùy chọn, giai đoạn sau)* compile Python bằng **Nuitka** → `.so` cho `app/core`, `app/api` (giữ `main.py`/`config.py` đọc được — không chứa bí mật). ### 2.4 Cách build + push ```bash # 1. Precompile JS + bump ?v= node build.mjs # hoặc: NODE=... babel ... (xem wiki) # 2. Build image (tag theo version) docker build -t ghcr.io//sonicforge-studio:v1.0.0-alpha.1 . docker push ghcr.io//sonicforge-studio:v1.0.0-alpha.1 # 3. Production chạy image đã push (KHÔNG mount source): docker compose -f docker-compose.prod.yml up -d ``` - Compose production (`docker-compose.prod.yml` — đã tạo): image từ registry, `env_file: .env`, volumes bền (uploads/processed/db), asset dirs qua env (`VST3_DIR`, `SOUNDFONTS_DIR`, `PIANOBOOK_DIR`), KHÔNG có `.:/app` (bỏ mount dev của compose cũ). ## 3. KẾ HOẠCH PHÁT HÀNH ### Giai đoạn 1 — ALPHA (nội bộ dev/QA) - Tag: `v0.x.x-alpha.N` — chạy `docker compose up --build` (dev mount OK). - Log verbose; chưa quan tâm bảo mật; test tính năng + thu hồi nhanh. - Mỗi thay đổi: bump `?v=` → build → tag → ghi wiki.md. ### Giai đoạn 2 — BETA (nhóm người dùng mời) - Tag: `v0.x.x-beta.N` — image push **registry riêng tư**. - Người dùng: `docker compose -f docker-compose.prod.yml pull && up -d` (chỉ cần `.env` + image). - Thu log lỗi: thêm endpoint `/health` + (tùy chọn) Sentry/self-host error tracking. - **Feature flags** (biến env `FEATURE_*`) để tắt tính năng rủi ro từ xa. ### Giai đoạn 3 — PRODUCTION - Tag: `vX.Y.Z` (semver) + `latest`. - **Trước khi release:** backup volumes (`docker run --rm -v sf_db:/data -v $PWD:/backup alpine tar czf /backup/db-.tgz /data`), migrate dữ liệu nếu schema đổi. - Triển khai: pull image mới → recreate (rolling — web trước, worker sau) → healthcheck. - `SECRET_KEY`, `DEFAULT_ADMIN_PASSWORD`, API keys: quản lý qua secret manager (Docker secrets / vault) — không ở compose file. ## 4. PIPELINE CẬP NHẬT (lặp lại mỗi release) ``` code mới → build.mjs (precompiled + ?v=) → docker build (tag mới) → push registry → [beta/prod] pull + recreate → backup trước nếu prod → kiểm tra /health ``` - Phiên bản: `git tag vX.Y.Z` — build tag tự động từ git (`git describe --tags`). - Rollback: giữ tag cũ — `docker compose -f docker-compose.prod.yml up -d` với `IMAGE=...:`. ## 5. VIỆC CẦN LÀM (checklist) - [x] `.env.example` — liệt kê đủ 7 biến - [x] `.dockerignore` — chặn source/secret/docs - [x] `docker-compose.prod.yml` — production (registry + env_file + volumes, bỏ mount source) - [ ] Kiểm tra endpoint `/health` (tạo nếu chưa có — healthcheck compose đang trỏ tới) - [ ] Chọn registry (GHCR/Docker Hub private/Harbor) + tạo token CI - [ ] Nuitka compile `app/core`+`app/api` (tùy chọn — nếu cần bảo vệ backend chặt hơn) - [ ] CI (GitHub Actions): test → build → push tag → deploy beta tự động - [ ] Backup script volumes trước mỗi production release