TRENDSHIFT 주간 #6 딥다이브 · 2026-06-04 분석

WechatOnCloud 딥다이브
— 微信을 통째로 클라우드에 올려 브라우저로 쓰는 셀프호스팅 시스템

NAS·서버에 "微信 전용 가상 컴퓨터"를 컨테이너로 띄우고, KasmVNC로 그 화면을 브라우저에 스트리밍해 여러 기기·여러 사용자가 같은 微信 세션을 공유합니다. 微信 클라이언트는 한 줄도 고치지 않습니다. 자체 제작 패널(panel)이 Docker를 원격조종해 실례(인스턴스)를 동적으로 만들고 지웁니다. (저장소: Gloridust/WechatOnCloud · TypeScript 78% · Docker · 셀프호스팅)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

WechatOnCloud가 정확히 무엇을 하는 물건인가

WechatOnCloud(줄여서 WOC, "云微")는 NAS나 리눅스 서버 위에서 PC용 微信(위챗)을 통째로 돌리고, 그 화면을 브라우저로 원격 접속해서 쓰게 해주는 셀프호스팅 시스템입니다. 微信 데스크탑 앱은 한 글자도 수정하지 않고, 리눅스 컨테이너 안에서 "원본 그대로" 실행한 다음 화면만 웹으로 중계합니다.

핵심 구조는 한 문장으로 요약됩니다: 微信 실례 1개 = 컨테이너 1개. 컨테이너 안에서 Xvfb(가상 화면) + 원본 微信이 돌고, KasmVNC가 그 화면을 브라우저로 스트리밍합니다. 같은 실례에 여러 브라우저가 접속하면 = 같은 微信 세션을 공유하는 것이 됩니다.

한 컷 비유

"회사 서버실에 '微信 전용 미니 PC'를 여러 대 세워두고, 어디서든 브라우저로 그 PC 화면에 원격 접속하는 것"

옛날에는 微信을 쓰려면 내 노트북에 깔아야 했고, 그 노트북을 꺼두면 끝이었습니다. WOC는 微信을 항상 켜져 있는 서버 안의 가상 PC로 옮겨놓습니다. 휴대폰으로 한 번 QR을 찍어 로그인해두면, 집 데스크탑·회사 노트북·태블릿 어디서든 같은 주소를 열어 똑같은 대화창을 봅니다.

그리고 가장 앞에는 직접 만든 관리 패널(panel)이 문지기로 서 있어, 로그인·권한·실례 생성/삭제를 모두 통제합니다. 브라우저는 오직 이 패널하고만 대화합니다.

2왜 주목받는가

트렌딩 이유와 경쟁 방식 대비 강점

WOC는 TrendShift 주간 6위·월간 4위에 오른 셀프호스팅 프로젝트입니다. 微信은 같은 계정을 여러 PC에서 동시에 쓰기 어렵고, 데스크탑 세션이 자주 끊기며, 외부에서 접속하기 번거롭다는 오래된 불편이 있습니다. WOC는 이 문제를 "微信을 개조하지 않고" 컨테이너 + 원격 데스크탑 기술로 우회합니다.

기존 방식의 불편함
내 PC에 깔린 微信 — 기기에 묶이고, 원격이 번거롭다

微信 데스크탑은 내가 켜둔 그 컴퓨터에서만 돕니다. 외출 중 그 대화를 보려면 PC를 계속 켜두고 TeamViewer 같은 원격 도구로 들어가야 합니다. 상용 "클라우드폰(云手机)"은 월 구독료가 들고, 메신저 클라이언트를 개조하는 방식은 계정 차단 위험이 큽니다.

WechatOnCloud의 해법
서버에 올려두고 브라우저로 — 개조 없이, 멀티 인스턴스로

