본문으로 건너뛰기

© 2026 Molayo

HN요약2026. 05. 20. 02:30

나의 Claude Code 설정: 순수 CLI, 순수 Unix, IDE 없음

요약

작성자는 Raspberry Pi 5와 Debian 환경에서 tmux와 SSH를 활용하여 Claude Code를 구축한 독특한 CLI 중심의 개발 환경을 소개합니다. 별도의 IDE나 Docker 없이 순수 Unix 철학을 바탕으로 기기 간 완벽한 세션 로밍과 SSH 에이전트 관리를 구현했습니다.

핵심 포인트

  • tmux를 활용하여 모바일, 태블릿, 노트북 등 다양한 기기에서 끊김 없는 세션 로밍 구현
  • Debian 기반의 Raspberry Pi 5를 서버로 활용하는 경량화된 개발 스택 구축
  • systemd와 SSH agent를 결합하여 Claude Code가 별도의 포워딩 없이도 Git 및 서버 접근이 가능하도록 설정
  • 편의성을 위해 SSH 키를 서버에 저장하는 방식의 보안 트레이드오프 주의 필요

이 글은 제가 지금 이 포스트를 작성하고 있는 모습입니다. 제 휴대폰으로, SSH를 통해, 아마도 욕조 안에서 말이죠.

Claude Code는 CLI (Command Line Interface) 도구입니다. 터미널에서 실행되죠. 제가 듣고 싶었던 말은 그게 전부였습니다.

설정 (The setup)

집에는 Debian Trixie가 실행 중인 Raspberry Pi 5가 있습니다. 이름은 nowhere입니다 (긴 이야기가 있습니다). Claude Code는 그곳의 tmux 내부에서 24시간 7일 내내 실행됩니다. 저는 SSH로 접속하여 다시 연결(reattach)함으로써 휴대폰, 태블릿, 노트북 등 어떤 기기에서도 이에 접근할 수 있습니다:

ssh nowhere
tmux -u at

그게 끝입니다. 두 개의 명령어로 제가 작업을 멈췄던 바로 그 지점으로 돌아갑니다. -u 플래그는 유니코드(Unicode) 지원(상태 줄의 이모지, 박스 그리기 문자)을 활성화하며, atattach -t 0의 약어입니다. 세션은 연결 끊김, 클라이언트 기기의 재부팅, 네트워크 전환 등 모든 상황에서도 유지됩니다. 노트북에서 작업을 시작하고, 산책하는 동안 휴대폰으로 이어서 하며, 소파에 앉아 태블릿으로 마무리할 수 있습니다.

기기 간의 완벽한 세션 로밍(session roaming)입니다. 상태 손실은 전혀 없습니다. 단 한 번도요.

살아있는 Unix 철학 (The Unix philosophy, alive and well)

아래에서 위로 쌓아 올린 스택은 다음과 같습니다:

Debian Trixie(aarch64) — 제 팔에 Debian 문신이 있고, 이 시점에서는 일종의 헌신이기 때문입니다.
systemd user unit (ssh-agent용) — 로그인 시 시작되며, 소켓 활성화(socket-activated) 방식이고 예측 가능합니다.
SSH_AUTH_SOCK 위치: /run/user/1000/openssh_agent
tmux — 멀티플렉서(multiplexer), 세션 유지, 스크롤백(scrollback), 복사-붙여넣기, 창 관리.
Claude Code — 실제 작업을 수행하는 AI.
SSH — 범용 전송 프로토콜.

Docker도 없습니다. Kubernetes도 없습니다. VS Code remote tunnels도 없습니다. 클라우드 IDE도, Electron도 없습니다. 오직 Unix뿐입니다.

SSH agent 트릭

에이전트(agent)는 systemd에 의해 관리되며, 소켓 경로는 .bashrc에 하드코딩되어 있습니다:

export SSH_AUTH_SOCK="${XDG_RUNTIME_DIR}/openssh_agent"

