Files
sori.studio/docs/deploy.md

260 lines
8.3 KiB
Markdown

# 배포 가이드
> 현재 프로젝트는 Nuxt 3 초기 스캐폴딩 상태다. Docker 설정은 파일 기준 초안이 있으며 운영 DB 확정 후 NAS에서 검증한다.
## 빌드 유형
| 유형 | 명령어 | 용도 |
|------|--------|------|
| 개발 | `npm run dev` | 로컬 테스트, 개발 서버 |
| 프로덕션 | `npm run build` | NAS 배포, 운영 서버 |
> `npm run dev`는 프로젝트 전용 실행 스크립트를 통해 개발 서버, Admin, Tailwind Viewer 링크만 요약 출력한다.
---
## 로컬 개발
### 필수 조건
- Node.js 22 LTS 권장
- npm 9+
- 개발 DB
### 실행 단계
```bash
# 프로젝트 클론
git clone https://git.sori.studio/zenn/sori.studio.git
# 디렉토리 이동
cd sori.studio
# 의존성 설치
npm install
# 개발 환경 변수 설정
# .env.development는 Git에 올리지 않는 로컬 전용 파일
# 새로 만들 때는 .env.example을 복사한 뒤 비밀번호를 랜덤 값으로 교체
cp .env.example .env.development
openssl rand -hex 32
# 로컬 DB 컨테이너를 호스트에서 접근할 때는 127.0.0.1:43119 사용
# 개발 서버 실행 (127.0.0.1:43117)
npm run dev
```
### 로컬 개발 DB
로컬 개발 DB는 Docker Compose의 `sori-studio-db` 서비스만 실행한다.
```bash
# Docker daemon 시작
# Docker Desktop을 사용하면 Docker.app을 먼저 실행
# Colima를 사용하면 아래 명령 실행
colima start
# 개발 DB 컨테이너 실행
ENV_FILE=.env.development docker compose --env-file .env.development up -d sori-studio-db
# 개발 DB 마이그레이션 실행
npm run db:migrate:dev
# DB 준비 상태 확인
docker exec sori-studio-db pg_isready -U sori_studio -d sori_studio
# 시드 데이터 확인
docker exec sori-studio-db psql -U sori_studio -d sori_studio -c 'SELECT count(*) AS posts_count FROM posts;'
```
### 확인 주소
- 개발 서버: http://127.0.0.1:43117
- 관리자: http://127.0.0.1:43117/admin
- Tailwind Viewer: http://127.0.0.1:43117/_tailwind/
### 로컬 DB 확인 방법
로컬 개발 DB는 PostgreSQL이며 호스트에서는 `127.0.0.1:43119`로 접근한다. 접속 정보는 Git에 포함하지 않는 `.env.development` 값을 사용한다.
| 항목 | 값 |
|------|----|
| Host | `127.0.0.1` |
| Port | `43119` |
| Database | `.env.development``POSTGRES_DB` |
| User | `.env.development``POSTGRES_USER` |
| Password | `.env.development``POSTGRES_PASSWORD` |
터미널에서 바로 확인할 때는 컨테이너 내부 `psql`을 사용한다.
```bash
# DB 준비 상태 확인
docker exec sori-studio-db pg_isready -U sori_studio -d sori_studio
# 게시물 개수 확인
docker exec sori-studio-db psql -U sori_studio -d sori_studio -c 'SELECT count(*) AS posts_count FROM posts;'
# psql 콘솔 접속
docker exec -it sori-studio-db psql -U sori_studio -d sori_studio
```
GUI로 확인할 때는 DBeaver, TablePlus, DataGrip, CloudBeaver 같은 PostgreSQL 클라이언트에서 위 접속 정보를 입력한다. phpMyAdmin은 MySQL/MariaDB용 도구라 이 프로젝트의 PostgreSQL DB 확인 용도로는 사용하지 않는다.
---
## UGREEN NAS Docker 배포
> Dockerfile과 docker-compose 설정은 초안이며 NAS 운영 환경에서는 아직 검증 전이다.
### SSH 접속
```bash
ssh [NAS_IP]
```
### 프로젝트 설치
```bash
# 프로젝트 디렉토리로 이동
cd /volume1/docker/sori.studio
# 프로젝트 클론
git clone https://git.sori.studio/zenn/sori.studio.git
# 디렉토리 이동
cd sori.studio
# 운영 환경 변수 설정
# .env.production은 Git에 올리지 않는 운영 전용 파일
cp .env.example .env.production
# .env.production 파일에 운영 DB 연결 정보, 운영 전용 랜덤 비밀번호, APP_PORT=43118 입력
# Docker 내부 앱에서 PostgreSQL에 접근할 때는 sori-studio-db:5432 사용
# Docker 빌드 및 실행
docker compose --env-file .env.production up -d
```
### 프로덕션 빌드 (NAS에서)
```bash
# 프로덕션 빌드
npm run build
# 또는 Docker로 빌드
docker build -t sori.studio:latest .
docker run -d -p 3000:3000 sori.studio:latest
```
### 포트
- 로컬 개발: 43117
- NAS Docker 외부: 43118
- 컨테이너 내부: 3000
- PostgreSQL 외부: 43119
- HTTPS: 3001 (SSL 설정 시)
---
## 데이터베이스
- 로컬 개발: `.env.development``DATABASE_URL`
- NAS 운영: `.env.production``DATABASE_URL`
- 로컬 개발 예시: `postgres://sori_studio:비밀번호@127.0.0.1:43119/sori_studio`
- NAS Docker 예시: `postgres://sori_studio:비밀번호@sori-studio-db:5432/sori_studio`
- `.env.example`에는 실제 비밀번호나 개인 이메일을 기록하지 않음
- 개발/운영 DB 비밀번호와 관리자 비밀번호는 서로 다른 랜덤 값을 사용
- 개발 DB와 운영 DB는 반드시 별도 인스턴스 또는 별도 데이터베이스로 분리
- 운영 DB는 로컬 개발 서버에서 직접 연결하지 않음
- 관리 도구: CloudBeaver 등으로 추후 연결 가능하게 설계
- NAS Docker 배포 시 PostgreSQL 초기 스키마는 `db/migrations/`의 SQL로 생성
- 로컬 개발 Docker Compose 실행 시 `ENV_FILE=.env.development``--env-file .env.development`를 함께 사용
- 로컬 개발 DB 마이그레이션은 `npm run db:migrate:dev`로 실행
- 네비게이션 계층(`parent_id`, `is_folder`)은 `017_navigation_hierarchy.sql` 적용 후 저장 API가 정상 동작한다(미적용 시 `INSERT` 컬럼 불일치).
### 개발/운영 DB 분리 검증 절차
검증 전제는 실제 비밀번호나 전체 `DATABASE_URL`을 화면 공유, 문서, 커밋 메시지에 노출하지 않는 것이다. 확인할 때는 호스트, 포트, DB 이름, 파일명만 대조한다.
1. `.env.development` 확인.
```bash
# 로컬 개발 DB는 호스트 기준 127.0.0.1:43119를 사용해야 한다.
# DATABASE_URL 전체 값은 공유하지 않는다.
rg -n "^(DATABASE_URL|POSTGRES_DB|POSTGRES_USER|DB_PORT)=" .env.development
```
기준:
- `DATABASE_URL` 호스트가 `127.0.0.1`
- `DATABASE_URL` 포트가 `43119`
- `DB_PORT=43119`
- 운영 NAS 호스트명, 운영 IP, 운영 DB 이름이 포함되지 않음
2. `.env.production` 확인.
```bash
# 운영 파일은 Git에 올리지 않는 운영 전용 파일이다.
# 값이 없으면 NAS 배포 전 작성해야 한다.
test -f .env.production && rg -n "^(DATABASE_URL|POSTGRES_DB|POSTGRES_USER|APP_PORT)=" .env.production
```
기준:
- NAS Docker 내부 실행 기준이면 `DATABASE_URL` 호스트가 `sori-studio-db`
- NAS 외부 DB를 별도 인스턴스로 쓰는 경우에도 로컬 개발 DB(`127.0.0.1:43119`)를 가리키지 않음
- `APP_PORT=43118`
- `.env.development`와 DB 비밀번호, 관리자 비밀번호가 서로 다름
3. 로컬 개발 DB 연결 확인.
```bash
docker exec sori-studio-db pg_isready -U sori_studio -d sori_studio
docker exec sori-studio-db psql -U sori_studio -d sori_studio -c 'SELECT current_database(), current_user;'
```
기준:
- `accepting connections` 표시
- `current_database`가 로컬 개발 DB 이름
- `current_user`가 로컬 개발 DB 계정
4. 로컬 개발 서버 연결 확인.
```bash
npm run dev
```
기준:
- 출력 주소가 `http://127.0.0.1:43117`
- 관리자 API 요청에서 `127.0.0.1:43119` 연결 오류가 발생하지 않음
5. 커밋 전 민감 정보 확인.
```bash
git status --short
git diff -- . ':!package-lock.json'
```
기준:
- `.env.development`, `.env.production`이 변경 목록에 포함되지 않음
- 문서와 코드 diff에 실제 DB 비밀번호, 관리자 비밀번호, 운영 접속 주소가 포함되지 않음
## 업로드 파일
- 관리자 글쓰기에서 업로드한 이미지는 `/uploads/posts/YYYY/MM/` URL로 제공한다.
- 로컬 개발에서는 실제 파일이 `public/uploads/posts/YYYY/MM/` 아래 저장된다.
- `public/uploads/`는 Git에 포함하지 않는다.
- NAS 운영에서는 업로드 파일이 컨테이너 재생성으로 사라지지 않도록 별도 볼륨 연결을 확정해야 한다.
- `MAX_FILE_SIZE` 환경 변수로 관리자 이미지 업로드 최대 크기를 제한한다.
- 관리자 미디어 화면은 현재 업로드 파일 시스템을 기준으로 목록, 파일명 변경, 삭제를 처리한다.
## 사용자 액션 필요 항목
- NAS SSH 접속 주소 확인.
- NAS 프로젝트 루트 경로 확정.
- 운영 DB 이름, 계정, 권한 확정.
- 운영 업로드 볼륨 경로 확정.
- 도메인 `sori.studio`의 NAS 연결 방식 확정.