📘 실전 운영 교재 v2.3

OpenClaw 실전 운영 교재

맥미니를 자동화 서버로 세팅하고, OpenClaw를 설치하고, Telegram으로 원격 제어하고, 어디서든 파일을 공유하는 법을 시행착오와 함께 배웁니다.

전체 아키텍처

완성 후 전체 운영 구조

📱 Telegram → 🦞 OpenClaw (tmux 안에서 실행) → 🧠 Claude Opus
💻 Windows → SSH/SMB (Tailscale) → 🖥️ Mac mini → 📁 ~/openclaw/

01. 맥미니 자동화용 초기 세팅

이 장은 맥이 처음인 사람도 따라할 수 있도록, 맥미니를 자동화용 서버로 세팅하는 전 과정을 다룹니다. 실제 시행착오와 판단 근거를 함께 기록했습니다.

🎯 이 장의 목표: 맥미니를 "항상 켜져 있고, 원격으로 관리 가능한 자동화 서버"로 만든다. 대상: 윈도우가 메인이고, 맥미니를 서브 장비로 쓰려는 사람.

운영 철학

맥미니를 자동화용으로 쓸 때는, 처음부터 운영 방향을 분명히 정하는 것이 중요합니다.

  • 🖥️ 맥미니는 상시 가동 — 24시간 켜두고, 자동화 프로그램(OpenClaw)이 항상 실행 중인 상태를 유지합니다.
  • 💻 윈도우 노트북이 메인 — 실제 조작은 윈도우에서 합니다. 맥 앞에 직접 가는 횟수를 최소화합니다.
  • 🔒 원격 접속은 사설 네트워크 — 공인 IP 직접 노출은 최소화하고, Tailscale 같은 사설 네트워크 위에서 관리합니다.

계정 분리 전략

자동화용 맥에서 계정을 섞지 않는 것이 핵심입니다. 사고가 나도 범위를 줄이기 위해 계정을 역할별로 나눕니다.

배경지식
계정 분리 전략 — 왜 계정을 나누는가

자동화 환경에서 계정이 섞이면 다음과 같은 문제가 생깁니다:

• 개인 비밀번호와 자동화용 토큰이 같은 키체인에 들어감
• 봇이 로그인할 서비스 계정이 개인 계정과 혼동됨
• 사고 발생 시 영향 범위가 전체로 확대됨

그래서 계정을 세 가지 역할로 분리합니다:

① 개인 실계정 — Apple 계정, 개인 메일, 개인 결제, 개인 비밀번호 관리
② 자동화 인프라 계정 — Tailscale, GitHub, 클라우드, 로그 수집, 테스트용 메일
③ 자동화 대상 계정 — 봇이 로그인할 웹 서비스 계정 (가능하면 전부 서브 계정)

추천 구조: Apple 계정은 개인 실계정, Tailscale은 자동화용 구글 계정, 봇 서비스는 서브 계정

맥 첫 부팅: 사용자 계정 만들기

맥을 처음 켜면 여러 설정이 연속으로 나옵니다. 자동화용이면 몇 가지는 의도적으로 골라야 합니다.

전체 이름은 화면에 표시되는 사람 이름입니다(예: 안현수). 계정 이름은 시스템 내부 ID로, 홈 폴더 경로(/Users/hyunsoo)에 쓰이며 나중에 바꾸기 까다롭습니다. 영문 소문자 + 숫자 조합을 추천합니다. 암호는 맥 로그인용 비밀번호로, Apple 계정 비밀번호와는 별개입니다.

macOS 초기 설정 — 사용자 계정
컴퓨터 계정 생성
전체 이름
안현수
계정 이름
hyunsoo
암호
••••••••

Apple 계정은 개인 실계정을 사용합니다. Apple 계정은 App Store, 시스템 서비스, 기기 소유권 등에 쓰이고, 자동화와는 역할이 다르기 때문입니다.

iCloud 설정: 로그인은 하되, 동기화는 전부 OFF

Apple 계정 로그인은 해도 괜찮지만, iCloud 동기화는 최소화해야 합니다. 자동화용 맥에서 개인 데이터가 클라우드에 엮이면 계정 분리가 어려워집니다.

시스템 설정 > Apple 계정 > iCloud
iCloud
iCloud Drive
키체인
사진
데스크탑 및 문서 폴더
모든 동기화 항목 OFF
iCloud 키체인 ON vs OFF
🔑 iCloud 키체인 ON
장점
  • 비밀번호 자동 저장/완성이 편리
  • 기기 간 비밀번호 동기화
단점
  • 개인용 계정과 자동화 계정이 섞임
  • 어떤 비밀번호가 어디 저장됐는지 혼란
  • 자동 로그인/완성이 과하게 작동
🔒 iCloud 키체인 OFF
장점
  • 계정 분리가 깔끔
  • 자동화 환경에서 예측 가능한 동작
  • 비밀번호는 별도 관리자로 통제
단점
  • 자동 완성 편의 기능 포기
  • 비밀번호를 수동 관리해야 함
결론
자동화용 서브 계정을 많이 다루는 환경에서는 키체인 OFF가 안전합니다. 비밀번호는 별도 관리자로 분리하세요.

키보드 & 입력 환경 세팅

맥을 처음 쓰는 윈도우 사용자가 가장 많이 헷갈리는 부분입니다. 맥 설정 화면에는 AltWindows 키가 직접 보이지 않고, 맥 기준 기능 이름으로 보입니다:

  • Alt = Option (⌥)
  • Windows 키 = Command (⌘)
  • Ctrl = Control (⌃)

이걸 이해하면 복사/붙여넣기가 헷갈리지 않습니다. 복사: Windows 키 + C (= Command + C), 붙여넣기: Windows 키 + V (= Command + V).

⌨️ 한영 전환 추천: 윈도우 키보드의 전용 한영키는 맥에서 잘 인식되지 않습니다. Caps Lock을 한영 전환으로 쓰는 것이 가장 실용적입니다. 입력 소스는 ABC + 한국어 두벌식, 이 두 개만 있으면 충분합니다. 스크롤 방향은 시스템 설정 > 마우스 > 자연스러운 스크롤 끄기 (윈도우식으로 변경)하면 됩니다.

절전 & 에너지 설정

자동화용 맥에서 절전은 가장 흔한 장애 원인입니다. 화면만 꺼지게 하고, 본체는 안 자게 만드는 것이 핵심입니다.

시스템 설정 > 에너지
에너지
디스플레이 꺼져 있을 때 자동 잠자기 방지
정전 후 자동으로 시작하기
저전력 모드

"정전 후 자동 시작"이 중요한 이유: 맥미니가 자동화 서버 역할을 하는 상황에서 정전이 발생하면, 이 설정이 꺼져 있으면 전원 복구 후에도 맥이 꺼진 상태로 남습니다. 사람이 직접 전원 버튼을 눌러야 하고, 그 사이 Tailscale, SSH, OpenClaw 전부 먹통이 됩니다. 이 설정을 켜면 전원 복구 → 자동 부팅 → 자동 로그인 → Tailscale 연결 → SSH/OpenClaw 복구로 이어집니다. 무인 운영의 출발점입니다.

⚠️
저전력 모드는 끄세요. 24시간 자동화에서는 성능 여유가 중요합니다. 발열과 전력보다, 안정적인 처리 속도가 우선입니다.

FileVault & 자동 로그인 — 보안 vs 무인 운영

이 단계는 보안과 무인 운영 사이의 핵심 갈림길입니다.

📌
시행착오 기록: 처음에 보안을 위해 FileVault를 켰습니다. 하지만 재부팅 후 바로 문제가 드러났습니다 — 부팅 시 비밀번호를 직접 넣어야 해서 Tailscale이 안 올라오고, 화면 공유도 불가, 무인 재시작이 완전히 막혔습니다.
FileVault ON vs OFF
🛡️ FileVault ON
장점
  • 저장장치 암호화로 보안 강화
  • 분실 시 데이터 보호에 유리
  • 로그인 비밀번호가 추가 보안층 역할
단점
  • 부팅 시 비밀번호 직접 입력 필수
  • 비밀번호 입력 전까지 Tailscale 불가
  • 원격 화면 공유 불가
  • 무인 재시작 완전 차단
🔓 FileVault OFF
장점
  • 재부팅 후 자동 로그인 가능
  • 무인 운영에 최적
  • 전원 복구 → 자동 부팅 → 원격 복구 가능
단점
  • 물리적 접근 시 데이터 노출 위험
  • 보안 수준 하락
결론
집 안 자동화 장비라면 FileVault OFF + 자동 로그인 ON이 실용적입니다. 사무실이나 공용 공간이라면 신중히 판단하세요. 무인 운영이 목표면 자동 로그인까지 켜야 진짜 무인 운영에 가까워집니다.
1
FileVault 끄기