微信을 NAS/서버의 컨테이너로 옮기고 KasmVNC로 브라우저에 띄웁니다. 클라이언트를 수정하지 않아 차단 위험이 낮고, 패널에서 여러 微信 실례를 따로따로 만들어 사용자별로 접근 권한을 나눠 줄 수 있습니다(RBAC). 휴대폰처럼 홈 화면에 추가하는 PWA도 됩니다.

경쟁 방식 대비 위치

비교 항목WechatOnCloud상용 클라우드폰TeamViewer류 원격단일 docker-wechat
비용무료/셀프호스팅월 구독개인 무료/상용 유료무료
여러 微信 동시 관리멀티 인스턴스대수만큼 과금PC 1대=1세션보통 1개
접근 권한 관리사용자별 RBAC제한적없음없음
클라이언트 개조안 함(원본)경우에 따라안 함안 함
접속 방식브라우저/PWA전용 앱전용 앱브라우저(VNC)
용어 설명
셀프호스팅 (Self-hosting)
남의 클라우드 서비스에 맡기지 않고, 내 서버(집 NAS·VPS 등)에 직접 소프트웨어를 올려서 운영하는 방식. 데이터가 내 손 안에 있고 구독료가 없는 대신, 설치·보안·백업을 내가 책임집니다.

3기술 스택 전체 지도

백엔드(패널) · 프론트엔드(웹 UI) · 인프라(컨테이너/배포) 각각 상세히

WOC는 크게 세 덩어리입니다. ① 문지기이자 두뇌인 패널(panel), ② 微信이 실제로 도는 微信 실례 이미지, ③ 이 둘을 빌드·배포하는 인프라/CI. 언어 구성은 TypeScript 78%, CSS 13%, Shell 6%로, "타입스크립트로 쓴 게이트웨이 + 셸 스크립트로 짠 실행 환경"이라는 성격이 그대로 드러납니다.

백엔드 — 패널 서버 (panel/server)

기술역할세부 사항
Node.js + TypeScript패널 런타임/언어전체 게이트웨이 로직
Fastify웹 서버 프레임워크고성능 HTTP API + 정적 SPA 서빙 + 리버스 프록시
쿠키 인증로그인 세션cookie 기반 인증, KasmVNC 자격증명은 서버에서만 주입
dockerodeDocker 제어 라이브러리docker.sock으로 微信 실례 컨테이너를 동적 생성/시작/삭제
계정/권한 저장데이터 영속화accounts.json(사용자·실례 메타·비밀번호 해시)

프론트엔드 — 패널 웹 UI (panel/web)

기술역할세부 사항
React + TypeScriptSPA UI로그인 / 실례 그리드 / 자식계정 / 데스크탑 진입 화면
Vite빌드 도구프론트엔드 번들링(패널 Dockerfile에서 빌드)
PWA앱처럼 설치iOS Safari "홈 화면에 추가", 데스크탑 Chrome "설치"
테마비주얼"우유빛 천(牛奶布艺) + 微信 그린" 테마

微信 실례 실행 환경 (docker/)

기술역할세부 사항
linuxserver KasmVNC 베이스 이미지원격 데스크탑 기반Xvfb + openbox + KasmVNC + 웹 클라이언트(3000/3001) 내장, 멀티아치
Xvfb가상 디스플레이모니터 없이 GUI를 그릴 "보이지 않는 화면"
openbox창 관리자가벼운 X11 윈도우 매니저, autostart로 微信 상주 실행
원본 微信 Linux 버전실제 앱이미지에 안 넣고 런타임에 텐센트 CDN에서 다운로드(약 190~210MB)
Qt / xcb / GTK3 라이브러리微信 구동 의존성微信은 Qt 앱, 내장 WeChatAppEx는 Chromium 커널이라 GTK3 필요
중문 폰트 (Noto CJK 등)한자 렌더링없으면 글자가 네모(두부)로 깨짐

인프라 / 배포

