서버 직접 운영
NoType 서버는 이미지 하나예요. 컨텍스트는 저장소 루트, 포트 8080, 데이터는 /data 볼륨에 둬요. 각 사용자는 자기 맥에서 시작하기 페이지의 명령으로 에이전트를 붙여요.
Docker 로 띄우기
sh
docker build -t notype .
docker run -d --name notype -p 8080:8080 -v notype-data:/data \
-e PUBLIC_URL=https://notype.example.com \
-e SESSION_SECRET=$(openssl rand -hex 32) \
-e GITHUB_CLIENT_ID=... -e GITHUB_CLIENT_SECRET=... \
-e ALLOWED_LOGINS=alice,bob \
notypedocker-compose.yml 로 쓴다면:
yaml
services:
notype:
build: .
restart: unless-stopped
ports: ["8080:8080"] # 리버스 프록시 뒤라면 127.0.0.1:8080:8080
volumes: ["notype-data:/data"]
environment:
PUBLIC_URL: https://notype.example.com
SESSION_SECRET: ${SESSION_SECRET} # openssl rand -hex 32
GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID}
GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET}
ALLOWED_LOGINS: alice,bob
TRUSTED_PROXIES: 172.16.0.0/12 # 리버스 프록시가 같은 도커 네트워크에 있을 때
volumes:
notype-data:이미지 빌드에는 메모리 2GB 정도면 돼요. 모든 값은 환경 변수에 있어요.
HTTPS 와 리버스 프록시
- 마이크는 https 에서만 열려요. Caddy·Traefik·nginx 등으로 TLS 를 끝내고 8080 으로 넘겨요.
- WebSocket(
/ws/,/agent/ws)이 그대로 통과해야 해요. nginx 라면proxy_http_version 1.1과Upgrade·Connection헤더를 넘겨요. - 첫 요청부터 https 여야 설치 스크립트 바꿔치기와 연결 코드 노출을 막아요. 명령에 보이는 주소는
PUBLIC_URL그대로예요. - Dokploy·Traefik 처럼 도커 네트워크 뒤라면
TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16을 줘요. 그래야 연결 코드 맞히기 제한이 사용자마다 걸려요.
로그인
두 방식 중 정확히 하나를 골라요.
GitHub OAuth
GitHub → Settings → Developer settings → OAuth Apps → New OAuth App 에서 만들어요.
| 칸 | 값 |
|---|---|
| Homepage URL | PUBLIC_URL |
| Authorization callback URL | <PUBLIC_URL>/auth/callback |
만든 Client ID·secret 을 GITHUB_CLIENT_ID·GITHUB_CLIENT_SECRET 에 넣어요. GitHub 은 이름을 바꿀 수 있으니, 오래 쓸 허용 목록이면 id:<숫자 id> 가 더 안전해요(curl https://api.github.com/users/<이름> 의 id).
OIDC
OIDC_ISSUER, OIDC_CLIENT_SECRET(필요하면 OIDC_CLIENT_ID)를 줘요. ES256 ID 토큰과 PKCE 를 써요. 허용 목록은 ID 토큰의 preferred_username 과 견주니, 이 이름을 사용자가 마음대로 정할 수 없는 믿을 수 있는 발급자만 써요.
함께 쓰기
- 에이전트는 한 번에 하나만 붙어요. 모든 사용자가 회의를 함께 봐요.
- 새 에이전트가 붙으면 녹음 중이던 회의는 지금까지의 줄로 끝나요.
보안 요약
- 로그인 없이 열리는 곳은
/healthz, 로그인·로그아웃, 설치·연결 스크립트(/setup,/c), 에이전트 바이너리(/dl/), 에이전트 연결뿐이에요. 나머지는 로그인과ALLOWED_LOGINS를 거쳐요. - 연결 코드 맞히기는 접속 주소마다 10분에 30번, 전체로 10분에 1000번까지예요.
- 연결 스크립트는 에이전트 바이너리의 sha256 을 확인해요. 내려받기가 중간에 끊기면 아무것도 실행되지 않아요.
- 브라우저 WebSocket 과 상태를 바꾸는 API 는
Origin이PUBLIC_URL과 같아야 해요. 인라인 스크립트 없는 CSP 를 걸어요.