시스템 설정 > 개인정보 보호 및 보안 > FileVault > 끄기

2
자동 로그인 켜기

시스템 설정 > 사용자 및 그룹 > 자동 로그인 > hyunsoo 선택

💡 참고: 자동 로그인을 설정하면 재부팅 후 자동으로: 계정 로그인 → Tailscale 실행 → SSH 복구 → 화면 공유 복구 → 자동화 프로그램 재실행이 이어집니다.

화면 공유 (VNC) 설정

키보드와 마우스를 윈도우 노트북으로 완전히 옮기려면, 맥 화면도 노트북에서 볼 수 있어야 합니다.

1
맥에서 화면 공유 켜기
시스템 설정 > 일반 > 공유
공유
📺
화면 공유
hyunsoo만 허용
2
윈도우에 RealVNC Viewer 설치
⚠️
시행착오 절약 포인트: RealVNC를 설치하면 회원가입을 강하게 유도합니다. 하지만 계정을 만들 필요 없습니다.
• RealVNC Viewer만 사용
• 맥에 별도 RealVNC Server 설치하지 않음
• 맥 내장 화면 공유 서버에 직접 접속
3
접속 테스트

RealVNC Viewer에서 Tailscale 주소로 접속합니다.

RealVNC Viewer — 접속 정보
접속 대상: 100.75.xxx.xxx
계정: hyunsoo
비밀번호: 맥 로그인 암호

🐭 마우스가 점처럼 보인다면? VNC 화면이 축소되어 표시되는 것이 원인입니다. 뷰어 창을 최대화하거나 전체 화면 모드를 사용하면 해결됩니다.

SSH 원격 로그인

SSH는 원격 터미널 관리의 기본입니다.

시스템 설정 > 일반 > 공유
🖥️
원격 로그인 (Remote Login)
다음 사용자만 허용: hyunsoo
윈도우 노트북 — SSH 접속
PS> ssh hyunsoo@100.75.xxx.xxx
Password: ••••••••
Last login: Thu Mar 26 09:00:00 2026
hyunsoo@macmini ~ % whoami
hyunsoo

🔐 왜 "관리자 그룹 전체"를 허용하지 않나: 나중에 다른 관리자 계정이 생기면 접근 범위가 넓어집니다. hyunsoo만 여는 것이 안전합니다.

02. OpenClaw 설치 및 초기 세팅

이 장은 Ch.01에서 만든 환경 위에 OpenClaw를 안정적으로 설치하고 실제로 돌아가게 만드는 단계를 다룹니다. "일단 설치만"이 아니라 안정적으로 운영 가능한 상태까지 만드는 것이 목표입니다.

설치 흐름 전체 그림

🍺 Homebrew → 📦 Node.js → 🦞 OpenClaw → 🔑 인증 → ▶️ 실행

Homebrew 설치와 첫 번째 시행착오

macOS는 기본적으로 개발 도구가 부족합니다. Node.js, npm 등을 관리하기 위해 Homebrew가 필요합니다.

💥
시행착오 기록: 처음에 curl -fsSL https://openclaw.ai/install.sh | bash를 바로 실행했더니 stdin is not a TTY 에러가 발생했습니다. 파이프 실행은 비대화형 모드라서 sudo 비밀번호 입력이 불가능합니다.
Terminal — ❌ 실패한 첫 시도
$ curl -fsSL https://openclaw.ai/install.sh | bash
stdin is not a TTY
Need sudo access

해결: Homebrew를 먼저 직접 설치합니다.

Terminal — ✅ 올바른 Homebrew 설치
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
==> Checking for `sudo` access...
Password: ••••••••
==> This script will install:
/opt/homebrew/bin/brew
...
==> Installation successful!

PATH 문제 — "command not found"의 진짜 원인

Homebrew 설치 후 brew --version을 실행하면 command not found가 나옵니다. 이것은 설치 실패가 아닙니다.

Terminal — PATH 문제 발생
$ brew --version
zsh: command not found: brew
배경지식
PATH란 무엇인가

터미널에서 brewnode 같은 명령어를 실행할 때, 시스템은 그 프로그램이 어디에 있는지 알아야 합니다.

PATH는 "명령어를 찾을 디렉토리 목록"입니다. 여기에 등록되지 않은 경로의 프로그램은 이름만으로는 실행할 수 없습니다.

Apple Silicon 맥에서 Homebrew는 /opt/homebrew/bin/에 설치됩니다. 하지만 zsh는 기본적으로 이 경로를 모릅니다.

그래서 직접 알려줘야 합니다 — ~/.zprofile에 shellenv를 추가하면 됩니다.

Terminal — ✅ PATH 해결
$ echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
$ eval "$(/opt/homebrew/bin/brew shellenv)"
 
$ brew --version
Homebrew 4.4.x

📝 핵심 교훈: 설치보다 PATH가 더 중요합니다. macOS는 설치 후 바로 안 되는 경우가 많습니다. "command not found"는 대부분 PATH 문제입니다.

OpenClaw 설치

Homebrew와 PATH가 정상이면 이제 OpenClaw를 설치합니다.

Terminal — OpenClaw 설치
$ curl -fsSL https://openclaw.ai/install.sh | bash
Checking system requirements...
Node.js v22.x detected ✓
Installing openclaw globally...
✓ OpenClaw installed successfully!
 
$ openclaw --version
openclaw v2.x.x

인증 방식 — 구독 vs API를 구분하라

OpenClaw 온보딩에서 가장 많이 헷갈리는 부분입니다. GPT Plus나 Claude Max 구독이 있어도 구독 ≠ API입니다.

API Key vs 구독(setup-token) 방식
🔑 API Key 방식
장점
  • 안정적, 공식 지원
  • 자동 갱신 불필요
  • 사용량 기반 과금으로 명확
단점
  • 별도 결제 필요 (구독과 이중 비용)
  • 사용량에 따라 비용 변동
🎫 구독 setup-token 방식
장점
  • 기존 Claude Max 구독 활용
  • 추가 비용 없이 바로 연결
단점
  • 정책 리스크 (약관 변경 가능성)
  • 토큰 자동 갱신 없음
  • 문제 시 재발급 필요
이번 선택
Claude Max 구독 사용 중이었으므로 setup-token 방식을 선택했습니다. claude setup-token 명령으로 토큰을 생성하고 연결합니다.
Terminal — setup-token 생성
$ claude setup-token
Token generated. Use it during onboarding.
⚠️ Store this token safely. No auto-renewal.

모델 선택 — Sonnet vs Opus

Claude Sonnet vs Claude Opus
⚡ Claude Sonnet
장점
  • 빠른 응답 속도
  • 일반 대화, 요약에 적합
  • 비용/토큰 효율적
단점
  • 복잡한 추론에 한계
  • 긴 컨텍스트 처리 약함
🧠 Claude Opus
장점
  • 높은 추론 성능
  • 긴 컨텍스트 처리 강함
  • 개발/코딩 작업에 최적
단점
  • 응답이 상대적으로 느림
  • 토큰 소비 많음
이번 선택
개발/코딩 목적이 주이고, 긴 컨텍스트와 높은 추론이 필요하므로 Claude Opus 4.6을 선택했습니다.

채널 · 검색 · 스킬 초기 설정

Terminal — 온보딩 초기 설정
? Configure Telegram channel?
Skip for now
 
? Web search provider?
❯ DuckDuckGo (no API key needed)
 
? Enable Skills?
❯ Yes
 
? Install Dependencies?
Skip for now
 
? Configure Hooks?
Skip for now

🎯 원칙: 최소 구성 → 안정화 → 확장. Telegram은 아직 외부 노출 단계가 아니므로 Skip. DuckDuckGo는 API 키 없이 바로 사용 가능. Skills는 에이전트 기능 활성화를 위해 Yes.

TUI 실행과 성공 확인

Terminal — TUI 실행
$ openclaw tui
 
connected | idle
model: claude-opus-4-6
session: main (openclaw-tui)

🎉 connected | idlemodel: claude-opus-4-6이 보이면 성공입니다. 맥미니 안에서 개인 AI 서버가 돌아가고 있는 것입니다.

상태 확인 주의: OpenClaw에 "현재 상태 알려줘"라고 물으면 자연어로 요약을 해줍니다. 하지만 이것은 추정값일 수 있습니다. 예를 들어 "Tailscale: 꺼져 있음"이라고 보고해도, 실제 tailscale status를 실행하면 정상일 수 있습니다. 신뢰해야 할 것은 tailscale status, openclaw gateway status, SSH 접속 여부 같은 실제 명령 결과입니다. 자연어 상태 요약은 참고만 하세요.

03. OpenClaw 운영 환경 구성 (tmux 기반)

이 장은 OpenClaw를 "설치된 프로그램"에서 "운영되는 서버"로 전환하는 단계를 다룹니다. SSH 끊김에도 살아남는 안정적인 운영 환경을 만듭니다.