이것은 tmux 내부의 쉘(shell) 안에서 실행되는 Claude Code가 자동으로 제 SSH 키에 접근할 수 있음을 의미합니다. 에이전트 포워딩(agent forwarding) 없이도 git push를 하거나, 제 서버로 ssh 접속을 하고, 스테이징(staging) 및 운영(prod) 환경에 배포할 수 있습니다. 키는 Pi에 저장되어 있고, 에이전트는 항상 실행 중이며, 모든 쉘(Claude의 쉘 포함)이 소켓 경로를 상속받습니다.

-A 옵션도 필요 없습니다.

클라이언트 측에서 필요한 플래그가 아닙니다. Pi 자체가 에이전트(agent)입니다.

주의 사항 (이 점을 지적해 준 Yaroslav에게 감사드립니다):
이는 편의성을 위한 트레이드오프(trade-off)입니다. 키(keys)가 Pi에 저장되어 있다는 것은, 만약 해당 기기가 해킹당할 경우 공격자가 그 키로 잠금 해제할 수 있는 모든 것에 접근할 수 있음을 의미합니다. 더 보안이 강화된 접근 방식은 터미널 세션에서 에이전트를 포워딩(ssh -A 사용)하고, 물리적으로 제어할 수 있는 장치의 비밀번호로 보호된 저장소에서 필요할 때마다 키를 로드하는 것입니다. 저는 포워딩 전용 키(forwarded-only keys)로 전환하는 것을 고려 중입니다. 현재 설정이 작동하는 이유는 Pi가 인터넷에 노출되어 있지 않고 인터넷에 연결된 어떤 서비스로부터도 명령을 받을 수 없기 때문이지만, 심층 방어(defense in depth)가 항상 더 나은 선택입니다.

tmux: 진정한 IDE

저의 tmux 설정은 Ctrl-F를 프리픽스(prefix) 키로 사용하며(미안해, find, 넌 이제 끝이야), 설명적인 라벨이 붙은 여러 개의 윈도우(window)를 유지합니다:

0:sysadm 1:gastone 2:sindrome 3:gastone-logs

각 윈도우는 하나의 프로젝트입니다. 각 프로젝트에는 Claude Code가 실행 중입니다. ^F 0, ^F 1 등을 사용하여 윈도우 사이를 전환할 수 있습니다. 로그, htop, 또는 필요할 때 병렬 쉘을 위한 분할 창(split panes)도 사용합니다.

이 워크플로우의 핵심 기능은 다음과 같습니다:

스크롤백 (Scrollback)Shift-PageUp을 누르면 복사 모드(copy mode)로 진입합니다. Claude의 출력물, 터미널 로그, 빌드 결과물 등 수천 줄의 내용을 스크롤하며 살펴볼 수 있습니다. history-limit은 10,000줄로 설정되어 있습니다.
복사 및 붙여넣기 (Copy-paste)—vi 키 바인딩(keybindings)을 지원하는 tmux의 내장 복사 모드를 사용합니다. 선택(select), 얀크(yank), 붙여넣기(paste)를 수행합니다. 마우스가 필요 없습니다 (물론 가끔 게으르게 스크롤하고 싶을 때를 위해 마우스 모드는 켜두었습니다).
창 동기화 (Pane sync)^F Ctrl-Y는 모든 창에 동기화된 입력(synchronized input)을 토글합니다. 분할된 뷰에서 동일한 명령어를 실행할 때 유용합니다.

WireGuard: 원활한 이동성

저는 모든 기기에 WireGuard VPN을 온디맨드(on-demand) 방식으로 구성해 두었습니다. 집 WiFi를 사용할 때는 트래픽이 LAN을 통해 직접 전달됩니다. 집 밖으로 나가면 WireGuard가 자동으로 작동하여 저를 집으로 터널링(tunneling)해 줍니다.

이제 엔드포인트(endpoint)가 로컬 LAN IP에서 VPN IP로 전환될 때 SSH 연결이 끊어지기는 합니다. TCP는 그런 상황에서 유지되지 않기 때문입니다. 하지만 상관없습니다. Termius에서 “Start over”를 누르면 연결이 1초 만에 재설정되고, tmux -u at을 입력하면 바로 이전 상태로 돌아갑니다. tmux 세션은 어디에도 가지 않고 그대로 남아 있습니다. 전체 왕복 시간은 단 3초입니다.

