8.2 KiB
UGREEN NAS 운영 배포 안내
운영 원칙
- 기능 테스트는 개발 Mac에서 수행한다.
- NAS에는 운영 컨테이너만 실행한다.
- 로컬 빌드와 Docker 검증을 통과한 커밋만 NAS에 배포한다.
- NAS에서 소스 코드를 직접 수정하지 않는다.
- 운영 주소는 현재
http://playuniare.sori.studio다. - HTTPS는 인증서와 리버스 프록시 구성이 완료된 뒤 전환한다.
현재 프로젝트는 Vue 정적 프런트엔드만 포함한다. 실시간 서버가 추가되면 같은 Compose 프로젝트 안에 Node.js 서비스를 추가한다.
배포 구조
사용자 브라우저
↓
http://playuniare.sori.studio
↓
NAS 리버스 프록시
↓
127.0.0.1:41809
↓
Play Uniare Nginx 컨테이너
├── / → Vue 빌드 결과
└── /card-assets/ → 기존 Uniare 카드 이미지
카드 이미지는 복사하지 않고 다음 폴더를 읽기 전용으로 연결한다.
/volume1/docker/projects/apps/uniare/config/www/images
로컬 배포 전 검증
개발 Mac의 프로젝트 폴더에서 실행한다.
npm install
npm run build
docker compose build
필요하면 로컬 Docker 컨테이너도 실행한다.
docker compose up -d
브라우저에서 다음 주소를 확인한다.
http://localhost:41809
로컬 Mac에는 NAS 카드 폴더가 없으므로 /card-assets 확인은 NAS 배포 후
수행한다.
검증이 끝나면 로컬 컨테이너를 종료한다.
docker compose down
NAS 최초 설치
1. SSH로 NAS 접속
개발 Mac 터미널에서 실행한다.
ssh NAS사용자명@192.168.50.146
실제 SSH 사용자명은 NAS 설정에 맞게 사용한다.
2. 저장소 복제
NAS 터미널에서 실행한다.
cd /volume1/docker/projects/apps
git clone https://git.sori.studio/zenn/playuniare.sori.studio.git playuniare
cd playuniare
비공개 저장소가 인증을 요구하면 Git 서버의 접근 토큰을 사용한다. 토큰을
문서나 .env에 저장하지 않는다.
3. NAS 환경변수 파일 생성
cp .env.example .env
기본 내용:
PLAYUNIARE_PRODUCTION_HTTP_PORT=41809
VITE_CARD_ASSET_BASE_URL=/card-assets
VITE_SOCKET_SERVER_URL=http://playuniare.sori.studio
현재 Socket.IO 서버는 구현 전이므로 VITE_SOCKET_SERVER_URL은 아직 실제
기능에 사용되지 않는다.
4. 포트 사용 여부 확인
docker ps --format "table {{.Names}}\t{{.Ports}}"
41809가 이미 사용 중이면 .env의 값을 다른 포트로 바꾼다.
PLAYUNIARE_PRODUCTION_HTTP_PORT=41819
이 경우 리버스 프록시 대상 포트도 같은 값으로 변경해야 한다.
5. 운영 컨테이너 실행
docker compose \
-f compose.yaml \
-f compose.nas.yaml \
up -d --build
상태 확인:
docker compose \
-f compose.yaml \
-f compose.nas.yaml \
ps
playuniare-web이 healthy 또는 running이면 정상이다.
6. 리버스 프록시 연결
현재 연결 기준:
외부 주소: http://playuniare.sori.studio
내부 대상: http://127.0.0.1:41809
.env에서 포트를 변경했다면 내부 대상 포트도 변경한다.
7. 배포 확인
메인 화면:
http://playuniare.sori.studio
카드 이미지:
http://playuniare.sori.studio/card-assets/ua03/EX01BT_HTR-2-001.png
두 주소가 모두 열리면 현재 정적 배포와 카드 자산 연결은 정상이다.
새 버전 업데이트
개발 Mac
- 기능을 구현한다.
- 관련 문서를 수정한다.
npm run build를 실행한다.- 필요한 경우 로컬 Docker로 검증한다.
- Git에 커밋하고 푸시한다.
NAS
cd /volume1/docker/projects/apps/playuniare
git pull
docker compose \
-f compose.yaml \
-f compose.nas.yaml \
up -d --build
배포 후 반드시 확인한다.
docker compose \
-f compose.yaml \
-f compose.nas.yaml \
ps
docker compose \
-f compose.yaml \
-f compose.nas.yaml \
logs --tail=100
마지막으로 실제 도메인에서 메인 화면과 주요 기능을 확인한다.
기존 NAS 테스트 컨테이너 제거
이전에 playuniare-test-web을 실행했다면 한 번만 정리한다.
docker rm -f playuniare-test-web
컨테이너가 없다는 메시지가 나오면 이미 제거된 것이므로 무시해도 된다.
테스트용 Docker 네트워크가 남아 있다면 확인 후 제거한다.
docker network ls
docker network rm playuniare-test_default
네트워크가 사용 중이거나 존재하지 않으면 무리하게 삭제하지 않는다.
이전 버전으로 되돌리기
최근 커밋 확인:
git log --oneline -10
정상 동작했던 커밋으로 전환:
git checkout 정상커밋식별자
docker compose \
-f compose.yaml \
-f compose.nas.yaml \
up -d --build
복구 후 개발 Mac에서 문제를 수정해 새로운 커밋을 만든다. 다시 최신
main으로 돌아갈 때:
git checkout main
git pull
docker compose \
-f compose.yaml \
-f compose.nas.yaml \
up -d --build
운영 점검 명령
상태:
docker compose -f compose.yaml -f compose.nas.yaml ps
최근 로그:
docker compose -f compose.yaml -f compose.nas.yaml logs --tail=100
재시작:
docker compose -f compose.yaml -f compose.nas.yaml restart
중지 및 제거:
docker compose -f compose.yaml -f compose.nas.yaml down
포트 충돌
다음 오류는 NAS 호스트 포트가 다른 서비스에 사용 중이라는 뜻이다.
Bind for 0.0.0.0:<포트> failed: port is already allocated
사용 중인 포트 확인:
docker ps --format "table {{.Names}}\t{{.Ports}}"
.env의 PLAYUNIARE_PRODUCTION_HTTP_PORT를 사용하지 않는 숫자로 변경하고
다시 실행한다. 컨테이너 내부의 80 포트는 다른 컨테이너와 같아도 괜찮다.
카드 이미지가 403인 경우
로그에 다음 내용이 있으면 NAS ACL에 의한 읽기 권한 문제다.
open() "/srv/uniare-card-images/..." failed (13: Permission denied)
현재 이미지는 카드 파일 소유자 UID 1000과 맞춘 cardreader 사용자를
사용한다. 최신 소스를 받고 반드시 이미지를 다시 빌드한다.
git pull
docker compose -f compose.yaml -f compose.nas.yaml up -d --build
Nginx 워커 확인:
docker exec playuniare-web ps aux
nginx: worker process가 cardreader로 표시되어야 한다.
카드 읽기 확인:
docker exec playuniare-web \
su -s /bin/sh cardreader -c \
'head -c 10 /srv/uniare-card-images/ua03/EX01BT_HTR-2-001.png >/dev/null && echo READ_OK'
데이터 마이그레이션
현재는 데이터베이스가 없으므로 마이그레이션할 데이터도 없다. 방 상태 저장,
사용자 계정 또는 덱 저장 데이터베이스가 추가되면
docs/migrations.md의 원칙을 따른다.
NAS에서 SQL이나 임시 명령을 직접 입력하는 방식은 초기에는 빠르지만, 같은 변경을 다시 재현하거나 복구하기 어렵다. 운영 데이터가 생긴 뒤에는 반드시 Git에 포함된 버전 관리 마이그레이션 코드를 실행하는 방식으로 전환한다.
배포 체크리스트
- 로컬
npm run build성공 - 필요한 로컬 Docker 검증 성공
- 관련 문서 업데이트
- Git 커밋과 푸시 완료
- NAS
git pull완료 - 운영 컨테이너 재빌드
- 컨테이너 상태와 로그 확인
http://playuniare.sori.studio확인/card-assets/<series>/<fileName>확인.env, 토큰, 비밀번호가 Git에 없는지 확인
향후 실시간 서버
Socket.IO 서버가 추가되면 브라우저에 서버 포트를 직접 공개하지 않는다.
브라우저
→ http://playuniare.sori.studio/socket.io
→ Play Uniare Nginx
→ Docker 내부 Socket.IO 서버:31873
Docker 내부에서는 다른 컨테이너와 같은 포트를 사용해도 충돌하지 않는다.
Socket.IO 서비스는 ports 대신 내부 통신용 expose를 사용하는 방향을
우선한다.