SSH 끊기면 OpenClaw가 죽는다

Ch.02까지 완료된 상태는 이렇습니다:

현재 구조의 문제
SSH 접속
openclaw tui 실행
 
→ SSH 끊기면 OpenClaw도 같이 종료됨!
배경지식
프로세스와 터미널 세션의 관계

OpenClaw는 기본적으로 터미널 프로세스입니다.

터미널 프로세스는 자신이 시작된 터미널 세션에 종속됩니다. SSH 접속으로 열린 터미널 세션이 끊기면, 그 안에서 실행 중이던 프로세스도 함께 종료됩니다.

이건 버그가 아니라 정상 동작입니다. Unix/Linux 시스템에서 터미널이 닫힐 때 자식 프로세스에 SIGHUP 신호가 전달되고, 기본 동작은 종료입니다.

그래서 SSH 세션과 독립적으로 프로세스를 유지하려면 별도의 세션 관리 도구가 필요합니다.

tmux — 터미널 세션 유지 레이어

배경지식
tmux는 무엇인가

tmux는 터미널 세션을 유지해주는 레이어입니다. "프로세스를 유지하는 컨테이너" 같은 역할을 합니다.

구조가 이렇게 바뀝니다:

SSH → tmux → OpenClaw

이렇게 되면:
• SSH 끊겨도 tmux는 살아 있음
• tmux 안의 OpenClaw도 유지됨
• 다시 SSH로 접속해서 tmux에 재연결하면 이전 상태 그대로

tmux 핵심 명령

Terminal — tmux 핵심 명령
# 새 세션 생성
$ tmux new -s openclaw
 
# 세션에서 빠져나오기 (프로세스는 유지됨)
Ctrl + B → D
 
# 세션 목록 확인
$ tmux ls
openclaw: 1 windows (created ...)
 
# 세션 재연결 (attach)
$ tmux attach -t openclaw
 
# 세션 종료
$ tmux kill-session -t openclaw

변경된 실행 구조

1
SSH로 맥미니 접속
윈도우 → 맥미니
PS> ssh hyunsoo@100.75.xxx.xxx
2
tmux 세션 생성 (또는 재연결)
맥미니 — tmux
$ tmux new -s openclaw
# 또는 이미 있으면:
$ tmux attach -t openclaw
3
tmux 안에서 OpenClaw 실행
tmux 세션 안 — OpenClaw
$ openclaw tui
connected | idle
model: claude-opus-4-6
4
Detach (빠져나오기)

Ctrl + B를 누른 다음 D를 누릅니다. OpenClaw는 계속 실행됩니다.

변경된 운영 구조

💻 Windows → SSH → 🖥️ Mac mini → 📟 tmux → 🦞 OpenClaw → 🧠 Claude

로그 관리 — tmux 스크롤만으로는 부족하다

tmux는 현재 화면을 유지하고 일부 스크롤이 가능하지만, 검색이 불편하고 오래된 기록 보존이 어렵습니다. 파일 로그가 필요합니다.

tmux는 "현재 상태" — 지금 화면에서 무슨 일이 일어나고 있는지를 보여줍니다. 로그 파일은 "기록" — 과거에 무슨 일이 있었는지, 어디서 실패했는지, 왜 이상한 결과가 나왔는지를 알려줍니다. 운영에서는 둘 다 필요합니다.

Terminal — 로그 구조와 명령
# 로그 디렉토리 생성
$ mkdir -p ~/openclaw/logs
 
# tee로 화면 출력 + 파일 저장 동시
$ openclaw 2>&1 | tee -a ~/openclaw/logs/openclaw.log
 
# 최근 100줄 확인
$ tail -n 100 ~/openclaw/logs/openclaw.log
 
# 실시간 로그 추적
$ tail -f ~/openclaw/logs/openclaw.log
 
# 에러만 검색
$ grep -i error ~/openclaw/logs/openclaw.log

작업별 로그 분리

여러 작업을 동시에 실행하면 로그가 섞입니다. 작업별로 파일을 분리하는 것이 핵심입니다.

작업별 로그 구조
~/openclaw/logs/
├── openclaw.log ← 공통 로그
├── job-001.log ← 작업 1
├── job-002.log ← 작업 2
└── job-003.log ← 작업 3

📝 핵심 원칙: 작업 단위로 추적 가능해야 합니다. 로그는 "나중에"가 아니라 지금부터 남겨야 합니다.

04. 원격 제어 및 작업 체계 (Telegram + Workflow)

이 장은 OpenClaw를 "유지되는 서버"에서 "실제로 일을 시키는 시스템"으로 전환하는 단계를 다룹니다. SSH 없이도 스마트폰에서 작업을 지시할 수 있는 구조를 만듭니다.

Telegram 연동

OpenClaw는 다양한 채널을 지원하지만, 개인 사용에는 Telegram이 가장 단순합니다. Bot 기반이라 구조가 명확하고, API 키 없이도 사용 가능합니다.

1
BotFather에서 봇 생성
🤖
BotFather
bot
/newbot
오후 2:30
Alright, a new bot. How are we going to call it?
오후 2:30
My OpenClaw Bot
오후 2:31
Good. Now let's choose a username. It must end in `bot`.
오후 2:31
myopenclaw_bot
오후 2:31
Done! Use this token:
123456789:ABCdefGHIjklMNO...
오후 2:31
2
OpenClaw에 토큰 등록 및 재시작
Terminal — Telegram 채널 설정
$ openclaw gateway restart
● Gateway restarted
Channels: web, telegram (active)
3
Pairing 승인

처음 봇에게 메시지를 보내면 Access not configured / Pairing code: XXXXX 메시지가 뜹니다. 아무나 봇을 못 쓰게 막아둔 상태입니다.

Terminal — Pairing 승인
$ openclaw pairing list telegram
Pending:
code: ABC123 user: Hyunsoo (8392998529)
 
$ openclaw pairing approve telegram ABC123
✓ User 8392998529 approved for Telegram DMs

역할 분리: SSH vs Telegram

  • 🔧 SSH — 관리용: 시스템 접속, tmux 재연결, 로그 확인, 설정 변경, 장애 대응 등 인프라 관리에 사용합니다.
  • 📱 Telegram — 운영용: 작업 지시, 결과 확인, 상태 점검 등 일상적인 운영에 사용합니다. 스마트폰에서 언제든 가능합니다.

명령 체계 설계

자연어만 쓰면 작업 방식이 흔들립니다. 명령 체계 + 자연어 혼합이 핵심입니다.

명령 체계 — 10가지 핵심 명령
/plan 계획만 수립 (구현하지 않음)
/dev 개발/수정/구현 실행
/run 이미 만든 코드 실행, 결과 생성
/review 결과 검토
/teach 교육용 정리
/log 로그 확인
/jobs 작업 목록
/status 현재 상태
/health 시스템 점검
/stop 작업 중단
배경지식
/dev vs /run — 왜 구분해야 하는가

/dev = "만든다" — 코드 작성, 구조 설계, 자동화 구성, 리팩토링

/run = "돌린다" — 이미 만든 코드를 실행해서 결과를 생성

이걸 분리하면:

• 작업 의도가 명확해짐
• 로그 구조가 자연스럽게 정리됨
• 개발 단계와 실행 단계의 기록이 분리됨
• 교재화 가능성 상승 — 과정이 설명 가능해짐

분리하지 않으면 "수정하면서 실행하면서 또 수정"이 되어 추적이 어려워집니다.

표준 작업 흐름

🦞
OpenClaw Bot
online
/plan 새 웹사이트 프로젝트 구조 파악하고 작업 계획 세워
오전 10:00
프로젝트 구조를 파악했습니다. 작업 계획:
1. HTML 구조 설계
2. CSS 테마 시스템 구현
3. JS 인터랙션 추가
승인 후 /dev로 진행하시면 됩니다.
오전 10:01
/dev 승인. 1번부터 구현 시작해
오전 10:02
HTML 구조 구현을 시작합니다... ✅ 완료
변경된 파일: index.html
오전 10:05
/review 결과 검토해
오전 10:06

workspace 파일 구조

OpenClaw는 하나의 CLAUDE.md가 아니라 역할별 파일로 분리해서 시스템을 정의합니다.

~/.openclaw/workspace/ 구조
~/.openclaw/workspace/
AGENTS.md ← 행동 규칙 (작업 절차, 체크포인트, 보고 규칙)
SOUL.md ← 성격과 톤 (정체성, 커뮤니케이션 스타일)
TOOLS.md ← 도구 사용 규칙 (탐색, 검증, 병렬화)
USER.md ← 사용자 정보 (선호, 작업 방식)
IDENTITY.md ← 캐릭터 (이름, 역할, 분위기)