노트북의 ~/.ssh/config와 Termius에 저장된 연결 정보는 모두 Raspberry Pi의 로컬 LAN IP를 사용합니다. WireGuard는 제가 물리적으로 어디에 있든 상관없이 라우팅(routing)을 처리합니다. 거실에 있든 카페에 있든, 동일한 IP와 동일한 연결을 사용합니다.

휴대폰 설정¶

iOS에서는 Termius(무료 버전)를 사용합니다. nowhere로 연결을 저장하고, SSH 키를 가져오면 끝입니다. 핵심적인 요령은 Ctrl-F(저의 tmux 프리픽스(prefix))를 키보드 위의 버튼에 매핑한 것입니다. 이를 통해 휴대폰에서도 창 전환, 창 분할(splitting panes), 복사 모드(copy mode) 진입 등 tmux의 모든 기능을 완전히 제어할 수 있습니다.

스크롤도 아주 잘 작동합니다. Termius가 터치 이벤트를 스크롤로 변환해주기 때문에, 손가락으로 Claude의 출력 내용을 위아래로 쓸어 넘기기만 하면 됩니다. 매우 자연스럽게 느껴집니다.

이 워크플로우에서 휴대폰은 놀라울 정도로 사용하기 좋습니다. 휴대폰으로 코드를 작성하는 것은 아니지만(그건 Claude가 합니다), diff를 검토하고, 도구 호출(tool calls)을 승인하며, 빌드 출력(build output)을 읽고, 스테이징(staging) 상태를 확인하며, Claude에게 지침을 내릴 수 있습니다. 어차피 제가 하는 일의 90%는 이런 것들입니다.

그리고 휴대폰 타이핑에 대해 한 가지 말씀드리자면, 저는 말도 안 될 정도로 많은 오타를 냅니다. 위의 스크린샷을 보세요. 저 프롬프트는 오타투성이입니다. 하지만 상관없습니다. LLM(대규모 언어 모델)은 본질적으로 퍼지 매칭(fuzzy matching)을 수행합니다. 이들은 키스트로크(keystrokes)가 아니라 의도를 파악합니다. “stsging”은 “staging”이고, “tge”는 “the”이며, “donMr”는 “don’t”입니다. Claude는 눈 하나 깜빡하지 않습니다. 이는 보통 마찰(friction)의 악몽이 될 수 있는 요소들(작은 키보드, 굵은 손가락, 방해하는 자동 수정 기능)을 아무런 문제가 되지 않게 만듭니다. 빠르게 타이핑하고, 수정하지 않아도 그냥 작동합니다. 오타는 워크플로우의 버그가 아니라 하나의 *기능(feature)*이 됩니다.

왜 mosh를 쓰지 않나요?¶

Andrei는 저에게 mosh를 시도해 보라고 제안했습니다. mosh는 IP 변경이나 연결 끊김 상황에서도 세션을 유지하며 살아남는 UDP 기반의 모바일 셸(mobile shell)입니다. 이러한 로밍(roaming) 워크플로우에 아주 자연스럽게 어울리는 도구이기에, 저도 한 번 시도해 보았습니다.

결정적인 결함(deal-breaker)은 mosh가 스크롤백(scrollback)이나 마우스 이벤트를 지원하지 않는다는 점입니다. mosh는 2012년부터 설계된 방식에 따라 로우 바이트(raw bytes)를 스트리밍하는 대신 화면 상태를 동기화하는 방식으로 작동합니다. 이는 Termius에서 터치 스크롤(touch-to-scroll) 기능을 사용할 수 없음을 의미하며, 저는 휴대폰에서 Claude의 출력물, 빌드 로그, 디프(diff)를 읽을 때 이 기능을 사용합니다. 모바일 워크플로우의 핵심은 손가락으로 수백 줄의 터미널 출력을 스와이프하며 읽는 것인데, mosh는 그 기능을 망가뜨립니다.

