From a69c5362c3080f5d377213f28dba4857e5872357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=B0=BD=ED=98=84?= Date: Sat, 3 Oct 2026 07:50:28 +0900 Subject: [PATCH] =?UTF-8?q?Bach=20=EC=84=A4=EC=B9=98=20=EB=AC=B8=EC=84=9C?= =?UTF-8?q?=EC=99=80=20=EB=82=A8=EC=9D=80=20=EB=B2=88=EC=97=AD=EC=9D=84=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 설치와 보안 및 업데이트와 복구 절차를 기록하고 실제 모바일 검수에서 남은 설정 문구를 한국어로 보완한다. --- INSTALL-KO.md | 81 +++++++++++++++++++++++++++++++++++++++++ frontend/src/i18n/ko.ts | 3 ++ 2 files changed, 84 insertions(+) create mode 100644 INSTALL-KO.md diff --git a/INSTALL-KO.md b/INSTALL-KO.md new file mode 100644 index 0000000..95f6f27 --- /dev/null +++ b/INSTALL-KO.md @@ -0,0 +1,81 @@ +# Bach to Basics 한국어판 설치 및 운영 + +## 운영 정보 + +| 항목 | 값 | +|---|---| +| 설치 위치 | `/home/syskiller/piano/bach-to-basics` | +| 프론트엔드 컨테이너 | `piano-bach-frontend` | +| 백엔드 컨테이너 | `piano-bach-backend` | +| 호스트 포트 | `127.0.0.1:18102` | +| 백엔드 내부 포트 | `8000` | +| 기본 주소 | `https://learn.itosm.co.kr` | +| 별칭 주소 | `https://learn.itosm.com` | +| MusicXML 보관 폴더 | `/home/syskiller/piano/music/musicxml` | + +백엔드는 호스트 포트를 열지 않는다. 프론트엔드 nginx만 Docker 내부 네트워크에서 백엔드에 접근한다. 외부 요청은 aaPanel nginx와 프론트엔드 nginx를 차례로 거친다. + +## 실행과 관리 + +```bash +cd /home/syskiller/piano/bach-to-basics +docker compose up -d --build +docker compose ps +docker compose logs -f --tail=200 +docker compose restart +docker compose down +``` + +프론트엔드 내부 확인은 `curl http://127.0.0.1:18102/`로 한다. 백엔드 확인은 프론트엔드 프록시를 통해 `curl http://127.0.0.1:18102/api/openapi.json`을 사용한다. + +## 비밀 파일과 환경 변수 + +백엔드 API 키는 `secrets/backend_api_key`에 저장한다. 파일 권한은 600을 유지하고 Git에 넣지 않는다. Compose는 다음 값을 사용한다. + +- `BACKEND_API_KEY_FILE=/run/secrets/backend_api_key` +- `REQUIRE_AUTH=1` +- `ALLOWED_ORIGINS=https://learn.itosm.co.kr,https://learn.itosm.com` +- `RATE_LIMIT_PER_MIN=60` + +프론트엔드 컨테이너가 비밀 파일을 읽어 백엔드로 보내는 내부 요청에만 인증 헤더를 추가한다. + +## 업데이트 + +1. `git status --short --branch`로 로컬 변경을 확인한다. +2. 공식 `origin`의 변경을 가져온다. +3. 한국어판과 운영 보안 커밋의 충돌 여부를 확인한다. +4. `docker compose build`를 실행한다. +5. `docker compose up -d`로 두 전용 컨테이너만 교체한다. +6. MIDI와 MusicXML 가져오기 및 악보와 내려오는 음표 화면을 다시 검사한다. + +## 한국어판 변경 파일 + +- `frontend/src/i18n/ko.ts` +- `frontend/src/main.tsx` +- `frontend/index.html` +- `frontend/vite.config.ts` +- `frontend/src/index.css` +- `frontend/src/views/PracticeView.tsx` +- `frontend/src/components/Transport/TransportControls.tsx` +- `backend/main.py` +- `frontend/nginx.conf` +- `frontend/docker-entrypoint.d/20-backend-api-key.sh` +- `frontend/Dockerfile` +- `docker-compose.yml` + +한국어 번역 리소스와 모바일 화면 보완 및 서버 내부 API 키 처리를 추가했다. 공식 CI와 같은 pnpm 9를 사용하도록 고정해 잠금 파일 기반 빌드를 유지한다. MIDI와 MusicXML 및 악보와 내려오는 음표와 따라치기 기능은 원본 구조를 유지한다. + +## 데이터와 한글 파일명 + +MIDI와 MusicXML은 브라우저 파일 선택이나 끌어 놓기로 불러온다. 공용 보관 폴더는 `/home/syskiller/piano/music/midi`와 `/home/syskiller/piano/music/musicxml`이다. 프론트엔드는 파일명을 유니코드 문자열로 처리하며 백엔드 전송 제목에는 UTF-8 URL 인코딩을 사용한다. + +## 원본으로 되돌리기 + +공식 원본 커밋을 별도 작업 트리에 복원해 빌드한다. 현재 운영 폴더의 기록은 강제로 다시 쓰지 않는다. `/home/syskiller/piano/backup`에 보관한 Git 번들과 설치 백업을 사용해 별도 복제본에서 먼저 검증한다. 백엔드 키를 복원할 때는 비밀 백업을 일반 소스와 분리하고 권한 600을 유지한다. + +## 선택 기능과 제한 사항 + +- 초기 운영에서는 Audiveris PDF OMR과 Basic Pitch 오디오 변환을 별도로 구성하지 않는다. +- MusicXML과 MIDI 및 기본 악보 변환 기능은 설치되어 있다. +- 실제 USB MIDI 입력과 따라치기 동작은 안드로이드 Chrome과 실제 전자피아노에서 최종 확인해야 한다. +- iPhone과 iPad의 Safari는 Web MIDI를 지원하지 않는다. diff --git a/frontend/src/i18n/ko.ts b/frontend/src/i18n/ko.ts index 96fe594..68b1e9e 100644 --- a/frontend/src/i18n/ko.ts +++ b/frontend/src/i18n/ko.ts @@ -52,6 +52,7 @@ const translations: Record = { 'Reset all settings to their default values': '모든 설정을 기본값으로 되돌리기', 'Something went wrong. Please reload the page.': '오류가 발생했습니다. 페이지를 새로고침해 주세요.', 'Color theme': '화면 색상', 'Differentiate hands': '왼손과 오른손 구분', + 'Use flats ♭': '내림표로 표시 ♭', 'affects all note labels': '모든 음이름 표시에 적용', 'Works with two-track MIDI files': '두 트랙으로 나뉜 MIDI 파일에 적용', 'pick your own colors': '색상을 직접 선택', 'on the keyboard': '건반에 표시', 'on note bars': '음표 막대에 표시', 'which notes appear in canvas': '표시할 음표 선택', @@ -74,7 +75,9 @@ const translations: Record = { 'which hand triggers wait mode pauses': '따라치기 모드에서 기다릴 손 선택', 'balance each hand independently': '왼손과 오른손 음량을 따로 조절', 'Count-in bars': '예비 마디', 'silent bars before playback starts': '재생 전 준비할 무음 마디', + '0 bars': '사용 안 함', '1 bar': '1마디', '2 bars': '2마디', 'ramps tempo up after each loop pass': '반복할 때마다 속도를 높임', + 'Buy me a metronome': '개발자 후원', 'on GitHub': 'GitHub에서 보기', original: '원래 음높이', };