세션 기반 동작에 주의하세요: OpenClaw는 workspace 파일을 세션 시작 시에 로딩합니다. 즉, AGENTS.md나 SOUL.md를 수정해도 기존 세션에는 반영되지 않을 수 있습니다. 설정 변경 후에는 반드시 openclaw tui --session fresh로 세션을 재시작해야 합니다. 이것은 버그가 아니라 설계입니다 — 세션 안정성을 위해 시작 시점의 설정을 유지합니다.

📝 핵심 교훈: OpenClaw는 "도구"가 아니라 작업 시스템입니다. Telegram은 "채팅"이 아니라 컨트롤 인터페이스입니다. 명령 체계 없으면 운영이 무너집니다.

05. 프로젝트 구조와 생성 스크립트

Ch.04까지 끝나면 OpenClaw는 "실행은 되는 상태"입니다. 하지만 새 작업이 들어올 때마다 폴더를 손으로 만들고, 어디에 기록할지 그때그때 정하게 됩니다. 이 장의 목적은 새 프로젝트를 시작할 때의 표준 시작점을 만드는 것입니다.

base + modules — 프로젝트 구조 설계

고정 템플릿 vs base + modules 방식
📋 고정 템플릿 방식
장점
  • 설명이 쉬움 (dev, doc, data 등)
  • 분류가 단순함
단점
  • 실제 프로젝트는 거의 항상 혼합형
  • "코드도 있고 문서도 있는" 프로젝트 분류 곤란
  • 프로젝트가 늘어나면 구조가 들쭉날쭉
🧩 base + modules 방식
장점
  • 프로젝트 종류가 아닌 필요 기능을 조합
  • 실제 현실에 잘 맞음
  • 확장이 자유로움
단점
  • 처음 이해가 약간 복잡
  • 조합이 많아질 수 있음
결론
프로젝트를 "무슨 종류인가"로 나누지 않고, "무슨 기능이 필요한가"로 조합합니다. 이것이 장기적으로 더 깔끔합니다.
base + modules 구조
── base (모든 프로젝트 공통) ──
notes/ ← 계획, 리뷰, 학습 기록
outputs/ ← 생성 결과물
logs/ ← 실행 로그
 
── modules (선택 추가) ──
code → src/, tests/
docs → drafts/, references/
data → data/, reports/
ops → scripts/, configs/, runs/
 
── 조합 예시 ──
코드+문서 프로젝트 → code docs
문서+운영 프로젝트 → docs ops
전체 프로젝트 → code docs data ops

.openclaw vs ~/openclaw — 설정과 작업 자산의 분리: ~/.openclaw는 OpenClaw 자체 설정과 내부 자산을 둡니다 (workspace 파일, 세션 설정 등 — 앱의 머리). ~/openclaw는 실제 운영하면서 쌓이는 작업 자산을 둡니다 (프로젝트 폴더, 로그, 산출물 — 앱이 일하면서 쌓는 몸통 데이터). 이렇게 분리하면 설정과 산출물이 섞이지 않고, 백업 범위를 나누기 쉽고, 재구성해도 운영 데이터가 안전합니다.

권장 전체 디렉토리 구조
~/.openclaw/ ← 설정 (앱의 머리)
workspace/
AGENTS.md, SOUL.md, ...
 
~/openclaw/ ← 작업 자산 (몸통)
projects/ ← 프로젝트들
logs/ ← 공통 로그
outputs/ ← 공용 산출물
scripts/ ← 운영 스크립트
runbook/ ← 운영 매뉴얼

new_project.sh — 프로젝트 생성 스크립트

new_project.sh는 새 프로젝트를 시작할 때 필요한 기본 폴더와 파일을 표준 방식으로 만들어주는 도구입니다. 상시 실행이 아니라 필요할 때 1회 실행합니다.

⚠️
실행 위치 주의: 이 스크립트는 윈도우 PowerShell에서 직접 실행하는 것이 아닙니다. SSH로 접속한 뒤의 맥미니 셸에서 실행합니다.
1
스크립트 저장 및 권한 설정
Terminal — 스크립트 저장
$ mkdir -p ~/openclaw/scripts
$ nano ~/openclaw/scripts/new_project.sh
# 스크립트 내용 붙여넣기 후 Ctrl+O → Enter → Ctrl+X
 
$ chmod +x ~/openclaw/scripts/new_project.sh
$ ls -l ~/openclaw/scripts/new_project.sh
-rwxr-xr-x 1 hyunsoo staff ... new_project.sh
2
dry-run으로 미리보기
Terminal — dry-run 테스트
$ ~/openclaw/scripts/new_project.sh test-project code docs --dry-run
 
[dry-run] Would create:
~/openclaw/projects/test-project/
notes/
outputs/
logs/
src/ ← code module
tests/ ← code module
drafts/ ← docs module
references/ ← docs module
README.md
notes/plan.md
notes/review.md
notes/teach.md
3
실제 생성
Terminal — 프로젝트 생성
$ ~/openclaw/scripts/new_project.sh test-project code docs
✓ Project created: ~/openclaw/projects/test-project
Modules: code, docs
Files: README.md, plan.md, review.md, teach.md
🍎
macOS bash 호환성 주의: macOS 기본 bash는 오래된 3.2 버전이라 mapfile 등 최신 bash 문법을 지원하지 않습니다. 스크립트는 macOS 기본 셸 호환 형태로 작성해야 합니다. 단순하고 호환성 높은 문법이 운영 안정성 측면에서 유리합니다.

명령 체계와 폴더의 연결

Ch.04에서 설계한 작업 흐름은 단순 명령 체계가 아니라, 파일 구조 안에서 흔적이 남는 운영 구조여야 합니다.

명령 → 폴더/파일 매핑
/plan → notes/plan.md
/dev → src/, drafts/, scripts/ (실제 작업 공간)
/run → outputs/, logs/, runs/
/review → notes/review.md
/teach → notes/teach.md

🎯 핵심: Telegram 명령이 단순 채팅이 아니라, 파일 구조 안에서 흔적이 남는 작업 체계로 이어지는 것입니다.

06. 메인-서브 PC간 파일 공유 (SMB + Tailscale)

앞선 장들로 OpenClaw 운영 시스템이 완성되었습니다. 이제 남은 것은 하나 — 파일을 어떻게 안전하고 편하게 다룰 것인가입니다. 이 장에서는 윈도우에서 맥미니의 파일을 로컬처럼 사용하는 구조를 완성합니다.

SMB란 무엇인가

배경지식
SMB (Server Message Block) — 네트워크 파일 공유 프로토콜

SMB는 네트워크를 통해 폴더를 공유하는 방식입니다. 윈도우에서는 \\서버주소\공유폴더 형태로 접근합니다.

장점:
• 파일 탐색기에서 바로 접근 가능
• 드래그 앤 드롭으로 파일 이동
• 네트워크 드라이브로 연결하면 로컬 드라이브처럼 사용
• 별도 프로그램 불필요 (윈도우와 macOS 모두 기본 지원)

일반적인 SMB 사용 방식(\\192.168.x.x\share)은 같은 와이파이에서만 동작합니다. 외부에서는 접속이 불가하고, 공인 IP로 열면 보안 위험이 큽니다.

Tailscale + SMB 조합

파일 공유 방식 비교
🌐 공인 IP SMB
장점
  • 별도 도구 없이 가능
단점
  • 인터넷에 직접 노출 (보안 위험)
  • 공유기 포트포워딩 필요
  • IP 변동 시 접속 불가
🔒 Tailscale + SMB
장점
  • 어디서든 접속 가능
  • 외부 노출 없음 (사설 네트워크)
  • 포트포워딩 불필요
  • 탐색기에서 드라이브처럼 사용
단점
  • 양쪽 Tailscale 실행 필요
📂 scp / sftp
장점
  • SSH만 있으면 사용 가능
  • 암호화 전송
단점
  • 파일 1~2개 전송에만 적합
  • 탐색기 통합 불가
  • 지속적 작업에 불편
결론
지속적인 파일 작업에는 Tailscale + SMB 조합이 최적입니다. NAS 없이 NAS처럼 사용할 수 있습니다.

Tailscale + SMB 연결 구조

💻 Windows (\\100.xxx\share) → Tailscale → 🖥️ Mac mini (SMB 서버) → 📁 ~/openclaw

맥 설정: 파일 공유 ON

1
파일 공유 켜기
시스템 설정 > 일반 > 공유
공유
📁
파일 공유
SMB를 사용하여 파일 및 폴더 공유

옵션에서 "SMB를 사용하여 파일 및 폴더 공유" 체크, 사용자 계정 체크, 비밀번호 입력.

2
공유 폴더 추가

공유 폴더를 추가하고 권한을 설정합니다. 사용자에게 "읽기 및 쓰기" 권한을 줍니다.

윈도우에서 접속

1
파일 탐색기에서 접속

양쪽 Tailscale이 실행 중인 상태에서 윈도우 파일 탐색기 주소창에 입력합니다.