실제로 연결이 끊기는 일은 드뭅니다. WireGuard는 VPN 링크를 유지하는 데 매우 효율적이며, 덕분에 백그라운드 상태의 Termius가 TCP keepalive를 계속 보내 SSH 연결을 유지할 수 있게 해줍니다. 연결이 끊기는 유일한 경우는 엔드포인트 전환(LAN ↔ VPN) 시뿐이며, 이때는 3초의 시간과 두 번의 명령어가 소요됩니다. 전체 터치 스크롤백 기능을 유지하기 위해서라면 기꺼이 지불할 용의가 있는 세금(tax)입니다.

결과¶

지난 30일 동안 저는 십여 개의 프로젝트에 걸쳐 **5,000개 이상의 커밋(commits)**을 수행했습니다. 이 모든 것은 현재의 설정으로 이루어졌습니다:

  • 이 블로그를 완전히 개편했습니다 — 69개의 포스트를 번역하고, 레이아웃을 재설계했으며, 부트 시퀀스 이스터 에그(Easter egg)를 추가했습니다. IDE도, Figma도, 디자인 도구도 사용하지 않았습니다. 오직 Claude Code와 시각적 작업을 위한 Superpowers 라이브 프리뷰(live preview)만 사용했습니다.
  • Verisure Italy를 위한 커스텀 Home Assistant 통합 기능을 구축했습니다 — 그들의 GraphQL API를 역공학(reverse-engineered)하고, 전체 Python 컴포넌트를 작성하여 PyPI에 게시했습니다.
  • OpenWrt 메시 네트워크 분석기인 WiFi Dethrash를 제작했습니다.
  • Home Assistant를 위한 WiFi 존재 감지(presence detection) 시스템을 작성했습니다.
  • OpenWrt를 위한 5G 모뎀 도구들을 구축했습니다.
  • 전체 인리치먼트 파이프라인(enrichment pipeline)을 통해 2년 치의 로그를 백필(backfill)했습니다.

이 모든 작업은 단 하나도 빠짐없이 터미널에서 수행되었습니다. CSS, Python, Go, Lua, 셸 스크립트(shell scripts), Hugo 템플릿, nginx 설정, systemd 유닛, 커널 인접 네트워킹 코드까지. 명령줄(command line)에서 처음부터 끝까지 전체 스택(full stack)을 다루었습니다.

이것이 작동하는 이유¶

핵심은 Claude Code에게 IDE가 필요하지 않은 이유가 바로 그 자체가 IDE이기 때문이라는 통찰입니다. Claude Code는 파일을 읽고, 수정하고, 테스트를 실행하고, 빌드 결과(build output)를 확인하며, 반복(iterate)합니다. 터미널(terminal)은 Claude Code의 타고난 서식지입니다. 그 위에 그래픽 계층(graphical layer)을 추가하는 것은 도움이 되지 않으며, 오히려 방해가 됩니다.

그리고 tmux는 현대적인 IDE의 "워크스페이스 (workspace)" 개념이 제공하는 모든 것—지속적인 세션(persistent sessions), 다중 컨텍스트(multiple contexts), 검색 가능한 히스토리(searchable history), 창 레이아웃(pane layouts)—을 불필요한 기능(bloat) 없이 제공하기 때문에 완벽한 동반자입니다.

저는 1988년 Olivetti Prodest PC1—8088 기반—에서 QBasic으로 프로그래밍을 시작했습니다. 당시 저는 일곱 살이었고, 80x25 앰버 터미널(amber terminal)을 응시하며 그것이 세상에서 가장 마법 같은 것이라고 생각했습니다. 그 후 업계는 지난 35년 동안 저에게 GUI, 마우스, IDE, 시각적 디버거(visual debuggers), 포인트 앤 클릭 배포 도구(point-and-click deployment tools)가 필요하다고 설득해 왔습니다. 이제 AI는 저를 다시 터미널과 키보드, 그리고 제가 원하는 것을 평이한 언어로 설명할 수 있는 능력으로 되돌려 놓았습니다.

저는 다시 원점으로 돌아왔으며, 컴퓨터를 다루며 이보다 더 행복했던 적은 없었습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 HN OpenAI Codex의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0