shellbase
v0.16.0
Published
내 컴퓨터 터미널(특히 Claude Code 세션)을 폰 브라우저로 실시간 접속하게 해주는 데스크톱 에이전트
Downloads
980
Maintainers
Readme
shellbase
내 컴퓨터 터미널(특히 Claude Code 세션)을 폰 브라우저로 실시간으로 보고 조작할 수 있게 해주는 데스크톱 에이전트입니다.
설치
Node.js 22 이상이 필요해요 (실시간 접속 기능이 Node 의 최신 WebSocket 기능을 써요 — 20 이하면
shellbase start 가 바로 에러 메시지를 보여주고 멈춰요). node --version 으로 확인해보세요.
npm install -g shellbase사용법
# 구글 계정으로 로그인 (처음이면 자동으로 가입도 됨)
shellbase login
# 지금 폴더에서 터미널 세션 시작
shellbase start
# 다른 폴더에서 시작하고 싶으면
shellbase start --dir ~/projects/my-app --name "내 노트북"shellbase start 를 실행한 뒤 shellbase.web.connectbase.world
에 같은 계정으로 접속하면 내 데스크톱 목록에 뜹니다. 선택하면 데스크톱에 접속 승인 알림이 뜨고,
승인하면 폰에서 그대로 타이핑할 수 있어요.
명령어
| 명령어 | 설명 |
|---|---|
| shellbase login | 구글 계정으로 로그인 |
| shellbase logout | 로그아웃 |
| shellbase whoami | 현재 로그인된 계정 확인 |
| shellbase start [--dir <path>] [--name <name>] [--require-approval] [--no-restore] [--no-hook] | 터미널 세션 시작 |
| shellbase hook install / remove / status | Claude Code 작업 완료 알림 켜기/끄기/확인 |
| shellbase notify | "작업이 끝났다"고 폰에 알림 (Claude Code 훅이 자동 실행 — 직접 칠 일은 없어요) |
작업이 끝나면 폰으로 알려줘요
Claude Code 에게 긴 작업을 시켜놓고 폰을 내려놓아도, 끝나면 알 수 있어요.
- 폰·PC 의 세션 목록과 상단 칩에 주황 점(●) 이 붙어요 — 그 세션에 들어가 보면 사라집니다
- 앱을 열어둔 상태라면 알림창도 띄울 수 있어요 (명령창
Ctrl+Shift+P→ "작업 완료 알림 켜기") - 앱을 아예 닫아둔 사이에 끝난 작업도 ● 로 남아 있어서, 나중에 열어보면 바로 보여요
끝난 걸 알아채는 방법은 두 가지고, 정확한 쪽이 우선입니다.
| 방법 | 정확도 | 준비 |
|---|---|---|
| Claude Code 훅 | 정확 (Claude 가 대답을 마치는 바로 그 순간) | shellbase hook install 한 번 |
| 화면 출력 보고 짐작 | 어림짐작 | 없음 (훅이 없을 때 자동으로 대신 씀) |
shellbase start 를 처음 실행하면 훅을 걸지 한 번 물어봐요. y 를 누르면
~/.claude/settings.json 에 알림 한 줄이 들어갑니다 — 원래 있던 설정은 그대로 두고, 고치기 전
같은 자리에 settings.json.shellbase-backup 으로 백업도 남겨요. 이미 켜져 있던 Claude Code 는 다시
시작해야 적용돼요.
shellbase hook status # 지금 걸려 있는지 확인
shellbase hook install # 걸기
shellbase hook remove # 빼기 (다른 설정은 안 건드려요)
shellbase start --no-hook # 물어보지 않고 시작훅이 없을 때 쓰는 짐작 방식은 "한동안 화면이 쉼 없이 바쁘다가(3초 이상, 글자 2KB 이상) 갑자기
4초간 조용해지면 끝난 것" 으로 봅니다. 그래서 ls 처럼 짧은 명령이나 타이핑에는 반응하지 않지만,
Claude Code 가 아닌 긴 명령(빌드 등)이 끝나도 알림이 올 수 있어요.
접속 승인 정책
기본은 "내 계정으로 로그인했으면 바로 입력 가능" 입니다. 이 도구의 보안 경계는 ConnectBase 계정(구글 로그인)이에요 — 터미널 화면은 원래부터 계정 주인만 볼 수 있었고(세션 키가 내 계정만 읽을 수 있는 자리에 있어요), 화면만 봐도 민감한 내용은 다 보이기 때문에 "보기는 되고 타이핑만 막기"는 실익이 크지 않았습니다. 화면 앞에 사람이 없는 서버·도커에서는 승인할 방법 자체가 없기도 했고요.
노트북처럼 한 단계 더 두고 싶다면 --require-approval 로 예전처럼 매번 이 컴퓨터에서 y 를 눌러야
입력이 되게 할 수 있어요.
shellbase start --require-approval여러 세션을 한 프로세스가 관리해요
shellbase start 를 한 번 실행하면 프로세스 하나가 뜨고, 그 안에서 터미널(세션)을 여러 개 관리해요.
폰에서 + 새 세션 으로 늘려도 프로세스는 그대로 하나입니다.
- 세션 2개 기준 메모리 약 85MB (예전엔 세션마다 프로세스를 띄워서 200MB였어요)
- 실시간 연결도 세션 수와 무관하게 1개만 사용해요
- 프로젝트마다 세션을 하나씩 켜두고 폰 상단 칩으로 왔다갔다 하면 됩니다
Ctrl+C를 누르면 그 프로세스의 모든 세션이 함께 정상 종료돼요 (열려 있던 목록은 기억해둬요 — 아래 참고)- 터미널을 새로 열어
shellbase start를 또 실행해도 됩니다 (프로세스가 하나 더 생기고, 이미 켜져 있는 세션을 중복으로 복구하지는 않아요)
재시작하면 세션이 자동으로 돌아와요
열려 있던 세션 목록은 ~/.shellbase/open-sessions.json 에 기록돼요. 컴퓨터·컨테이너가 재시작되거나
Ctrl+C 로 껐다가 shellbase start 를 다시 실행하면, 그때 열려 있던 세션들을 자동으로 다시 띄워요.
shellbase start # 이전 세션들도 함께 복구
shellbase start --no-restore # 복구하지 않고 이 폴더 세션 하나만- 폰에서 일부러 끈 세션은 복구 대상에서 빠져요 (다시 열리지 않아요)
- 폴더가 사라졌거나, 이미 켜져 있는 세션은 조용히 건너뜁니다
폰에서 세션 열기 · 전환 · 끄기 (컴퓨터에 손 안 대고)
세션이 하나라도 켜져 있으면, 그다음부터는 폰에서 전부 할 수 있어요.
| 하고 싶은 것 | 폰에서 하는 법 |
|---|---|
| 세션 하나 더 열기 | 목록 화면의 + 새 세션, 또는 터미널 화면의 기기 이름(▾) → + 이 컴퓨터에서 새 세션 열기 (열리면 그 세션으로 바로 넘어가요) |
| 잠깐 쓸 터미널 열기 | 터미널 화면 위쪽의 + 임시 터미널 — 지금 폴더에 하나 더 띄워요 (목록에 안 남고, 나가면 사라져요) |
| 세션 갈아타기 | 터미널 화면 위쪽의 기기 이름(▾) 탭 → 원하는 세션 선택 |
| 세션 끄기 | 목록의 전원 아이콘, 또는 터미널 화면의 기기 이름(▾) → 이 세션 끄기 |
| 화면만 닫기 | ← 목록 으로 나가기 — 컴퓨터의 세션은 계속 살아있어요 |
| 파일 열어보기·고치기 | 📁 폴더 찾기 → 목록에서 파일을 탭하면 에디터가 열려요 (수정 후 저장) |
| 세션 이름 바꾸기 | 기기 이름(▾) → 세션 옆 연필 버튼 |
- 끄기는 진짜로 꺼요. 컴퓨터에서 돌아가던 그 터미널이 종료되고 목록에서도 자동으로 사라져요
(
Ctrl+C를 누른 것과 같아요). 프로세스가 죽었는데 목록에만 남아있는 항목은 휴지통 아이콘으로 지울 수 있어요 — 그건 목록만 정리하는 버튼이에요. - 남의 세션은 열거나 끌 수 없어요. 요청을 보낸 쪽이 그 세션의 암호화 키를 가지고 있는지 먼저 확인하는데, 그 키는 내 계정으로만 읽을 수 있는 자리에 있거든요.
- 폰에서 연 세션도 같은 프로세스가 관리해요. 그래서 컴퓨터에서
Ctrl+C를 누르면 모든 세션이 함께 종료돼요(그 대신 다음 실행 때 자동 복구됩니다). 세션을 하나만 끄고 싶으면 폰에서 그 세션의✕를 쓰세요 — 나머지 세션은 그대로 유지돼요.
임시 터미널 (0.10.0+)
Claude Code 가 화면을 꽉 채우고 있을 때 git status 같은 걸 잠깐 쳐보려고 터미널을 하나 더 열곤 하는데,
그렇게 연 터미널이 목록에 계속 쌓이는 게 문제였어요. 터미널 화면 위쪽의 + 임시 터미널 로 연 것은
한 번 쓰고 버리는 터미널이에요.
- 세션 목록에도, 상단 칩 줄에도 안 보여요 (지금 보고 있는 동안만 칩으로 보입니다)
- 그 화면에서 나가면 스스로 종료돼요 — 다만 방금까지 뭔가 돌고 있었으면 끄지 않고 목록에 남깁니다 (하던 일이 조용히 사라지면 안 되니까요)
- 컴퓨터를 재시작해도 되살아나지 않아요 (정식 세션만 복구 대상)
- 브라우저를 그냥 닫아버린 경우엔, 아무도 안 보고 화면도 조용한 채로 5분이 지나면 컴퓨터가 알아서 정리해요
- 계속 쓰고 싶어지면
임시 · 계속 쓰기를 누르세요 — 정식 세션이 되고 이름의(임시)표시도 떨어져요 - 임시 터미널에는 Claude 자동 시작이 적용되지 않아요 (명령 하나 치려고 여는 것이라 빈 터미널로 열립니다)
파일 보기·편집
📁 폴더 찾기 목록에는 폴더와 함께 파일도 나와요. 파일을 탭하면 편집기가 열리고, 고친 뒤 저장 을
누르면 그 컴퓨터의 파일이 실제로 바뀝니다. 기기에 따라 편집기가 다르게 열려요:
노트북·데스크톱(넓은 화면 + 마우스): VS Code 와 같은 모나코 — 찾기·바꾸기(Ctrl+F), 커서 여러 개, 줄 접기, 미니맵,
Ctrl+S저장이 그대로 동작해요. 파일을 처음 열 때만 내려받습니다.폰: 가벼운 편집기(CodeMirror) — 터치 우선이라 좁은 화면에서 편하고,
Tab들여쓰기와Ctrl+S저장도 됩니다.모나코에서 JS/TS 타입 기반 자동완성은 빠져 있어요 (그 기능 파일 하나가 6.6MB 라 웹 스토리지 한도를 넘습니다). 색칠·단축키·검색은 모두 정상이에요.
512KB 까지, 글자 파일만 열려요 (사진·동영상은 아래의 보기 창으로 열립니다)
저장은 같은 폴더의 임시 파일에 먼저 쓴 뒤 교체해서, 저장 도중 끊겨도 원본이 깨지지 않아요
파일 내용은 터미널 화면과 똑같이 세션 키로 암호화해서 주고받아요
에디터는 파일을 처음 열 때만 따로 내려받아요 — 터미널만 쓰면 그만큼 안 받습니다
사진·동영상 보기 (0.14.0+)
폴더 찾기에서 사진(🖼)·동영상(🎬)·소리(🎵)·PDF(📕) 를 탭하면 편집기 대신 보기 창이 열려서 폰에서 그대로 보입니다. 동영상은 재생·되감기까지 돼요.
- 열리는 형식:
png jpg gif webp avif bmp heic tif·mp4 mov m4v webm mkv avi·mp3 m4a aac wav ogg opus flac·pdf - 64MB 까지, 그리고 3MB 가 넘으면 "받을까요?" 를 한 번 물어봐요 — 파일이 터미널 화면과 같은 통로로 오기 때문에, 큰 동영상을 잘못 누르면 그동안 터미널이 굼떠집니다
- 받는 동안 진행 막대가 보이고 그만두기를 누르면 곧바로 멈춰요 (컴퓨터 쪽도 바로 손을 뗍니다)
- 속도는 초당 300KB 남짓이에요 (실측) — 3MB 사진이면 10초쯤, 10MB 동영상이면 35초쯤
- 사진은 눌러서 원래 크기 ↔ 화면 맞추기를 오갈 수 있어요
- 파일은 32KB 조각으로 나눠 세션 키로 암호화해서 오고, 폰에서만 다시 하나로 붙습니다 — 중간에 저장되는 곳은 없어요
- 브라우저가 못 여는 형식(아이폰 밖에서의 HEIC, mkv·avi 등)은 그렇게 알려주고, 경로를
터미널에 넣어주는 버튼을 보여줘요 — 그 자리에서
ffmpeg로 바꾸면 됩니다
폰에서 사진·스크린샷 첨부 (0.7.0+)
폰 화면의 클립(📎) 버튼(PC 는 상단 바)으로 사진을 고르면, 사진이 이 컴퓨터의
~/.shellbase/images/ 에 파일로 저장되고 그 파일 경로가 터미널에 자동으로 입력됩니다.
이어서 "이 화면 좀 봐줘" 처럼 쓰고 엔터를 누르면 Claude Code 가 그 사진을 읽어요.
- 폰에서는 📎 버튼을 누르면 「사진 찍기 / 사진 보관함」이 함께 떠요 — 방금 찍은 스크린샷은 보관함에 있습니다
- PC 는 스크린샷 파일을 터미널 위로 끌어다 놓으면(드래그&드롭) 바로 첨부돼요 (📎 버튼은 폰 전용)
- 스크린샷을 복사해서 붙여넣기(Ctrl+V) 해도 첨부돼요 (PC·폰 공통)
- 사진은 보내기 전에 폰에서 긴 변 1568px 로 줄여서 올라가요(전송이 빠르고 인식 정확도는 그대로)
- 저장된 사진은 하루가 지나면 자동으로 지워져요, 파일 권한은 본인만 읽기(600)
- 사진도 터미널 화면과 똑같이 세션 키로 암호화해서 전송돼요
폰에서 마이크로 말하기 (음성 → 글자)
폰 화면 오른쪽 아래 마이크 버튼을 누르고 말하면 글자로 바뀝니다. 기본값은 말한 뒤 바로
보내기(엔터까지 자동) 라서, 「완료」만 누르면 그대로 실행돼요 (Claude Code 에게 말로 시킬 때
편합니다). 확인하고 보내고 싶으면 명령창의 말한 뒤 바로 보내기 끄기 로 예전 방식(받아쓴 글자를
보여주고 보내기 ↵ 를 누르는 방식)으로 바꿀 수 있어요.
받아쓰는 곳은 두 군데고, 준비된 쪽이 자동으로 쓰입니다. 폰 화면에 어느 쪽인지 표시돼요.
| | 내 컴퓨터에서 받아쓰기 | 브라우저가 받아쓰기 | |---|---|---| | 언제 | 이 컴퓨터에 음성인식 서버가 떠 있을 때 | 그 밖의 모든 경우 | | 준비 | 서버를 직접 띄워야 함 | 필요 없음 | | 목소리가 나가는 곳 | 안 나감 (내 컴퓨터에서 끝) | 브라우저 회사 서버 (크롬=구글, 사파리=애플) | | 품질 | 좋음 | 보통 |
- 음성인식 서버는 시작할 때 자동으로 찾아요:
SHELLBASE_STT_URL→http://127.0.0.1:5005→http://172.17.0.1:5005(도커 안에서 본 호스트) 순서 - 주소가 다르면
SHELLBASE_STT_URL=http://127.0.0.1:9000처럼 지정하고 다시 시작하세요. 인식 언어는SHELLBASE_STT_LANGS=ko,en으로 바꿀 수 있어요 (기본ko) - 일부러 브라우저 쪽을 쓰고 싶으면(또는 5005 포트를 다른 프로그램이 쓰고 있으면)
shellbase start --no-stt또는SHELLBASE_NO_STT=1 - 필요한 서버 형식:
GET /health와POST /transcribe_json({audio_base64, languages}→{ok, text}) — whisper 계열 서버면 대개 이 형태입니다
⚠️ 도커로 돌릴 때, 마지막 세션을 폰에서 끄면 도커가 다시 띄워요. 세션이 0개가 되면 프로세스가 종료되는데,
--restart unless-stopped는 정상 종료(exit 0)에도 컨테이너를 자동 재시작하기 때문이에요 (실제로 확인한 동작). 즉 마지막 세션 끄기는 사실상 재시작이 됩니다. 세션이 여러 개일 때 하나만 끄는 건 프로세스가 계속 살아있으니 그대로 꺼져요. 컨테이너를 완전히 내리려면 컴퓨터에서docker stop shellbase-agent를 쓰세요.
터미널은 셸 시작 파일(rc)을 읽습니다
폰에서 여는 터미널도 ~/.bashrc(zsh 는 ~/.zshrc) 같은 시작 파일을 그대로 읽습니다. 프롬프트,
ll 같은 줄임말, 시작 파일에서 늘려둔 PATH 가 컴퓨터 앞에 앉았을 때와 똑같이 나옵니다.
0.14.1 에서 되돌린 기본값입니다. 0.14.0 한 버전 동안만 반대로(읽지 않게) 동작했어요. 개인 별칭이 컨테이너에 딸려가 깨지는 문제(
bash: gnuls: command not found) 때문이었는데, 시작 파일은 PATH 를 늘리는 사실상 유일한 통로이기도 해서 대가가 훨씬 컸습니다 — 에이전트를 systemd 서비스나 런처로 띄운 컴퓨터에서는 물려받을 환경 자체가 최소 PATH 라,~/bin이나/usr/local/go/bin에 있는gh·go같은 명령이 폰에서 영영 안 보이게 됩니다. 0.14.0 을 쓰시다 프롬프트가bash-5.2$로 바뀌고 명령이 사라졌다면 0.14.1 로 올리세요.
일부러 개인 설정을 떼고 맨 셸로 띄우고 싶다면(여러 사람이 같은 홈 폴더를 공유하는 컨테이너 등)
SHELLBASE_NO_SHELL_RC=1 shellbase start … 로 켜세요. 그러면 bash --norc --noprofile,
zsh --no-rcs, fish --no-config, PowerShell -NoProfile 로 뜨고 프롬프트도 꾸밈 없는
기본값(bash-5.2$)이 됩니다. 이때는 에이전트를 켤 때의 환경변수(PATH 포함)만 물려받으므로,
필요한 경로는 에이전트를 켜는 쪽에 미리 넣어두세요.
참고
node-pty를 사용해서 설치 시 네이티브 모듈을 컴파일합니다. macOS는 Xcode Command Line Tools, Linux는build-essential(또는 배포판의 동급 패키지), Windows는 Visual Studio Build Tools가 필요할 수 있어요.- 폰이 (재)접속하면 지금 화면 그대로 복원돼요. 에이전트가 화면 상태를 따로 들고 있다가 그대로 보내주기 때문에, Claude Code 같은 전체화면 앱을 보다가 잠깐 끊겼다 돌아와도 화면이 깨지지 않아요 (이전 300줄까지 함께 복원).
- 터미널 내용은 기기별 키로 암호화돼서 전송되고, 모바일에서 접속을 시도할 때마다 데스크톱에서 직접 승인해야 입력이 가능합니다.
⚠️ shellbase start 는 컴퓨터가 꺼지거나 재부팅되면 같이 꺼져요
이건 각자의 컴퓨터에서 직접 관리해야 하는 부분입니다 — ShellBase 서비스가 대신 재시작해주지 않아요.
shellbase start 를 실행해둔 터미널을 닫거나, 컴퓨터를 껐다 켜거나, 프로세스가 죽으면 그 세션은
끝나고, 다시 접속하려면 직접 shellbase start 를 다시 실행해야 합니다.
컴퓨터가 꺼지지 않는 이상 자동으로 살아있게 하고 싶다면(예: 항상 켜져 있는 리눅스 서버), 아래처럼 OS의 자동 재시작 기능을 직접 설정하면 됩니다. 실제로 테스트해서 확인한 방법이에요:
Linux (systemd, 실제 검증됨) — 권장
도커로 감싸는 것보다 이 방법을 권합니다. 컨테이너 안에서는 그 터미널이 호스트의
docker·systemctl· 다른 컨테이너·호스트 서비스에 손을 댈 수 없어서, 정작 컴퓨터를 관리하려고 폰에서 접속했을 때 막힙니다. systemd 로 띄우면 재부팅 자동 복구는 똑같이 되면서 터미널 권한은 온전합니다.
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/shellbase.service << 'EOF'
[Unit]
Description=ShellBase desktop agent
After=network-online.target
[Service]
Environment=PATH=/usr/local/bin:/usr/bin:/bin:%h/.nvm/current/bin
ExecStart=%h/.local/bin/shellbase start --dir %h
Restart=always
RestartSec=3
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now shellbase.service주의할 점 3가지 (직접 겪은 문제라 적어둡니다):
ExecStart의shellbase경로는which shellbase로 직접 확인해서 넣으세요 — systemd 서비스는 평소 터미널의 PATH를 그대로 물려받지 않아서, node/shellbase를 못 찾는 경우가 흔해요. (Environment=PATH=...에도 같은 폴더를 넣어야 해요.)- 로그인 세션 없이(원격 SSH 접속도 안 하고) 완전히 백그라운드로 계속 떠있게 하려면
loginctl enable-linger $(whoami)도 한 번 실행해야 해요. 안 하면 로그아웃할 때 같이 꺼져요.- 메모리 지킴이(
earlyoom)가 도는 컴퓨터라면 0.14.2 이상을 쓰세요. 지킴이 설정에는 보통 "빌드 도구를 먼저 죽여라"는 뜻으로--prefer ^(cc1|gcc|node|npm|vite|tsc|...)$가 들어 있는데, 이 규칙은 명령줄이 아니라 프로세스 이름만 봅니다 — Node 로 만든 것은 전부 이름이node라 에이전트가 수십 MB 만 쓰고 있어도 1순위 사살 대상이 돼요(실측: oom_score 800 + 이름 보너스 300 = 1100 으로, 500MB 쓰는 프로세스보다 높았습니다). 에이전트가 죽으면 그 안의 세션이 전부 함께 죽습니다. 0.14.2 부터는 프로세스 이름을shellbase로 바꿔서 이 규칙에 안 걸려요.승인 옵션은 넣지 마세요 — 기본이 "내 계정이면 바로 입력 가능"이라 무인 서버에 그대로 맞습니다. (
--require-approval을 넣으면 접속할 때마다 이 컴퓨터에서y를 눌러야 하는데, 화면을 안 보는 서버에서는 사실상 승인을 못 하게 돼요.)
macOS
launchd 로 같은 걸 할 수 있어요 (~/Library/LaunchAgents/ 에 .plist 등록, KeepAlive: true).
아직 저희가 macOS에서 직접 검증은 못 했어요 — 해보시고 문제 있으면 알려주세요.
Windows
작업 스케줄러(Task Scheduler)에서 "로그온 시 시작" + "실패 시 다시 시작" 옵션으로 등록하면 비슷하게 됩니다. 아직 저희가 Windows에서 직접 검증은 못 했어요.
Docker (Linux, 실제 검증됨) — 격리가 꼭 필요할 때만
⚠️ 컨테이너 안 터미널은 호스트 시스템에 손이 닿지 않습니다. 파일 작업(프로젝트 편집·빌드·git)은 홈 폴더를 마운트하므로 100% 동일하지만,
docker/systemctl/다른 컨테이너/호스트 서비스는 못 씁니다 (도커의 정상적인 격리 동작). 컴퓨터 관리까지 폰에서 하려면 위의 systemd 방식을 쓰세요./var/run/docker.sock을 마운트하면 도커 제어는 가능해지지만, 그 순간 컨테이너가 호스트 전체를 조종할 수 있게 되어 격리의 의미가 사라집니다 — 권하지 않습니다.
컨테이너 안은 이 컴퓨터의 실제 환경과 분리돼 있어서, 홈 폴더를 통째로 볼륨(-v)으로 연결해야
git 설정·SSH 키·진짜 작업 파일들이 컨테이너 밖과 똑같이 보여요. 아래는 실제로 빌드해서 재부팅 시나리오
까지 검증한 구성이에요.
# Dockerfile
FROM node:22-bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential python3 git openssh-client ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN npm install -g shellbase@latest
ENTRYPOINT ["shellbase"]
CMD ["start"]docker build -t shellbase-agent .
docker run -d \
--name shellbase-agent \
--restart unless-stopped \
--user $(id -u):$(id -g) \
-v $HOME:$HOME \
-e HOME=$HOME \
shellbase-agent \
start --dir $HOME --name "내 서버 (Docker)"주의할 점 3가지 (직접 겪은 문제라 적어둡니다):
- Node 22 이상 이미지를 써야 해요.
node:20-...로 빌드하면 실시간 접속이 조용히 SSE 모드로 떨어져서shellbase start가 "네트워크가 막혔다"는 헷갈리는 에러를 내고 죽어요 — (0.1.5부터는 시작 시 Node 버전을 먼저 확인해서 바로 알려줘요.)--user $(id -u):$(id -g)를 꼭 넣으세요. 안 넣으면 컨테이너가 root로 돌아서, 터미널 안에서 만들거나 수정한 파일이 호스트에서는 root 소유가 돼버려요(내 계정으로 못 지우고 수정 못 하는 파일이 생김).--require-approval은 넣지 마세요. detached 컨테이너는y를 입력할 TTY가 없어서 승인을 못 해요. 기본값(내 계정이면 바로 입력 가능)이 이 상황에 맞습니다.
재부팅 시 자동 복구는 도커 데몬이 담당해요 — systemctl is-enabled docker 로 enabled 인지
확인하세요(보통 기본값). unless-stopped 는 컴퓨터가 재부팅되면서 데몬이 다시 뜰 때 "그때 돌아가고
있던" 컨테이너를 자동으로 복구해줘요(직접 docker stop 으로 멈춰뒀던 건 복구 안 해요 — 의도된
동작이에요). 강제 종료(kill -9, OOM 등)로 죽는 경우도 자동 재시작되는 것까지 확인했어요.