Windows 파일 탐색기 — 주소창
\\100.xxx.xxx.xx\share
 
사용자 이름: hyunsoo
비밀번호: 맥 로그인 비밀번호
2
네트워크 드라이브 연결 (추천)
Windows — 네트워크 드라이브 연결
네트워크 드라이브 연결
드라이브
Z:
폴더
\\100.xxx.xxx.xx\share
로그온 시 다시 연결
다른 자격 증명을 사용하여 연결

운영 팁

  • 📏 공유 범위 최소화 — 전체 디스크가 아닌, 작업 폴더 하나만 공유하세요. 관리자 계정이면 전체가 보여 실수로 삭제 위험이 있습니다.
  • 🔌 필요할 때만 켜기 — 파일 공유는 상시 켜둘 필요 없습니다. 파일 작업이 필요할 때만 ON, 끝나면 OFF가 보안상 좋습니다.
  • 📦 Taildrop 활용 — 파일 1~2개를 빠르게 전송할 때는 Tailscale의 Taildrop 기능도 유용합니다. 지속 작업은 SMB가 편합니다.

🎉 이것으로 전체 구성 완료! 이 구조가 완성되면: NAS 없이 NAS처럼 사용 가능, 자동화 결과 확인 속도 향상, 원격 작업 효율 극대화.

최종 완성 구조 — 전체 운영 시스템 요약

6장까지 완료된 전체 시스템:

  • 맥미니 — 상시 가동, 자동 부팅, 자동 로그인
  • Tailscale — 사설 네트워크로 안전한 연결
  • SSH — 관리용 원격 접속
  • 화면 공유 — GUI 조작 필요시
  • OpenClaw — tmux 안에서 안정 실행
  • Telegram — 스마트폰에서 작업 지시
  • 프로젝트 구조 — base + modules로 표준화
  • SMB — 윈도우에서 맥 파일을 드라이브처럼 접근

이 모든 것이 하나의 원격 개발 시스템으로 동작합니다.

07. Telegram 그룹 생성하기

Ch.04에서 Telegram을 연결하고 나면, 다음 단계는 그룹에서 작업을 시작하는 것입니다. 그런데 그룹에서 일반 메시지에 무응답이 발생하는 경우가 있습니다. 이 장은 이 문제의 원인과 해결법을 정리합니다.

그룹 꼬임 문제 — 설정 문제가 아니다

다음과 같은 현상이 발생할 수 있습니다:

📱 DM → ✅ 정상 응답
💬 그룹 멘션 → ✅ 응답
💬 그룹 일반 메시지 → ❌ 무응답

이 상황에서 대부분 다음을 의심합니다:

  • OpenClaw 설정 문제 ❌
  • 모델 문제 ❌
  • Gateway 문제 ❌
📌
실제 원인: 대부분 Telegram 그룹 상태가 꼬여서, 봇이 "정상 멤버가 아닌 상태"입니다. OpenClaw 문제가 아닙니다.

그룹 UI에서 다음이 보이면 문제 상태입니다:

  • Members: 1 (또는 실제 인원보다 적게 표시)
  • 봇이 has access to messages로 표시됨
배경지식
왜 이런 상태가 생기나

주로 다음 상황에서 발생합니다:

1. 봇 Kick / Ban 이력 — 그룹에서 봇을 "내보내기" 또는 "차단" 후 재초대하면, Telegram 내부적으로 restricted 상태가 유지될 수 있습니다.

2. Supergroup 구조 꼬임 — 채널 연결 Discussion Group 또는 Supergroup 전환 과정에서 상태가 이상해지는 경우입니다.

3. Telegram 내부 상태 캐싱 — 봇은 추가됐지만 정상 멤버로 승격되지 않은 상태로 캐싱됩니다.

증상과 패턴 — 100% 구조 문제 판별법

그룹 꼬임 증상 패턴
일반 메시지 → ❌ 무응답
@멘션 메시지 → ⭕ 응답
DM → ⭕ 정상
 
이 패턴 = 100% Telegram 구조 문제
항목 정상 상태 문제 상태
멤버 여부✅ 정식 멤버❌ restricted 상태
일반 메시지 수신✅ 가능❌ 불가
멘션 수신✅ 가능⭕ 일부 가능
Members UI실제 인원 수1로 표시 (이상)

잘못된 해결 시도 — 시간 낭비 방지

❌ 효과 없는 시도들
× OpenClaw 설정 수정
× openclaw gateway restart
× 모델 변경
× privacy mode 변경
 
이유: 문제는 Telegram 내부 상태이기 때문

해결: 새 그룹 생성

기존 그룹 복구 vs 새 그룹 생성
🔧 기존 그룹 복구
장점
  • 기존 대화 기록 유지
  • 새로 초대 불필요
단점
  • 봇 제거 → 재초대 반복해도 실패 多
  • Telegram 내부 상태 리셋 불가
  • 불안정한 상태 지속 가능
  • 시간 낭비 위험
✨ 새 그룹 생성
장점
  • 가장 빠르고 확실한 해결
  • 깨끗한 상태에서 시작
  • 봇이 처음부터 정식 멤버
단점
  • 기존 대화 기록 이전 불가
  • 멤버 재초대 필요
결론
Telegram 그룹이 꼬이면 복구하려 하지 말고 새로 만든다. 이것이 가장 빠른 해결 방법입니다.
1
새 그룹 생성

Telegram 앱에서 새 그룹을 만들고 사용자를 추가합니다.

2
봇 바로 추가

@your_bot을 초대합니다. 불필요한 설정은 건드리지 않습니다.

3
정상 상태 확인
정상 상태 기준
✅ Members: 실제 인원 수 (2 이상)
✅ 봇이 멤버 리스트에 포함
✅ "has access to messages" 문구 없음
4
테스트 메시지
🦞
OpenClaw Bot
online
ping
오후 3:00
pong 🏓
오후 3:00

멘션 없이 일반 메시지에 응답하면 정상입니다.

💡
운영 팁: 그룹 상태 확인은 UI로 판단합니다. Members 수와 멤버 리스트가 기준입니다. 멘션만 되는 경우는 100% 구조 문제 — 설정을 건드리지 말고 그룹을 의심하세요.

08. Telegram 그룹 운영 설정과 프로젝트 폴더 연결

Ch.07까지 Telegram 그룹을 안정적으로 만들었습니다. 이 장은 그 그룹을 실제 작업 공간으로 연결하는 단계를 다룹니다. 목표는 "봇이 응답하는 것"이 아니라, 텔레그램 대화가 파일 구조로 기록되는 운영 시스템을 완성하는 것입니다.

이번 장에서 만드는 구조

📱 Telegram 그룹 → 🦞 OpenClaw → 📁 그룹별 프로젝트 폴더 → notes / outputs / logs

그룹 1개 = 프로젝트 1개 = 폴더 1개

Telegram 그룹은 단순 채팅방이 아니라 프로젝트 단위 작업 채널이어야 합니다. 작업이 진행되면 계획 메모, 산출물, 로그, 검토 기록이 함께 쌓이기 때문입니다.

배경지식
왜 그룹 1개당 프로젝트 폴더 1개인가

OpenClaw는 기본적으로 chat_id 기준으로 연결을 관리합니다. 그룹 안에서 토픽 여러 개를 프로젝트로 나누는 구조는 기본 상태에서는 안정적이지 않습니다.

그룹 1개 = 프로젝트 1개 구조의 장점:
• 어떤 그룹이 어떤 프로젝트인지 명확
• 작업 기록이 섞이지 않음
• 로그 추적이 쉬움
• 디버깅 시 기준 경로가 항상 확정됨

매핑 파일 구조 (양방향)
~/.openclaw/.folder-telegram-group-index.json
← 그룹 기준 조회 (chat_id → project_path)
 
~/openclaw/projects/프로젝트명/.folder-telegram-group.json
← 프로젝트 기준 조회 (project → chat_id)

Privacy Mode — Telegram과 OpenClaw 양쪽 설정

봇이 그룹 일반 메시지를 받으려면 두 가지 설정이 함께 맞아야 합니다.

1
BotFather — Privacy Mode 끄기
🤖
BotFather
bot
/mybots
오후 2:00
Select a bot: @your_bot
오후 2:00
Bot Settings → Group Privacy
오후 2:01
Privacy mode is currently ENABLED. Turn off?
오후 2:01
Privacy mode is now DISABLED. ✅ Bot can receive all group messages.
오후 2:01
⚠️
주의: Privacy Mode 변경은 그룹 구조 문제(restricted 상태)와 별개입니다. 그룹 자체가 꼬여 있다면 이 설정을 바꿔도 해결되지 않습니다 — 새 그룹 생성이 우선입니다.
2
OpenClaw — 그룹 정책 설정
openclaw 설정 — Telegram 그룹 정책
"dmPolicy": "pairing",
"groupPolicy": "open",
"groups": {
"*": {
"requireMention": false,
"groupPolicy": "open"
}
}