기술역할세부 사항
Docker + Compose컨테이너 오케스트레이션compose에는 패널 1개 서비스만(微信 실례는 런타임 동적 생성)
Docker Hub / GHCR이미지 레지스트리기본 레지스트리는 Docker Hub(docker.io/gloridust). GHCR(ghcr.io/gloridust)은 동기화된 백업 소스 — .envWOC_IMAGE_PREFIX로 전환 가능
docker buildx + QEMU멀티아치 빌드amd64 + arm64 동시 빌드/푸시
GitHub ActionsCI/CDvX.Y.Z 태그/릴리스 시 멀티아치 이미지 자동 빌드·푸시
fnOS(飞牛) fpkNAS 네이티브 패키징飞牛 NAS용 앱 패키지 프로젝트(로드맵 진행 중)

4아키텍처 심화 분석

시스템 구조도(ASCII) · 핵심 설계 패턴 5가지

전체 그림은 "브라우저 → 패널 → Docker 엔진 → 微信 실례 컨테이너"의 한 줄짜리 흐름입니다. 단, 브라우저는 微信 컨테이너에 직접 닿지 못합니다. 모든 트래픽은 패널을 거치고, 패널이 자격증명을 서버 쪽에서 끼워 넣어 微信 실례로 리버스 프록시합니다.

