265 lines
9.3 KiB
Markdown
265 lines
9.3 KiB
Markdown
# NAS 배포 상세 가이드 (UGREEN 등 Docker 호스트)
|
||
|
||
이 문서는 **다른 PC에서 작업한 뒤 NAS에 올리는 경우**까지 포함해, 처음부터 끝까지 순서대로 따라 할 수 있도록 적었다.
|
||
요약·변수 설명은 `docs/deploy.md`를 참고하고, 여기서는 **SSH 기준으로 한 단계씩** 기술한다.
|
||
|
||
앱·문서의 **공식 버전**은 `package.json`의 `version`과 `docs/spec.md`의 `현재 버전`을 기준으로 한다.
|
||
|
||
---
|
||
|
||
## 1. 전제 조건(미리 확인)
|
||
|
||
다음이 갖춰져 있어야 한다. 기종마다 메뉴 이름은 다를 수 있다.
|
||
|
||
1. **Docker**(및 **Docker Compose** 플러그인 또는 `docker compose` 명령)가 NAS에서 동작한다.
|
||
2. **SSH**로 NAS에 접속할 수 있다. (예: Mac 터미널에서 `ssh nas`처럼 호스트 별칭을 써도 된다.)
|
||
3. NAS에 **Git**이 설치되어 있거나, Git 없이 배포하려면 12절의 대안을 본다.
|
||
|
||
원격 저장소 URL(예시, 실제 주소는 저장소 관리 화면과 동일해야 한다):
|
||
|
||
- `https://git.sori.studio/zenn/todo.sori.studio.git`
|
||
|
||
---
|
||
|
||
## 2. NAS에 둘 폴더 경로 정하기
|
||
|
||
이 프로젝트는 예시로 다음 경로를 쓴다.
|
||
|
||
- `/volume1/docker/projects/apps/todo`
|
||
|
||
**의미:** Docker용 프로젝트를 모아 두는 `apps` 아래에 `todo` 전용 디렉터리를 둔다.
|
||
다른 경로를 써도 되지만, 이후 명령의 `cd` 경로만 본인 환경에 맞게 바꾸면 된다.
|
||
|
||
---
|
||
|
||
## 3. SSH로 NAS 접속 후 폴더로 이동
|
||
|
||
```bash
|
||
ssh <NAS에_설정한_호스트이름>
|
||
```
|
||
|
||
접속 후:
|
||
|
||
```bash
|
||
cd /volume1/docker/projects/apps
|
||
```
|
||
|
||
`apps` 목록에 `todo`가 보이는지 확인한다.
|
||
|
||
```bash
|
||
ls
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Git으로 가져오기(권장: 빈 폴더에 클론)
|
||
|
||
### 4-1. `todo` 폴더가 **아직 없거나**, 비어 있게 만들 수 있는 경우
|
||
|
||
`apps`에서:
|
||
|
||
```bash
|
||
git clone https://git.sori.studio/zenn/todo.sori.studio.git todo
|
||
cd todo
|
||
```
|
||
|
||
이렇게 하면 `todo` 안에 저장소 파일이 채워진다.
|
||
|
||
### 4-2. 이미 `todo` 폴더로 들어가 있는데 **안이 비어 있는** 경우
|
||
|
||
`todo` 안에서 현재 디렉터리에 클론한다.
|
||
|
||
```bash
|
||
cd /volume1/docker/projects/apps/todo
|
||
git clone https://git.sori.studio/zenn/todo.sori.studio.git .
|
||
```
|
||
|
||
마지막의 `.`은 “현재 폴더에 받아라”는 뜻이다.
|
||
|
||
### 4-3. 폴더 안에 **다른 파일이 이미 있는** 경우
|
||
|
||
`git clone ... .`은 비어 있지 않으면 실패한다. 다음 중 하나로 정리한다.
|
||
|
||
- 다른 곳으로 파일을 옮기거나 이름을 바꾼 뒤 빈 폴더에서 4-2를 실행한다.
|
||
- 또는 상위에서 새 이름으로 클론한다.
|
||
`git clone https://git.sori.studio/zenn/todo.sori.studio.git todo-app`
|
||
이후 `docker compose`는 **클론된 디렉터리 안**에서만 실행하면 된다.
|
||
|
||
### 4-4. 클론 후 한 번 확인
|
||
|
||
```bash
|
||
cd /volume1/docker/projects/apps/todo
|
||
ls
|
||
```
|
||
|
||
`docker-compose.yml`, `Dockerfile`, `package.json` 등이 보이면 된다.
|
||
|
||
---
|
||
|
||
## 5. NAS의 LAN IP 확인(중요)
|
||
|
||
웹앱은 **사용자의 브라우저**에서 PocketBase 주소로 직접 요청한다.
|
||
그래서 빌드에 넣는 주소는 **“브라우저가 NAS에 접속할 때 쓰는 주소”**여야 한다.
|
||
|
||
예시:
|
||
|
||
- `docker-compose.yml`에 적어 둔 **호스트 포트**(웹 `42881`, PocketBase `42917`)는 다른 스택과 겹치지 않게 잡은 값이다. 겹치면 해당 파일의 `ports`만 바꾼 뒤, 아래 `export`·`.env`의 포트도 같이 맞춘다.
|
||
- 같은 NAS 안의 브라우저만: `http://127.0.0.1:42917`처럼 **호스트에 열린 포트**로 접근한다. **폰이나 다른 PC**에서는 `127.0.0.1` 대신 **NAS LAN IP**를 써야 한다.
|
||
- 집 안에서 여러 기기: `http://192.168.x.x:42917`(API), `http://192.168.x.x:42881`(웹) 형태로 쓴다.
|
||
|
||
IP 확인은 NAS 관리 화면의 네트워크 정보를 보거나, SSH에서 NAS OS에 맞는 명령으로 확인한다. (기종별로 명령이 다를 수 있다.)
|
||
|
||
아래에서는 예시로 `192.168.0.50`을 쓴다. **본인 NAS IP로 바꿔야 한다.**
|
||
|
||
---
|
||
|
||
## 6. 환경 변수 설정 후 Compose 실행
|
||
|
||
`docker compose`는 프로젝트 루트에 **`.env` 파일이 있으면 자동으로 읽는다.** (Git에 올리지 말 것. `.gitignore`에 포함됨.)
|
||
|
||
### 6-0. 운영 도메인을 쓰는 경우(예: todo.sori.studio)
|
||
|
||
`/volume1/docker/projects/apps/todo/.env` 예시:
|
||
|
||
```bash
|
||
VITE_PUBLIC_APP_URL=https://todo.sori.studio
|
||
VITE_POCKETBASE_URL=https://api.todo.sori.studio
|
||
```
|
||
|
||
그다음:
|
||
|
||
```bash
|
||
cd /volume1/docker/projects/apps/todo
|
||
docker compose up -d --build
|
||
```
|
||
|
||
리버스 프록시에서 **`todo.sori.studio` → 웹**, **`api.todo.sori.studio` → PocketBase** 로 각각 연결해야 한다. (경로·TLS는 사용 중인 NAS/프록시 제품 문서를 따른다.)
|
||
|
||
### 6-1. LAN IP만 쓰는 경우
|
||
|
||
프로젝트 루트에서 `export`로 한 세션에만 줄 수도 있다.
|
||
|
||
```bash
|
||
cd /volume1/docker/projects/apps/todo
|
||
export VITE_PUBLIC_APP_URL="http://192.168.0.50:42881"
|
||
export VITE_POCKETBASE_URL="http://192.168.0.50:42917"
|
||
docker compose up -d --build
|
||
```
|
||
|
||
- 첫 실행은 이미지 다운로드·빌드로 **시간이 걸릴 수 있다.**
|
||
- 백그라운드 실행은 `-d` 때문이다.
|
||
|
||
### 6-2. 잘 떴는지 확인
|
||
|
||
```bash
|
||
docker compose ps
|
||
```
|
||
|
||
`pocketbase`, `todo-web`(또는 compose에 정의된 웹 서비스 이름)이 `running`에 가깝게 보이면 된다.
|
||
|
||
### 6-3. 로그가 궁금할 때
|
||
|
||
```bash
|
||
docker compose logs -f --tail=100
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 브라우저로 접속해 보기
|
||
|
||
예시 IP 기준:
|
||
|
||
- **할 일 웹앱:** `http://192.168.0.50:42881`
|
||
- **PocketBase 관리자 UI:** `http://192.168.0.50:42917/_/`
|
||
|
||
접속이 안 되면:
|
||
|
||
- NAS 방화벽 또는 보안 앱에서 **42881, 42917** 포트가 막혀 있지 않은지 확인한다.
|
||
- `docker compose ps`로 컨테이너가 떠 있는지 다시 본다.
|
||
|
||
---
|
||
|
||
## 8. PocketBase 최초 설정(한 번)
|
||
|
||
1. 브라우저에서 `http://<NAS_IP>:42917/_/` 를 연다. (호스트 포트를 바꿨다면 그 번호로 연다.)
|
||
2. 관리자 계정(이메일·비밀번호)을 만들고 마법사를 끝낸다.
|
||
3. **컬렉션 `todos` 생성**
|
||
- 필드 `title`: 타입 **Text**
|
||
- 필드 `done`: 타입 **Bool**
|
||
4. **API 규칙**
|
||
처음에는 테스트로 느슨하게 두었다가, 나중에 로그인 기반으로 조이는 것을 권장한다. (운영 정책에 맞게 조정.)
|
||
5. **설정 → CORS**
|
||
웹앱 출처를 허용 목록에 넣는다. 예: `http://192.168.0.50:42881` 또는 `https://todo.sori.studio`
|
||
포트·프로토콜·호스트가 **실제로 주소창에 쓰는 것과 한 글자라도 다르면** 브라우저가 차단한다.
|
||
|
||
이후 `http://<NAS_IP>:42881`에서 목록·추가·완료 토글이 동작하는지 본다.
|
||
|
||
---
|
||
|
||
## 9. 왜 `export`로 주소를 줄이는가
|
||
|
||
`VITE_POCKETBASE_URL`은 **Docker 이미지를 빌드할 때** 프런트 번들에 박힌다.
|
||
NAS IP나 도메인이 바뀌면, **다시 빌드**해야 한다.
|
||
|
||
```bash
|
||
cd /volume1/docker/projects/apps/todo
|
||
export VITE_PUBLIC_APP_URL="http://새로운_주소:42881"
|
||
export VITE_POCKETBASE_URL="http://새로운_주소:42917"
|
||
docker compose up -d --build
|
||
```
|
||
|
||
---
|
||
|
||
## 10. 코드를 최신으로 갱신할 때(이미 클론해 둔 경우)
|
||
|
||
```bash
|
||
cd /volume1/docker/projects/apps/todo
|
||
git pull
|
||
export VITE_PUBLIC_APP_URL="http://192.168.0.50:42881"
|
||
export VITE_POCKETBASE_URL="http://192.168.0.50:42917"
|
||
docker compose up -d --build
|
||
```
|
||
|
||
`VITE_POCKETBASE_URL`이 이전과 같아도, 프런트 변경이 있으면 `--build`로 다시 빌드하는 편이 안전하다.
|
||
|
||
---
|
||
|
||
## 11. HTTPS와 PWA(나중에 해도 됨)
|
||
|
||
집 안 HTTP만으로도 개발·가족용으로는 쓸 수 있다.
|
||
다만 **PWA 설치·서비스 워커**는 브라우저·환경에 따라 HTTPS를 요구하는 경우가 많다.
|
||
공유기 뒤에서 도메인을 달거나, NAS 리버스 프록시로 **TLS 종료**하는 구성을 최종 목표로 두면 좋다. (구체 도메인·인증서 발급은 NAS/OS마다 다르다.)
|
||
|
||
---
|
||
|
||
## 12. NAS에 Git이 없을 때
|
||
|
||
- Mac/PC에서 클론한 뒤 `rsync`나 압축(zip)으로 `todo` 폴더 전체를 NAS에 올리고, NAS에서는 `docker compose up -d --build`만 실행한다.
|
||
- 이 경우에도 **6절의 `export VITE_POCKETBASE_URL`**은 동일하게 필요하다.
|
||
|
||
---
|
||
|
||
## 13. 자주 막히는 지점
|
||
|
||
| 증상 | 점검 |
|
||
| --- | --- |
|
||
| 웹은 뜨는데 데이터가 안 됨 | PocketBase `todos` 컬렉션·필드명, API 규칙, CORS에 웹 출처(`http://…:42881` 또는 `https://todo.sori.studio`)가 들어갔는지 |
|
||
| 폰에서만 안 됨 | `VITE_POCKETBASE_URL`이 `127.0.0.1`이 아닌지, 폰이 같은 Wi‑Fi인지, NAS IP가 맞는지 |
|
||
| 빌드 후에도 주소가 이상함 | `docker compose build --no-cache` 후 다시 `up`, 또는 `export`를 잊지 않았는지 |
|
||
| ARM NAS에서 이미지 오류 | 사용 중인 이미지가 해당 CPU 아키텍처를 지원하는지 로그로 확인한다. |
|
||
|
||
---
|
||
|
||
## 14. 한 페이지로 순서만 보기
|
||
|
||
1. SSH 접속
|
||
2. `cd /volume1/docker/projects/apps`
|
||
3. `git clone … todo` **또는** `cd todo` 후 `git clone … .`
|
||
4. NAS LAN IP 확인
|
||
5. LAN만 쓸 때: `export VITE_PUBLIC_APP_URL="http://<NAS_IP>:42881"` 및 `export VITE_POCKETBASE_URL="http://<NAS_IP>:42917"` (또는 6-0과 같이 `.env`에 기록)
|
||
6. `docker compose up -d --build`
|
||
7. 브라우저: `:42881` 앱, `:42917/_/` 관리자
|
||
8. `todos` 컬렉션·CORS·API 규칙 설정
|
||
|
||
이후 작업은 `git pull` → `export` → `docker compose up -d --build`를 반복하면 된다.
|