requireMention: false이면 멘션 없이도 그룹 일반 메시지를 처리합니다.

/start — 연결 명령

/start는 텔레그램 그룹과 프로젝트 폴더를 바인딩하는 명령입니다. 프로젝트를 다 만드는 것이 아니라 연결만 수행합니다.

배경지식
왜 /start를 작게 유지해야 하나

/start에 폴더 구조 생성, 템플릿 복사, 문서 초기화까지 한 번에 넣으면, 문제가 생겼을 때 어느 단계에서 실패했는지 추적하기 어려워집니다.

/start를 연결 전용으로 두면:
• 어느 단계에서 실패했는지 분리 가능
• 연결만 성공했는지 확인 가능
• 이후 구조 생성은 별도 재실행 가능
• 오류 복구가 쉬움

/start = 등록 명령으로 이해하는 편이 맞습니다.

/start 실행 흐름
1. 현재 Telegram 그룹의 chat_id 확인
2. 그룹 이름 → 프로젝트 이름 결정
3. ~/openclaw/projects 아래 경로 확정
4. 그룹 ↔ 폴더 매핑 등록
5. 성공 메시지 + /structure 안내

/structure — 구조 적용 명령

/structure는 연결된 프로젝트 폴더에 기본 디렉토리 구조를 입히는 명령입니다. 반드시 /start 이후에만 실행해야 합니다.

/start vs /structure 역할 구분
🔗 /start
역할
  • 그룹 ↔ 프로젝트 폴더 바인딩
  • 매핑 파일 생성
  • 인덱스 등록
하지 않는 것
  • 폴더 구조 생성 ❌
  • 템플릿 파일 생성 ❌
🏗️ /structure
역할
  • notes/, outputs/, logs/ 생성
  • 선택 모듈 적용 (code, docs, data, ops)
  • 기본 템플릿 파일 생성
제약
  • 연결된 그룹에서만 실행
  • idempotent (재실행 안전)
핵심 설계
연결과 구조 적용을 분리하면, 각 단계의 실패를 독립적으로 추적하고 재시도할 수 있습니다. 이미 작업이 시작된 폴더에 /structure를 다시 실행해도 기존 파일은 유지됩니다.

운영 절차 요약

1
BotFather — Privacy Mode 확인

봇의 그룹 privacy 상태를 확인하고 disabled로 맞춥니다. 그룹 자체가 꼬여 있다면 새 그룹 생성이 우선입니다.

2
새 Telegram 그룹 생성

새 그룹 생성 → 사용자 추가 → 봇 초대 순서로 진행합니다. 봇이 정식 멤버로 보이는지 UI에서 확인합니다.

3
기본 응답 테스트

멘션 없이 ping을 보내 일반 메시지 수신 여부를 확인합니다.

4
/start 실행
🦞
OpenClaw Bot
online
/start
오전 10:00
✅ 프로젝트 폴더가 연결되었습니다.
경로: ~/openclaw/projects/my-project
기본 구조를 생성하려면 /structure를 실행하세요.
오전 10:00
5
/structure 실행
🦞
OpenClaw Bot
online
/structure
오전 10:01
✅ 프로젝트 기본 구조가 생성되었습니다.
- notes/ ✓
- outputs/ ✓
- logs/ ✓
오전 10:01
6
실제 작업 시작

이제부터 이 그룹은 해당 프로젝트를 운영하는 인터페이스가 됩니다. /plan → /dev → /run → /review 흐름으로 작업하면 결과가 프로젝트 폴더에 쌓입니다.

09. SSH, 공인 IP, Tailscale 기반 보안 구성

지금까지 만든 시스템은 편리하지만, 공인 IP가 외부에 노출된 상태라면 언제든 공격 대상이 될 수 있습니다. 이 장은 공인 IP 기반 SSH를 완전히 차단하고, Tailscale 전용 보안 구조로 전환하는 방법을 다룹니다.

최종 보안 구조

💻 노트북 → (Tailscale) → 🖥️ 맥미니 (100.x.x.x) → OpenClaw / 개발 서버
❌ 공인 IP (210.x.x.x) → 차단됨

보안 모델 이해

공인 IP SSH vs Tailscale SSH
🌐 공인 IP SSH
특징
  • 어디서든 바로 접속 가능
위험
  • 전 세계에서 접근 가능
  • 포트 스캔 대상
  • brute force 공격 노출
🔒 Tailscale SSH
특징
  • 내 계정 네트워크만 접근 가능
  • 포트 스캔 불가
  • brute force 불가
  • 보안 수준 매우 높음
주의
  • Tailscale 계정 보안이 핵심
공격 난이도 변화
공인 IP → 바로 공격 가능. Tailscale → 계정 해킹 → 네트워크 진입 → SSH 공격 순서 필요. 공격 난이도가 급상승합니다.

1단계: SSH 키 기반 인증 설정

1
키 생성 (노트북에서)
Windows PowerShell — SSH 키 생성
PS> ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
~/.ssh/id_ed25519 ← 개인 키 (절대 유출 금지)
~/.ssh/id_ed25519.pub ← 공개 키 (맥미니에 등록)
2
공개 키 등록 (맥미니에서)
맥미니 — 공개 키 등록
$ nano ~/.ssh/authorized_keys
# id_ed25519.pub 내용을 붙여넣기
$ chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
3
테스트
Windows — 키 인증 접속 테스트
PS> ssh hyunsoo@100.x.x.x
비밀번호 없이 접속되면 성공 ✅

2단계: 비밀번호 로그인 완전 차단

맥미니 — sshd_config 수정
$ sudo nano /etc/ssh/sshd_config
# 아래 내용 추가:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
 
$ sudo launchctl stop com.openssh.sshd && sudo launchctl start com.openssh.sshd
 
# 비밀번호로 접속 시도 → 실패해야 정상
PS> ssh -o PreferredAuthentications=password hyunsoo@100.x.x.x
Permission denied (publickey) ✅

3단계: 공인 IP SSH 차단 (pf 방화벽)

macOS 내장 방화벽 pf를 사용해 공인 IP로의 SSH 포트 자체를 차단합니다.

1
네트워크 인터페이스 확인
맥미니
$ route get default | grep interface
interface: en0
2
pf 규칙 생성 및 적용
맥미니 — pf 설정
$ sudo nano /etc/pf.anchors/block-public-ssh
block in quick on en0 proto tcp from any to (en0) port 22
 
# /etc/pf.conf 맨 아래에 추가:
anchor "block-public-ssh"
load anchor "block-public-ssh" from "/etc/pf.anchors/block-public-ssh"
 
$ sudo pfctl -f /etc/pf.conf && sudo pfctl -e
pf enabled ✅
3
검증
Windows — 검증
# Tailscale → 성공
PS> ssh hyunsoo@100.x.x.x
Last login: ... ✅
 
# 공인 IP → timeout (정상)
PS> ssh hyunsoo@210.x.x.x
Connection timed out ✅

4단계: 개발 서버 외부 노출 방지

개발 서버 실행 방식 비교
# ❌ 위험한 방식 — 외부 노출
$ npx next dev → http://210.x.x.x:3000 (공개)
 
# ✅ 안전한 방식 — localhost 바인딩
$ npx next dev -H 127.0.0.1 -p 3000
→ http://127.0.0.1:3000 (로컬만)
 
# 외부에서 접근 필요 시 — SSH 터널
PS> ssh -L 3000:127.0.0.1:3000 hyunsoo@100.x.x.x
→ 브라우저: http://localhost:3000
🛡️
보안 운영 원칙 3가지:
1. Google/GitHub 2FA 필수 — Tailscale 계정 보안이 전체의 핵심
2. ~/.ssh/id_ed25519 개인 키 절대 유출 금지
3. 개발 서버는 항상 127.0.0.1로 바인딩, 공인 IP 직접 접속 금지

10. OpenClaw 셋팅을 개인화하기

설치와 보안 구성이 끝났다면, 마지막 단계는 OpenClaw를 "내 환경을 아는 에이전트"로 만드는 것입니다. 기본 OpenClaw는 강력하지만, 내 서버 구조나 보안 정책을 모릅니다. 개인화는 이 간극을 메웁니다.

왜 개인화가 필요한가

💥
실제 문제 사례: OpenClaw에게 "Tailscale 상태 알려줘"라고 했더니 "Tailscale이 설치되어 있지 않습니다"라고 답했습니다. 실제로는 설치되어 있었지만, PATH 문제로 오판한 것이었습니다.

기본 OpenClaw의 한계:

  • 내 서버 환경 구조를 모름
  • 네트워크 구조 (Tailscale IP, 공인 IP) 모름
  • 보안 정책 (공인 IP 차단 여부) 모름
  • 추측 기반으로 답변하여 잘못된 안내를 줄 수 있음