브라우저 ──▶ panel(:36080) ──┬─ / 패널 SPA (로그인/실례 그리드/자식계정/데스크탑 진입) 쿠키 인증 ├─ /api/* 계정·실례·권한 API └─ /desktop/:id/* 리버스 프록시 → 해당 실례 KasmVNC (Basic 인증 주입) panel ──(docker.sock)──▶ Docker 엔진 ──▶ 필요할 때 생성/삭제: 微信 실례 컨테이너 woc-wx-<id> 실례 1개 = 독립 컨테이너 + 독립 데이터 볼륨 + 독립 微信 세션 실례는 Docker 내부 네트워크에만 노출 (호스트에 직접 연결 안 됨) [ 微信 실례 컨테이너 내부 ] Xvfb (가상 화면) ◀── 원본 微信(Qt) ◀── autostart(openbox) 가 상주 실행 │ └──▶ KasmVNC ──(화면 스트리밍)──▶ 패널이 /desktop/:id 로 프록시 ──▶ 브라우저

설계 패턴 1 — docker.sock 동적 컨테이너 오케스트레이션

가장 핵심적인 트릭입니다. 보통 컨테이너는 docker-compose.yml에 미리 적어두지만, WOC의 微信 실례는 사용자가 "새 微信 실례" 버튼을 누른 순간 패널이 만들어 냅니다. 패널 컨테이너에 호스트의 /var/run/docker.sock을 마운트해 두면, 패널 안의 dockerode가 호스트 Docker 엔진을 "리모컨"처럼 조종해 docker run을 대신 실행합니다.

# docker-compose.yml — 서비스는 패널 하나뿐. docker.sock을 마운트하는 게 포인트.
services:
  panel:
    image: ${WOC_IMAGE_PREFIX:-docker.io/gloridust}/woc-panel:${WOC_VERSION:-latest}
    container_name: woc-panel
    environment:
      - PORT=8080
      - WOC_WECHAT_IMAGE=${WOC_IMAGE_PREFIX:-docker.io/gloridust}/wechat-on-cloud:${WOC_VERSION:-latest}
      - PANEL_ADMIN_USER=${WOC_USER:-admin}
      - PANEL_ADMIN_PASSWORD=${WOC_PASSWORD:-wechat}   # 기본 비번 꼭 변경!
    volumes:
      - ./data-panel:/data                              # 패널 계정/실례 메타
      - /var/run/docker.sock:/var/run/docker.sock       # Docker 리모컨 = 호스트 root 권한
    ports:
      - "${WOC_HTTP_PORT:-36080}:8080"                  # 유일한 대외 입구
    restart: unless-stopped
보안상 가장 중요한 지점
docker.sock = 호스트 root 권한과 동급

docker.sock을 쥔 컨테이너는 사실상 호스트를 통째로 지배할 수 있습니다. 그래서 WOC는 ① 패널을 절대 공인 IP에 그대로 노출하지 말 것(내부망/VPN/내부망 침투 도구로만 접근), ② 실례 증감·微信 설치 같은 Docker를 건드리는 동작은 관리자만, ③ Docker API를 프론트엔드에 절대 내려보내지 않음을 원칙으로 합니다.

설계 패턴 2 — 단일 입구 + 자격증명 서버사이드 주입

브라우저는 KasmVNC의 비밀번호를 절대 받지 못합니다. 사용자가 데스크탑에 들어가면, 패널이 /desktop/:id/*로 들어온 요청에 Basic 인증 헤더를 서버에서 끼워 넣어 해당 실례로 프록시합니다. 즉 "열쇠는 문지기만 들고, 손님은 문지기를 통해서만 방에 들어간다"는 구조입니다. 실례 컨테이너 이름도 내부 랜덤 ID에서 파생해 추측/주입을 막습니다.

설계 패턴 3 — 런타임 CPU 아키텍처 자동 감지

微信은 x86_64와 arm64용 deb만 제공합니다. WOC 이미지는 멀티아치라 어디서든 같은 docker compose up -d로 뜨고, 微信을 내려받는 순간 컨테이너 안에서 dpkg --print-architecture로 CPU를 감지해 맞는 패키지를 가져옵니다.

실행 머신아키텍처자동 다운로드
Intel/AMD NAS·x86 서버amd64WeChatLinux_x86_64.deb
ARM NAS·Apple Silicon Macarm64WeChatLinux_arm64.deb

설계 패턴 4 — 微信 본체는 "이미지가 아니라 볼륨"에

微信 앱 자체는 이미지에 넣지 않습니다. 새 실례를 만든 뒤 패널에서 "다운로드 및 설치"를 누르면, 그때 텐센트 CDN에서 받아 그 실례의 데이터 볼륨에 풀어 설치합니다. 덕분에 이미지가 작아 빌드가 빠르고, 텐센트 CDN에 빌드가 묶이지 않으며, 微信만 따로 "최신으로 업데이트"하기도 쉽습니다. 다운로드·설치·상태는 셸 스크립트 wechat-ctl.sh가 맡고, 패널이 docker exec로 이를 트리거합니다.

설계 패턴 5 — 중문 입력(IME)을 클라이언트에서 처리

원격 데스크탑에서 한자/한글 입력은 악명 높은 난제입니다. WOC는 컨테이너 안에 입력기를 깔지 않고, KasmVNC의 IME 입력 모드를 켜서 "내 PC의 입력기로 완성된 글자만" 컨테이너로 보냅니다. 원래 noVNC 구현은 키 입력을 글자 단위로 다시 쏘다가 글자가 새거나 누락되는데, WOC는 입력 완료 시점(compositionend)에 완성 문자열만 직접 보내도록 웹 클라이언트 번들을 패치했습니다.

용어 설명
KasmVNC / noVNC
서버의 화면을 "픽셀째로" 브라우저에 그려주는 원격 데스크탑 기술. noVNC는 웹 표준만으로 VNC를 구현한 고전이고, KasmVNC는 그것을 성능·코덱·IME까지 개선한 현대판입니다. WOC는 KasmVNC 위에서 微信 화면을 중계합니다.

5디렉토리 구조 해부

"패널 + 微信 이미지 + 인프라" 세 덩어리가 폴더로 그대로 보인다
WechatOnCloud/ ├── .github/workflows/ │ └── release.yml # 태그/릴리스 시 멀티아치 이미지 빌드 → GHCR 푸시 ├── docker/ # ★ 微信 실례 이미지 (ghcr.io/<owner>/wechat-on-cloud) │ ├── Dockerfile # KasmVNC 베이스 + 중문 폰트 + 微信 런타임 의존성 + IME 기본 ON │ ├── wechat-ctl.sh # 런타임에 微信 다운로드/해제/업데이트 (패널이 docker exec로 호출) │ └── autostart # openbox 세션 시작: 微信 상주 실행 + 죽으면 자동 재시작 ├── panel/ # ★ 자체 제작 패널 (ghcr.io/<owner>/woc-panel, 유일한 대외 입구) │ ├── Dockerfile # 프론트 Vite 빌드 + 백엔드 Fastify 게이트웨이 (멀티아치) │ ├── server/ # Fastify: 쿠키 인증 + 계정/실례/권한 API + dockerode + 리버스 프록시 │ └── web/ # React + TS + PWA (우유빛 + 微信 그린 테마) ├── fnos/ # 飞牛 fnOS 네이티브 앱 패키징(.fpk) 프로젝트 ├── scripts/ │ └── build-local.sh # 패널 + 微信 이미지를 로컬에서 직접 빌드 (발표 전 자체 테스트용) ├── doc/ │ └── 技术方案.md # 전체 설계 문서 ├── docker-compose.yml # 단일 서비스: panel (docker.sock 마운트, 실례는 동적 생성) ├── .env.example # 선택 설정 (계정/비번, 이미지 버전, PUID/PGID, 포트, 타임존) └── README.md

핵심 파일/폴더별 역할

경로역할
panel/server두뇌. Fastify로 API를 열고, dockerode로 微信 실례를 만들고 지우며, KasmVNC로 리버스 프록시. 자격증명은 여기서만 주입
panel/web얼굴. React SPA. 로그인 → 실례 그리드 → 데스크탑 진입. PWA로 설치 가능
docker/Dockerfile微信이 돌 "가상 PC" 이미지. KasmVNC 베이스 + 폰트 + Qt/GTK 의존성. 微信 본체는 안 넣음
docker/wechat-ctl.sh微信 다운로드/해제/업데이트 셸 스크립트. 상태를 볼륨의 /config/.woc-state에 기록
docker/autostart컨테이너가 뜨면 微信을 자동 실행하고, 꺼지면 다시 살리는 "지킴이"
.github/workflows/release.yml버전 태그를 밀면 멀티아치 이미지를 빌드해 GHCR에 자동 배포
data-panel/ (런타임 생성)호스트에 남는 패널 데이터. accounts.json에 사용자·실례 메타·비번 해시
woc-data-<id> (런타임 볼륨)각 微信 실례의 데이터. /config에 微信 본체·로그인 상태·메시지 캐시

요점: 소스 트리에 "微信 실례"는 폴더로 보이지 않습니다. 그것은 실행 중에 패널이 만들어내는 동적 컨테이너이기 때문입니다. 소스에는 "그 실례를 어떻게 만들지"의 설계도(docker/)와 "누가 그것을 만드는지"의 두뇌(panel/)만 있습니다.

6학습 포인트 (기술별)

이 레포에서 배울 수 있는 기술 + 실습 아이디어

6-1. docker.sock + dockerode 동적 오케스트레이션

이 레포의 가장 값진 패턴입니다. "프로그램이 코드로 컨테이너를 만들어내는" 방식을 배웁니다. dockerode로 컨테이너를 생성하고, 볼륨을 붙이고, 같은 네트워크에 연결하는 흐름을 익히면 "셀프호스팅 PaaS"의 축소판을 만들 수 있습니다.

// dockerode로 微信 실례 컨테이너를 동적으로 만드는 개념 코드
import Docker from "dockerode";
const docker = new Docker({ socketPath: "/var/run/docker.sock" });

const c = await docker.createContainer({
  Image: process.env.WOC_WECHAT_IMAGE,        // 微信 실례 이미지
  name: `woc-wx-${id}`,                        // 랜덤 id로 컨테이너 이름
  HostConfig: {
    Binds: [`woc-data-${id}:/config`],         // 실례 전용 볼륨
    NetworkMode: net || undefined,              // 패널 컨테이너와 공유 중인 네트워크(동적 탐지, 없으면 기본 브리지)
    SecurityOpt: ["seccomp=unconfined"],       // 微信 구동에 필요
    ShmSize: 1024 * 1024 * 1024,               // 1 GB
  },
});
await c.start();

6-2. 원격 데스크탑 스트리밍 (Xvfb + openbox + KasmVNC)

"GUI 앱을 서버에서 돌려 브라우저로 보여주기"의 표준 레시피를 배웁니다. 모니터 없는 서버에 가상 화면(Xvfb)을 만들고, 가벼운 창 관리자(openbox)로 앱을 띄운 뒤, KasmVNC로 그 화면을 웹으로 중계합니다. 微信 자리에 어떤 GUI 앱을 넣어도 같은 원리입니다.

6-3. 리버스 프록시 + 자격증명 주입 게이트웨이

"백엔드의 비밀을 프론트에 노출하지 않고 안전하게 중계"하는 패턴입니다. 사용자는 패널 쿠키로만 인증하고, 패널이 뒤쪽 서비스(KasmVNC)의 Basic 인증을 서버에서 끼워 넣습니다. API 키를 숨겨야 하는 모든 프록시에 응용됩니다.

6-4. 멀티아치 Docker 이미지 (buildx + QEMU)

amd64 NAS와 arm64 NAS 양쪽에서 같은 명령으로 도는 이미지를 만드는 법을 배웁니다.

# QEMU 설치(리눅스에서 크로스 빌드 시) → buildx 빌더 생성 → 멀티아치 빌드/푸시
docker run --privileged --rm tonistiigi/binfmt --install all
docker buildx create --name woc --use
docker buildx build --platform linux/amd64,linux/arm64 \
  -t ghcr.io/gloridust/woc-panel:1.0.1 -t ghcr.io/gloridust/woc-panel:latest \
  --push ./panel

6-5. GitHub Actions 릴리스 자동화 + GHCR

버전 태그를 푸시하면 멀티아치 이미지가 자동으로 빌드·배포되는 CI/CD 파이프라인을 배웁니다. "태그 = 배포"라는 깔끔한 릴리스 규칙을 직접 경험할 수 있습니다.

# 태그를 밀면 Actions가 멀티아치 이미지를 빌드해 GHCR로 푸시
git tag v1.0.0
git push origin v1.0.0
# latest까지 갱신하려면 Release 발행 또는 workflow_dispatch 사용

6-6. PWA + 원격 IME 입력 처리

웹앱을 네이티브 앱처럼 설치하는 PWA, 그리고 원격 데스크탑의 고질적 난제인 한자/한글 입력을 compositionend 시점에 완성 문자열만 보내 해결하는 기법을 배웁니다. 한국어 IME 문제와도 똑같은 원리라 한글 입력 처리에 그대로 응용됩니다.

7하드웨어 / 시스템 요구사항

무엇이 있어야 돌아가는가 · 흔한 함정

최소 요구사항

꼭 알아야 할 실행 옵션(함정)

항목왜 필요한가
볼륨 exec 권한微信 본체가 볼륨에서 직접 실행됨. noexec 볼륨에 두면 微信이 안 뜸
seccomp=unconfined微信(Chromium 커널 포함) 구동에 필요한 시스템콜 허용
shm_size 확대공유 메모리 부족 시 화면이 검게 나오거나 微信이 죽음
중문 폰트fonts-noto-cjk 등이 없으면 글자가 네모(두부)로 깨짐
기본 비밀번호 변경기본값 admin / wechat은 반드시 즉시 변경
외부 TLS 반영패널 앞에 Caddy/Nginx 같은 HTTPS 리버스 프록시 한 겹 권장

데이터 영속화 / 백업

패널 데이터는 호스트 ./data-panel에, 각 微信 실례는 Docker 명명 볼륨 woc-data-<id>에 저장됩니다. 실례를 삭제해도 기본적으로 볼륨은 남겨(같은 이름으로 재생성하면 복구), "완전 삭제"를 명시해야 볼륨까지 지워집니다. 특정 실례 백업 = 그 woc-data-<id> 볼륨 백업입니다.

8직접 해볼 수 있는 실습 과제

난이도별 5개 — WOC를 그대로 따라하거나, 핵심 패턴만 떼어 연습
BEGINNER

패널 띄우고 微信 실례 1개 만들기 초급 · 30분

WOC를 실제로 올려보며 "컨테이너 = 가상 PC" 감각을 잡습니다. 微信 계정이 없으면 KasmVNC 진입 화면까지만 확인해도 충분합니다.

git clone https://github.com/Gloridust/WechatOnCloud.git
cd WechatOnCloud
cp .env.example .env            # WOC_PASSWORD 기본 비번 변경
docker compose up -d            # 패널 컨테이너 woc-panel 기동
docker logs -f woc-panel        # 로그 확인 후 브라우저로 :36080 접속
INTERMEDIATE

dockerode로 "버튼 누르면 컨테이너 생성" 미니 패널 중급 · 반나절

WOC의 심장인 동적 오케스트레이션만 떼어 연습합니다. 작은 Fastify 서버에서 버튼 클릭 시 nginx 컨테이너를 동적으로 만들고 지우는 API를 구현해 봅니다.

// POST /spawn → 새 컨테이너 생성, DELETE /spawn/:id → 제거
import Docker from "dockerode";
const docker = new Docker({ socketPath: "/var/run/docker.sock" });
app.post("/spawn", async (req, reply) => {
  const c = await docker.createContainer({ Image: "nginx:alpine" });
  await c.start();
  return { id: c.id.slice(0, 12) };
});
INTERMEDIATE

임의의 GUI 앱을 브라우저로 띄우기 중급 · 2시간

KasmVNC 베이스 이미지 위에 微信 대신 다른 GUI 앱(예: GIMP, 계산기)을 올려, "원격 데스크탑 스트리밍"이 앱 종류와 무관함을 체감합니다.

FROM lscr.io/linuxserver/baseimage-kasmvnc:debianbookworm
RUN apt-get update && apt-get install -y --no-install-recommends gimp
COPY autostart /defaults/autostart   # 시작 시 gimp 실행
EXPOSE 3000 3001
ADVANCED

멀티아치 이미지 빌드 → GHCR 푸시 → Actions 자동화 고급 · 하루

내 GitHub 계정으로 amd64+arm64 이미지를 buildx로 만들어 GHCR에 올리고, 태그 푸시 시 자동 빌드되는 Actions 워크플로를 작성합니다.

echo $GITHUB_PAT | docker login ghcr.io -u <user> --password-stdin
docker buildx create --name demo --use
docker buildx build --platform linux/amd64,linux/arm64 \
  -t ghcr.io/<user>/my-app:1.0.0 --push .
ADVANCED

자격증명 주입 리버스 프록시 게이트웨이 고급 · 하루

WOC의 보안 모델을 재현합니다. 쿠키로 사용자 인증을 받고, 뒤쪽 보호된 서비스(Basic 인증이 걸린)로 요청을 프록시할 때 자격증명을 서버에서 끼워 넣어 프론트엔드가 비밀을 보지 못하게 합니다.

# 개념: 쿠키 검증 통과 시에만, 서버가 Authorization 헤더를 주입해 프록시
proxy.on("proxyReq", (proxyReq) => {
  const cred = Buffer.from("user:secret").toString("base64");
  proxyReq.setHeader("Authorization", "Basic " + cred);
});

9관련 기술 심화 학습 로드맵

5주 커리큘럼 — "셀프호스팅 게이트웨이"를 스스로 설계하기까지

1주차: Docker 기초 5종

이미지 / 컨테이너 / 볼륨 / 네트워크 / docker.sock의 관계 이해. docker compose로 서비스 정의, 명명 볼륨과 바인드 마운트의 차이, 컨테이너 간 이름 기반 통신(내부 네트워크) 실습.

2주차: 프로그래밍으로 컨테이너 조종

dockerode(Node) 또는 docker-py(Python)로 컨테이너를 생성/시작/삭제. docker.sock의 권한 위험과 대안(소켓 프록시, rootless Docker) 이해. WOC의 "동적 실례 생성" 흐름 따라 만들기.

3주차: 원격 데스크탑 스트리밍

Xvfb 가상 디스플레이, X11과 창 관리자(openbox), VNC의 역사(VNC → noVNC → KasmVNC). 헤드리스 서버에서 GUI 앱을 띄워 브라우저로 보는 파이프라인 구축. 코덱·지연·IME 이슈 파악.

4주차: 인증 게이트웨이 + 리버스 프록시 + RBAC

Fastify(또는 Express)로 쿠키 세션 인증, 리버스 프록시로 백엔드 자격증명 숨기기, 역할 기반 접근 제어(관리자/자식계정)와 리소스별 권한 매트릭스 설계.

5주차: 멀티아치 빌드 · CI/CD · 보안 하드닝

buildx + QEMU 멀티아치, GitHub Actions로 태그 기반 릴리스, GHCR 배포와 공개 설정. 그리고 공인망 비노출·TLS·기본 비번 변경·감사 로그 등 셀프호스팅 보안 체크리스트 정립.

10핵심 키워드 사전

이 레포를 이해하기 위한 핵심 용어 18개
키워드설명
셀프호스팅남의 클라우드 대신 내 서버에 직접 소프트웨어를 올려 운영하는 방식
docker.sockDocker 엔진의 "리모컨" 소켓(/var/run/docker.sock). 쥐면 호스트 root와 동급의 힘
dockerodeNode.js에서 Docker 엔진을 프로그래밍으로 제어하는 라이브러리
컨테이너 오케스트레이션여러 컨테이너의 생성/배치/연결/제거를 자동으로 관리하는 것
KasmVNC서버 화면을 브라우저로 스트리밍하는 현대판 원격 데스크탑(코덱·IME 개선)
noVNC웹 표준만으로 VNC를 구현한 고전 라이브러리. KasmVNC의 뿌리
XvfbX Virtual Framebuffer. 모니터 없이 GUI를 그리는 "보이지 않는 화면"
openbox가벼운 X11 창 관리자. WOC에서 微信을 상주 실행시키는 세션 담당
리버스 프록시클라이언트 요청을 받아 뒤쪽 서버로 대신 전달. WOC에선 자격증명을 주입해 중계
FastifyNode.js의 고성능 웹 프레임워크. WOC 패널의 백엔드
PWAProgressive Web App. 웹앱을 네이티브 앱처럼 홈 화면에 설치
RBACRole-Based Access Control. 역할(관리자/자식계정)별로 접근 권한을 나누는 방식
GHCRGitHub Container Registry. GitHub가 제공하는 컨테이너 이미지 저장소
buildx / QEMUdocker buildx로 멀티아치 빌드, QEMU로 다른 CPU 아키텍처 에뮬레이션
멀티아치 이미지amd64·arm64 등 여러 CPU에서 같은 태그로 도는 이미지
seccomp컨테이너가 쓸 수 있는 시스템콜을 제한하는 보안 기능. 微信은 unconfined 필요
명명 볼륨이름을 가진 Docker 영속 디스크. 컨테이너를 지워도 데이터가 남음
IME / compositionend입력기(한자·한글 조합)와, 글자 조합이 끝나는 브라우저 이벤트. 완성 문자만 전송해 누락 방지

11참고 링크

더 깊이 파고들기 위한 리소스