[개발일지 #01 | 기획] 유그린 NAS와 Flutter로 만드는 나만의 프라이빗 메신저 ‘딩동’ (기획 & 아키텍처 편)

카카오톡처럼 편리하지만, 모든 데이터는 내 집 NAS에 안전하게 보관되는 크로스플랫폼 메신저 만들기 프로젝트
모바일(Android, iOS)부터 데스크톱(Windows, macOS)까지 코드 하나로 개발하고, 집에 있는 Ugreen NAS(Docker)를 백엔드 서버로 구축하는 전체적인 아키텍처와 로드맵을 공유합니다.


1. 프로젝트를 시작하게 된 계기

가족들과 친구들이 매일 사용하는 메신저 앱. 카카오톡이나 라인처럼 친숙하고 편리하지만, 아래와 같은 아쉬움이나 고민이 있었습니다:

  1. 데이터 주권과 프라이버시: 가족들의 사진, 일상 대화, 소중한 파일들을 외부 클라우드가 아닌 우리 집 NAS에 안전하게 보관하고 싶다.
  2. 크로스플랫폼 지원: 부모님 스마트폰(Android/iOS)은 물론, 일할 때 쓰는 컴퓨터(Windows, Mac)에서도 매끄럽게 돌아가야 한다.
  3. 가족 친화적인 쉬운 사용성: QR 코드 같은 번거로운 인증 대신, 카톡 링크 전송이나 휴대전화 연락처로 쉽게 초대할 수 있어야 한다.

그래서 집에서 24시간 가동 중인 유그린(Ugreen) NAS를 개인 서버로 활용하고, Flutter로 4개 OS를 모두 지원하는 프라이빗 메신저 ‘딩동(DingDong)’ 프로젝트를 시작하게 되었습니다.


2. 우리가 만들 핵심 기능 (Feature Scope)

  • 💬 실시간 1:1 및 가족 그룹 채팅: 카카오톡처럼 안 읽은 인원 수(노란 숫자 1) 표시 및 실시간 읽음 처리
  • 📞 1:1 보이스톡(음성 통화): WebRTC 기반 고음질 음성 통화 (잠금화면에서도 일반 전화처럼 수신)
  • 📷 사진 및 대용량 파일 전송: 네트워크가 끊겨도 이어서 올릴 수 있는 안정적인 업로드, 내 NAS 하드디스크에 원본 영구 저장
  • 🔗 초간단 친구/가족 초대: 카카오톡이나 문자로 원클릭 링크 공유, 내 폰 주소록(연락처) 기반 친구 매칭
  • 🖥️ PC 멀티 디바이스 로그인: 모바일 앱에서 한 번의 승인으로 데스크톱 앱 간편 로그인

3. 전체 시스템 아키텍처

클라우드 비용을 매달 내지 않고, 안정적이면서도 유지보수가 쉬운 구성을 목표로 설계했습니다.

flowchart TB
    subgraph Clients["클라이언트 (Flutter 단일 코드베이스)"]
        A[Android 스마트폰]
        I[iPhone / iPad]
        M[Mac 데스크톱]
        W[Windows PC]
    end

    subgraph Internet["외부 서비스 (푸시 전용)"]
        FCM["Google FCM (안드로이드 푸시)"]
        APNS["Apple APNs (아이폰 VoIP/푸시)"]
    end

    subgraph HomeNAS["우리 집 유그린 NAS (Docker Compose)"]
        CADDY["Caddy 웹서버 (HTTPS / WSS 자동 SSL)"]
        API["NestJS API 서버 (REST + WebSocket)"]
        PG[(PostgreSQL DB - 대화/회원 정보)]
        RD[(Redis - 접속상태 / 작업 큐)]
        FILES[("NAS HDD 볼륨 - 사진/파일 원본")]
        LK["LiveKit 서버 (WebRTC 음성 통화 중계)"]
    end

    Clients -->|HTTPS / WSS 실시간 접속| CADDY
    CADDY --> API
    API --> PG & RD & FILES
    Clients <-->|WebRTC 음성 스트림| LK
    API -.->|백그라운드 알림 전송| FCM & APNS
    FCM & APNS -.->|앱 깨우기| Clients
    linkStyle default stroke-width:3px,stroke:#333333

왜 이 기술들을 선택했을까요?

계층선택한 기술선택 이유 (초보 개발자 팁)
앱 클라이언트Flutter (Dart)코드 1개로 Android, iOS, Windows, macOS 4개 플랫폼 앱이 모두 나옵니다. UI 컴포넌트가 OS에 구애받지 않고 카톡과 똑같이 그려집니다.
로컬 캐시 DBDrift (SQLite)“오프라인 우선” 구조를 위해 필수입니다. 집 인터넷이나 NAS가 잠시 끊겨도 앱에서 이전 대화를 즉시 볼 수 있고, 오프라인 작성 후 재연결 시 자동 전송됩니다.
백엔드 서버NestJS (TypeScript)Node.js 생태계에서 가장 구조화가 잘 되어 있고, 실시간 WebSocket 게이트웨이 및 LiveKit 연동이 매우 쉽습니다.
데이터베이스PostgreSQL 16안정성과 트랜잭션 보장이 뛰어납니다. 대화 순번(seq)을 매겨 메시지 유실 없는 동기화를 구현하기에 최적입니다.
캐시 / 큐Redis + BullMQ사용자의 현재 접속 여부(Presence) 체크와 백그라운드 푸시 알림 발송 큐를 가볍게 처리합니다.
음성 통화LiveKit (Self-hosted)WebRTC 기반 오픈소스 통화 서버입니다. 복잡한 P2P 통신이나 TURN 서버 설정 없이, Docker 컨테이너 하나로 깔끔하게 음성 통화 인프라가 해결됩니다.
리버스 프록시CaddyNginx보다 설정이 10배 간단하며, 도메인만 적어두면 무료 Let’s Encrypt SSL 인증서(HTTPS)를 알아서 발급/갱신해 줍니다.

4. 핵심 기술 포인트 & 구현 꿀팁

① 실시간 채팅과 “안 읽은 숫자 1” 처리

  • 방별 순번(Seq) 방식: 기기 시계 차이로 인한 메시지 순서 꼬임을 방지하기 위해, 서버에서 방마다 1, 2, 3… 형태로 seq 번호를 부여합니다.
  • 가벼운 읽음 계산: 메시지마다 “누가 읽었는지” 리스트를 저장하면 서버에 부하가 큽니다. 대신 **”각 멤버가 마지막으로 읽은 순번(Last Read Seq)”**만 기록하여, 현재 순번 - 내가 읽은 순번으로 안 읽은 개수를 가볍게 계산합니다.

② 가족과 친구를 편하게 초대하는 방법

  • 카톡/문자 원클릭 링크: 앱 내 [초대하기]를 누르면 카톡 공유창이 떠서 바로 초대 링크가 전송됩니다. 링크 클릭 시 설치 안내 및 딥링크를 통해 가입 즉시 친구로 연결됩니다.
  • 연락처(주소록) 매칭: 내 폰 주소록의 전화번호를 안전하게 단방향 암호화(SHA-256 해시)하여 서버와 대조합니다. 이미 가입된 가족은 바로 추가하고, 미가입된 가족은 문자 초대장을 보낼 수 있습니다.

③ 유그린 NAS(집 서버) 환경에 맞춘 최적화

  • HDD 수면 모드 방지: NAS의 하드디스크가 절전 모드에 들어가면 첫 메시지 반응이 몇 초 느려질 수 있습니다. 따라서 DB와 Docker 컨테이너는 NVMe SSD 볼륨에 두고, 용량이 큰 사진/파일 원본만 대용량 HDD 볼륨에 저장하도록 분리했습니다.
  • Docker Compose 배포: 모든 서버 환경이 docker-compose.yml 파일 하나로 관리되므로, NAS를 교체하거나 다른 PC로 이전할 때도 명령어 한 줄로 복구할 수 있습니다.

5. 앞으로의 개발 로드맵

앞으로 실제 코드를 작성하고 기능을 완성해 나갈 단계별 계획입니다:

  1. [1단계] NAS 환경 셋업 & 기술 검증: Caddy + NestJS + PostgreSQL + LiveKit을 NAS Docker에 올리고, 외부(LTE) 접속 및 통화 테스트
  2. [2단계] 기본 로그인 & 친구 추가: 초대 링크 공유 및 주소록 매칭 기능 구현
  3. [3단계] 실시간 문자 채팅 완성: 오프라인 로컬 저장, WebSocket 실시간 전송, 안 읽은 숫자 카운팅
  4. [4단계] 사진/대용량 파일 전송 & 푸시 알림: 이어올리기(Tus) 프로토콜 및 모바일 푸시 알림 연동
  5. [5단계] 보이스톡(음성 통화): LiveKit 연동 및 스마트폰 잠금화면 수신 UI(CallKit) 연동
  6. [6단계] 데스크톱(Windows/Mac) 최적화 & 가족 실사용 테스트

6. 다음 편 예고

다음 글에서는 Mac에서 Flutter & VS Code 개발 환경 구축하기를 다루겠습니다.

메신저 개발이나 개인 NAS를 활용한 셀프 호스팅에 관심 있으신 분들은 다음 편도 기대해 주세요! 궁금한 점이 있으시다면 언제든 댓글로 남겨주세요.

📂 Part 1. 기획 & 아키텍처 설계

📂 Part 2. 홈서버 & 인프라 구축 (UGREEN + Synology)

📂 Part 3. 백엔드(API) & 실시간 통화 서버

📂 Part 4. 모바일 앱 개발 (iOS / Android)

  • ⏳ [#07 | 앱-공통] 모바일 앱 프로젝트 생성 및 로그인/채팅방 UI 구현 (예정)
  • ⏳ [#08 | 앱-공통] 300MB 대용량 원본 사진/영상 전송 및 미디어 처리 (예정)
  • ⏳ [#09 | 앱-푸시] 앱이 꺼져 있어도 울리는 푸시 알림(FCM/APNs) 연동 (예정)

📂 Part 5. 정식 배포 & 운영

  • ⏳ [#10 | 배포] 백엔드 서버 도커 이미지 빌드 및 유그린 NAS 정식 배포 (예정)
  • ⏳ [#11 | 운영] DB 자동 백업 스크립트 구성 및 가족 실사용 후기 (예정)

댓글 남기기