핵심 원칙: OpenClaw는 "알려준 것만 안다"

그래서 반드시 필요한 것: 환경 정의 + 행동 규칙 + 상태 조회 도구

개인화의 3가지 레이어

1
환경 정의 — USER.md

"나는 어떤 구조에서 일하는가"를 정의합니다.

~/.openclaw/workspace/USER.md — 예시
## 시스템 구조
Windows 노트북 → Telegram → Mac mini → OpenClaw
 
## 네트워크 구조
- Tailscale 기반 사설 네트워크
- SSH: 100.x.x.x (Tailscale)
- 공인 IP: 차단됨
2
행동 규칙 — AGENTS.md

"어떻게 행동해야 하는가"를 정의합니다. 보안 정책과 판단 기준을 주입합니다.

~/.openclaw/workspace/AGENTS.md — 보안 규칙 예시
공인 IP 기반 SSH 안내 금지
개발 서버를 외부 URL로 안내 금지
SSH는 항상 Tailscale (100.x.x.x) 기준으로 안내
개발 서버는 localhost 바인딩 강제
3
상태 조회 스크립트

OpenClaw가 상태를 "추측"하지 않고 직접 확인하게 만듭니다. 원격 접속 관련 질문이 오면, 스크립트를 실행해 실제 상태를 기반으로 답합니다.

Workspace 파일 분리 전략

~/.openclaw/workspace/ — 역할별 파일 분리
USER.md ← 환경 설명 (시스템 구조, 작업 방식, 네트워크)
AGENTS.md ← 행동 규칙 (보안 정책, 판단 기준, tmux 규칙)
TOOLS.md ← 실행 방식 (개발 서버 규칙, SSH 터널, 스크립트)
SOUL.md ← 성격/톤 (정체성, 커뮤니케이션 스타일)
IDENTITY.md ← 캐릭터 (이름, 역할)

각 파일의 역할을 명확히 나누면, 어디를 수정해야 할지 바로 알 수 있습니다. 하나의 큰 파일보다 작은 파일 여러 개가 운영에 유리합니다.

상태 조회 스크립트

~/openclaw/scripts/get-remote-access-info.sh
#!/bin/bash
echo "=== Remote Access Info ==="
TS_IP=$(tailscale ip -4 2>/dev/null)
echo "Tailscale IP: $TS_IP"
echo "SSH: ssh $(whoami)@$TS_IP"
echo "Tunnel: ssh -L 3000:127.0.0.1:3000 $(whoami)@$TS_IP"

AGENTS.md에 다음 규칙을 추가하면, 원격 접속 관련 질문 시 OpenClaw가 자동으로 스크립트를 실행합니다:

AGENTS.md — 스크립트 사용 규칙
원격 접속 관련 질문 시:
반드시 ~/openclaw/scripts/get-remote-access-info.sh 실행 후 답변

개인화 전후 비교

개인화 전 vs 후
😕 개인화 전
문제 사례
  • "Tailscale이 설치되어 있지 않습니다" (실제로는 설치됨)
  • 공인 IP SSH 접속 안내 (보안 정책 위반)
  • 개발 서버를 0.0.0.0으로 실행 안내
  • 추측 기반 상태 보고
✅ 개인화 후
동작 변화
  • 스크립트 실행 → 정확한 Tailscale IP 응답
  • 항상 Tailscale SSH 명령으로 안내
  • 개발 서버는 자동으로 127.0.0.1 바인딩 안내
  • 실제 상태 기반 응답
핵심 요약
OpenClaw는 "똑똑한 AI"가 아니라 "잘 정의된 시스템"입니다. 환경을 정의하고, 규칙을 강제하고, 상태를 직접 확인하게 만들면 — 개인 환경에 최적화된 AI 엔지니어로 동작합니다.
🔁
자동화된 판단 체크리스트:
OpenClaw가 실행 명령을 안내하기 전에 스스로 확인해야 할 것들:
1. 공인 IP가 포함되는가? → YES면 실행 금지
2. 외부에서 접근 가능한가? → YES면 localhost로 바꿔 안내
3. 인증 없이 접근 가능한가? → YES면 경고 후 진행

🎉 전체 과정 완료! Ch.01부터 Ch.10까지 — 맥미니 초기 세팅, OpenClaw 설치, tmux 운영, Telegram 연결, 프로젝트 구조, 파일 공유, 그룹 운영, 보안 구성, 개인화까지 전체 시스템이 완성되었습니다.

11. Gmail 발송 자동화 (SMTP 설정하기)

이 장에서는 OpenClaw 운영 환경에서 Gmail SMTP 기반 이메일 발송 자동화를 구축합니다. 결과 파일을 매번 SMB 폴더를 열어 꺼내는 방식에서, "결과가 나에게 오는 구조"로 전환합니다.

왜 이메일 자동화가 필요한가

💥
반복되는 불편함: OpenClaw가 결과 파일을 만들었는데, 확인하려면 매번 SMB 접속 → 폴더 열기 → 파일 다운로드가 필요합니다. 외부 환경에서는 더 불편합니다.

기존 방식의 문제:

  • 매번 SMB 접속 필요
  • 외부 환경에서 불편
  • 즉시 확인 어려움
📱 Telegram 명령
    ↓
🦞 OpenClaw 실행 → 결과 생성
    ↓
📧 이메일 자동 발송
    ↓
📬 사용자 수신

👉 "결과를 내가 가져오는 구조 → 결과가 나에게 오는 구조"로 전환

시크릿 관리 구조

이메일 자동화에는 Gmail 계정과 앱 비밀번호가 필요합니다. 이 민감 정보는 프로젝트 폴더나 코드 안에 직접 넣지 않고, 중앙 시크릿 저장소에 모아서 관리합니다.

~/.openclaw/secrets.json — 중앙 시크릿 저장소
{
  "gmail": {
    "account": "your-email@gmail.com",
    "appPassword": "xxxx xxxx xxxx xxxx"
  },
  "anthropic": { "apiKey": "sk-ant-..." },
  "gemini": { "apiKey": "AIza..." }
}

파일을 만들고 나면 반드시 권한을 제한합니다:

파일 권한 설정
$ chmod 600 ~/.openclaw/secrets.json
$ ls -l ~/.openclaw/secrets.json
-rw------- (소유자만 읽기/쓰기 가능)
⚠️
운영 원칙:
• 모든 시크릿의 원본은 secrets.json 한 곳에만 저장
• 스크립트는 값을 하드코딩하지 않고 secrets.json을 참조만 함
• 채팅(Telegram 등)으로 비밀번호를 전달하지 않음
secrets.json을 Git에 포함하지 않음

Gmail SMTP 설정

Gmail SMTP를 앱 비밀번호로 사용하려면 Google 계정에 2단계 인증이 켜져 있어야 합니다. 일반 계정 비밀번호를 그대로 사용하는 것은 보안상 허용되지 않습니다.

1
Google 계정 2단계 인증 켜기

Google 계정 → 보안 → Google에 로그인하는 방법 → 2단계 인증 활성화

2
앱 비밀번호 생성

직접 접속: myaccount.google.com/apppasswords

앱 이름 입력 예시: OpenClaw Mac mini SMTP

→ 16자리 앱 비밀번호 생성됨 (그 순간에만 표시되므로 바로 복사·저장)

3
secrets.json에 저장

생성된 앱 비밀번호를 ~/.openclaw/secrets.jsongmail.appPassword에 입력합니다.

값은 채팅으로 전달하지 않고 Mac mini에서 직접 편집합니다:

Mac mini에서 직접 편집
$ nano ~/.openclaw/secrets.json

Gmail SMTP 기본 정보:

항목
SMTP 서버smtp.gmail.com
포트465 (SSL)
인증 방식앱 비밀번호 (일반 비밀번호 사용 금지)
사용자명Gmail 전체 주소

공통 발송 스크립트

한 번만 만들어두고 계속 쓰는 공통 스크립트입니다. ~/openclaw/scripts/send-email.py에 위치하며, HTML 이메일과 첨부파일 두 가지 케이스를 모두 처리합니다.

~/openclaw/scripts/send-email.py — 핵심 구조
import smtplib, json, argparse
from email.message import EmailMessage
from pathlib import Path
 
# secrets.json 에서 계정 정보 로드
secrets = json.loads((Path.home() / ".openclaw/secrets.json").read_text())
EMAIL = secrets["gmail"]["account"]
PASSWORD = secrets["gmail"]["appPassword"]
 
with smtplib.SMTP_SSL("smtp.gmail.com", 465) as smtp:
    smtp.login(EMAIL, PASSWORD)
    smtp.send_message(msg)

케이스 1 — HTML 이메일 (제안서, 소개서 등):

HTML 파일을 이메일 본문으로 발송
$ python3 ~/openclaw/scripts/send-email.py \
  --to "gildong@company.com" \
  --subject "2024년 교육 제안서" \
  --html /path/to/proposal.html

케이스 2 — 파일 첨부 발송:

파일 첨부해서 발송
$ python3 ~/openclaw/scripts/send-email.py \
  --to "cs@company.com" \
  --subject "월간 리포트" \
  --body "첨부 파일 확인 부탁드립니다" \
  --attach report.xlsx

OpenClaw에게 지시하는 방식:

Telegram으로 이메일 지시 예시
"proposal.html을 홍길동(gildong@company.com)에게 보내줘, 제목은 '2024년 교육 제안서'"
 
"report.xlsx를 김철수(cs@company.com)에게 보내줘, 제목은 '월간 리포트', 본문은 '첨부 파일 확인 부탁드립니다'"

활용 사례

1
HTML 제안서 발송

HTML로 완성된 제안서·소개서를 이메일 본문에 완전히 시각화해서 발송합니다. 수신자는 별도 파일을 열지 않고 메일 본문에서 바로 확인합니다.

proposal.html → 이메일 본문 → 발송

이처럼 HTML로 서식을 갖춰 발송하는 이메일을 HTML 이메일 (Rich Email)이라고 합니다. 일반 텍스트만 있는 Plain Text Email과 구분됩니다.

2
리포트 파일 첨부 전달

OpenClaw가 생성한 결과물(Excel, PDF, 로그 등)을 이메일에 첨부해서 바로 전달합니다. SMB 폴더를 열 필요가 없습니다.

outputs/report.xlsx → 첨부 → 발송
3
작업 완료 자동 알림

OpenClaw가 긴 작업을 마치면 자동으로 완료 메일을 보냅니다. Telegram = 작업 입력, 이메일 = 결과 수신으로 채널을 분리합니다.

작업 완료 → send-email.py 호출 → 메일 발송
4
에러 로그 자동 전송

서버에서 에러가 발생하면 로그 파일을 첨부해서 자동으로 알립니다.

에러 발생 → logs 첨부 → 발송

최종 구조 정리

🔐 secrets.json (계정 + 앱 비밀번호)
    ↓
🐍 send-email.py (공통 발송 스크립트)
    ↓
📡 Gmail SMTP (smtp.gmail.com:465)
    ↓
📬 수신자 Gmail
이메일 자동화 전 vs 후
😕 자동화 전
불편했던 점
  • 결과 확인마다 SMB 접속
  • 외부 환경에서 파일 접근 불편
  • 즉시 확인 어려움
  • 작업 완료 알림 없음
✅ 자동화 후
바뀐 점
  • 결과가 이메일로 자동 도착
  • 어디서든 Gmail로 확인
  • HTML 제안서도 본문에서 바로 확인
  • SMB 폴더 거의 안 열어도 됨
핵심 요약
secrets.json은 "비밀 저장소", send-email.py는 "전송 도구", OpenClaw는 "자동화 엔진"입니다. 이 세 가지가 연결되면 Telegram으로 지시하고 Gmail로 결과를 받는 완전한 자동화 파이프라인이 완성됩니다.
🛡️
보안 운영 원칙:
1. Gmail 일반 비밀번호 사용 금지 → 반드시 앱 비밀번호 사용
2. secrets.json을 Git에 포함하지 않음
3. 채팅으로 비밀번호를 전달하거나 요청하지 않음
4. openclaw.json에 평문으로 새어나온 값이 없는지 주기적으로 확인

🎉 Ch.11 완료! Gmail SMTP 연결, secrets.json 시크릿 관리, 공통 발송 스크립트까지 — OpenClaw에서 이메일로 결과를 자동 전달하는 파이프라인이 완성되었습니다.

12. GitHub + Vercel 연동

이 장에서는 Mac mini에서 GitHub SSH 연결을 구축하고, GitHub CLI와 Vercel CLI를 연동해 "Telegram 명령 → GitHub push → 배포" 자동화 파이프라인을 완성합니다.

전체 구조 이해

📱 Telegram (지시)
    ↓
🦞 OpenClaw
    ↓
🖥️ Mac mini (터미널 실행)
    ↓
🐙 GitHub (코드 저장)
    ↓
🚀 Vercel (배포)

👉 사람이 직접 하지 않고 명령으로 전체 흐름 실행 가능

Git 기본 설정

Git 사용자 정보 설정
$ git config --global user.name "이름"
$ git config --global user.email "GitHub 이메일"
💡
아무 반응 없음 = 성공
git config 명령은 성공해도 아무 출력이 없습니다. 에러 메시지가 없으면 정상 적용된 것입니다.

GitHub SSH 연결

1
SSH 키 생성
SSH 키 생성
$ ssh-keygen -t ed25519 -C "GitHub 이메일"
# 경로: Enter (기본값 ~/.ssh/id_ed25519)
# 패스프레이즈: 선택사항
2
키 구조 이해
파일 공개 여부 역할
id_ed25519.pub공개 가능GitHub에 등록
id_ed25519절대 비공개Mac mini에만 보관

공개키 = 자물쇠 / 개인키 = 열쇠. 자물쇠(공개키)는 누가 봐도 괜찮습니다.

3
공개키 확인 후 GitHub 등록
공개키 확인
$ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3... your@email.com

출력된 내용 전체를 복사해서 GitHub에 등록합니다:

GitHub → Settings → SSH and GPG keys → New SSH key

Title: Mac mini / Key: 복사한 공개키 붙여넣기

4
연결 테스트
SSH 연결 확인
$ ssh -T git@github.com
Hi 계정명! You've successfully authenticated

이 메시지가 나오면 완료. 이제 OpenClaw가 git push, git pull 등 모든 Git 명령을 실행할 수 있습니다.

⚠️
민감 정보 보호: push 전에 .env, secrets.json.gitignore에 포함되어 있는지 반드시 확인합니다. OpenClaw가 자동으로 체크합니다.

GitHub CLI (gh)

SSH 연결만으로는 기존 repo에 push/pull이 가능하지만, 새 repo 생성은 GitHub CLI(gh)가 있어야 터미널에서 바로 할 수 있습니다.

1
gh 로그인
gh auth login
$ gh auth login
# 1. GitHub.com 선택
# 2. SSH 선택
# 3. Login with a web browser 선택
2
헤드리스 환경 대응

Mac mini는 브라우저가 없는 환경이라 자동으로 브라우저가 열리지 않습니다. 터미널에 one-time code가 표시됩니다.

터미널 출력 예시
First copy your one-time code: XXXX-XXXX
Open: https://github.com/login/device

👉 Windows 브라우저에서 https://github.com/login/device 접속 후 코드 입력

로그인 완료 후 OpenClaw에게 다음과 같이 지시할 수 있습니다:

Telegram 지시 예시
"repo 만들어줘"
"future-me 프로젝트 push해줘"

Vercel 연동

1
Vercel CLI 로그인
vercel login
$ vercel login
# Continue with GitHub 선택
# gh와 동일하게 device code 방식으로 인증
2
인증 정보 저장 위치

로그인 완료 후 인증 정보는 Mac mini에 자동 저장됩니다. secrets.json에 별도로 저장할 필요 없습니다.

인증 정보 저장 위치
GitHub CLI : ~/.config/gh/hosts.yml
Vercel : ~/.local/share/com.vercel.cli/auth.json
💡
Google 계정 연결 불필요: Vercel을 GitHub 계정으로 가입했다면 추가 연결은 필요 없습니다. Google 계정이 필요한 경우는 Google Analytics, Firebase 연동 때뿐입니다.

최종 배포 흐름

✍️ 코드 작성/수정
    ↓
📤 git push
    ↓
🚀 vercel --prod
    ↓
🌐 배포 URL 생성

Telegram에서 이렇게 지시하면 됩니다:

배포 지시 예시
"future-me 배포해줘"
"openclaw-textbook 배포해줘"
"프로젝트 push해줘"
GitHub + Vercel 연동 전 vs 후
😕 연동 전
수동 작업
  • GitHub 웹 UI에서 직접 업로드
  • Vercel 대시보드에서 수동 배포
  • 매번 브라우저 열기 필요
  • Mac mini 앞에 있어야 함
✅ 연동 후
자동화
  • Telegram 한 줄로 push + 배포
  • OpenClaw가 전체 실행
  • 어디서든 원격 지시 가능
  • 민감 정보 자동 보호
핵심 요약
SSH 연결 → Git 자동화 / gh CLI → repo 생성 자동화 / Vercel CLI → 배포 자동화. 이 세 가지가 연결되면 Telegram → OpenClaw → GitHub → Vercel 전체 파이프라인이 완성됩니다.

🎉 Ch.12 완료! GitHub SSH 연결, GitHub CLI, Vercel CLI까지 — 코드 작성부터 배포까지 Telegram 한 줄로 실행하는 자동화 파이프라인이 완성되었습니다.