AI Agent 데스크톱, 컨테이너를 버리고 진짜 우분투 화면으로 갈아탔다
일주일 전에 AI Agent 전용 컨테이너 데스크톱을 만들었다. 링크 하나로 AI Agent가 브라우저를 조작하는 화면을 지켜볼 수 있게 한 것까지는 좋았는데, 쓰다 보니 자꾸 걸리는 게 있었다. AI Agent가 만지는 화면이 진짜 내 서버가 아니라는 점이었다.
가짜 데스크톱이라는 걸 알고 나니
대시보드에서 AI Agent 화면 카드를 볼 때마다 "이거 컨테이너로 올린 거잖아"라는 생각이 계속 들었다. AI Agent가 그 안에서 뭘 눌러도 진짜 우분투 파일이나 도커 컨테이너는 건드릴 수 없었다. 격리해 둔 이유가 있어서 만든 구조였는데, 막상 쓰다 보니 그 격리가 답답하게 느껴졌다.
내가 원한 건 AI Agent가 진짜 파일을 열고, 진짜 도커 컨테이너 목록을 보고, 진짜 터미널에서 작업하는 화면이었다. 그래서 물어봤다. 컨테이너 말고, 내 진짜 우분투 화면을 백북에서 볼 수는 없을까.
근데 이 서버, 모니터가 없다
바로 문제가 하나 나왔다. 이 우분투 서버는 모니터를 꽂아본 적이 없는 완전 헤드리스 서버다. xrandr를 돌려도 디스플레이가 안 잡히고, GNOME 세션도 한 번도 로그인된 적이 없었다. "진짜 화면"이라고 해도 사실 켜져 있는 화면이 없으니, 새로 띄워야 했다.
방법은 두 갈래였다.
| 방식 | 장점 | 단점 |
|---|---|---|
| RDP (Microsoft Remote Desktop) | 표준적이고 안정적 | 전용 앱 필요, 브라우저 탭으로는 못 봄 |
| VNC + noVNC | 브라우저에서 바로 열림, 기존 컨테이너와 같은 감각 | 설정이 한 단계 더 필요 |
지금 컨테이너 방식이 사실 내부적으로 VNC 계열을 쓰고 있었다. 그러니 그 조합을 컨테이너 없이 호스트에 그대로 깔면, 지금 쓰는 "링크 열면 바로 화면"이라는 감각을 유지하면서 진짜 우분투에 붙을 수 있겠다 싶었다.
TigerVNC로 진짜 화면 하나 띄우기
XFCE, TigerVNC, noVNC를 호스트에 직접 설치했다.
sudo apt-get install -y xfce4 xfce4-goodies tigervnc-standalone-server dbus-x11 novnc websockify
VNC 접속 비밀번호도 하나 걸었다. 우분투 로그인 비밀번호와는 완전히 별개다. 이 화면을 보려면 Tailnet 안에 있으면서 동시에 이 비밀번호도 알아야 한다.
vncpasswd
systemd 서비스로 등록하는 과정에서 한 번 삐끗했다. 처음엔 직접 유닛 파일을 만들어서 등록했는데, TigerVNC의 PID 파일 관리 방식과 안 맞아서 systemd가 "서비스 실패"로 잘못 판단했다. 로그를 뒤져보니 XFCE 세션 자체는 멀쩡히 떠 있었다. 원인은 다른 데 있었다.
New main PID does not belong to service, and PID file is not owned by root. Refusing.
알고 보니 tigervnc-standalone-server 패키지에 이미 공식 systemd 유닛(tigervncserver@.service)이 들어 있었다. 직접 짠 유닛을 버리고 이걸로 갈아탔더니 바로 정상 작동했다.
echo ":1=duncan" | sudo tee -a /etc/tigervnc/vncserver.users
sudo systemctl enable --now tigervncserver@:1.service
sudo systemctl enable --now novnc.service
노출은 이전 글과 같은 방식, Tailscale Serve로 했다.
sudo tailscale serve --bg --https=8443 http://127.0.0.1:6080
_링크를 열면 뜨는 noVNC 첫 화면. 연결 버튼 하나 누르면 VNC 비밀번호 입력창이 뜨고, 그다음 바로 데스크톱이 보인다._열어보니 낯선 화면이 떴다
접속 링크를 열었더니 처음 보는 배경화면이 나왔다. 순간 "어, 이거 내가 아는 우분투가 아닌데" 싶었다. 알고 보니 별거 아니었다. 이 서버가 GUI로 로그인된 적이 한 번도 없어서, XFCE가 이 계정으로 처음 실행되면서 기본 테마를 새로 깐 것뿐이었다.
배경화면에 그려진 동물도 낯설었는데, 확인해보니 너뱃(Numbat)이었다. 호주에만 사는 유대류 동물로, 쥐랑 닮았지만 사실 개미핥기에 가깝다. 우분투 24.04의 공식 코드네임이 "Noble Numbat"이라서, 기본 배경화면 세트에 너뱃 캐릭터가 들어 있던 거였다. 홈 디렉토리를 열어보니 development, docker 폴더가 그대로 있고, 터미널에서 docker ps를 쳐보니 운영 중인 컨테이너들이 다 보였다. 배경화면만 낯설었지, 안은 완전히 내 서버였다.
_한 번도 GUI 로그인한 적 없는 서버라 XFCE가 기본 테마로 처음 뜬 화면. 지금은 검정 배경으로 바꿔서 이런 낯선 느낌은 사라졌다._안전망은 없어졌다
컨테이너를 쓰던 이유는 격리였다. 그 격리를 걷어냈으니, 이제 AI Agent가 여기서 뭘 잘못 누르면 그대로 실제 시스템에 영향이 간다. 파일을 지우면 진짜 지워지고, 설정을 바꾸면 진짜 바뀐다.
대신 접근 통로는 최대한 좁혀뒀다.
| 항목 | 상태 |
|---|---|
| VNC 포트 바인딩 | 127.0.0.1만 (로컬에서만 접근 가능) |
| 외부 노출 | Tailscale Serve 하나, Funnel 없음 |
| 인증 | VNC 비밀번호 + Tailnet 소속 여부 이중 확인 |
| 데스크톱 계정 | 서버 계정과 동일, 별도 격리 계정 아님 |
이전 글에서는 "비밀번호를 안 건 이유"를 따로 썼는데, 이번엔 반대로 비밀번호를 걸었다. 격리된 장난감 화면일 때는 Tailscale 하나로 충분했지만, 진짜 파일과 진짜 도커에 닿는 화면이라면 한 겹 더 있는 게 맞다고 판단했다.
정리는 바로 했다
새 방식이 잘 되는 걸 확인하고 나서 옛날 컨테이너는 바로 지웠다.
docker compose down -v
sudo tailscale serve --set-path=/agent-desktop/ off
대시보드 카드도 컨테이너 상태 대신 실제 화면 프로세스(Xtigervnc, websockify)가 떠 있는지 확인하는 방식으로 코드를 바꿔서 다시 배포했다. 컨테이너 이름을 조회하던 자리에, 지금은 그 두 프로세스가 살아 있는지를 확인한다.
써보니
AI Agent가 지금 이 화면에서 만지는 건 더는 장난감이 아니다. 홈 디렉토리도, 도커 컨테이너도, 다 진짜다. 그만큼 지켜보는 마음가짐도 달라졌다. 이전 글에서는 "뭔가 잘못돼도 그 컨테이너 안에서 끝난다는 걸 아니까 마음이 편해졌다"고 썼는데, 이번엔 반대다. AI Agent가 화면에서 뭘 하는지 이전보다 더 자주 들여다보게 됐다.
배경화면의 너뱃은 그대로 뒀다가, 결국 XFCE 기본 무늬로 바꿨다. 작업 화면인데 낯선 캐릭터가 계속 보이면 신경이 쓰였다.
정리
- 시작: 컨테이너 데스크톱을 쓰다 보니 "이거 진짜 내 서버가 아니잖아"라는 답답함
- 바꾼 것: 컨테이너 대신 호스트에 TigerVNC + noVNC 직접 설치
- 삽질 포인트: 커스텀 systemd 유닛이 PID 관리 방식과 안 맞아 실패 → 패키지 제공 공식 유닛(
tigervncserver@.service)으로 교체 - 의외의 순간: 헤드리스 서버라 처음 뜬 화면이 낯설었다, 정체는 우분투 24.04 코드네임 마스코트 너뱃
- 잃은 것: 컨테이너 격리 — 이제 실수하면 진짜 시스템에 영향
- 대신 채운 것: VNC 포트 로컬 바인딩 + Tailscale Serve + VNC 비밀번호 이중 확인
- 뒷정리: 옛날 컨테이너와 Tailscale Serve 경로 삭제, 대시보드 코드도 실제 프로세스 확인 방식으로 교체
컨테이너 화면은 안전했지만 반쪽짜리였다. 진짜 화면은 위험한 만큼, AI Agent가 뭘 하는지 더 자세히 보게 만든다.
환경: 우분투 서버, TigerVNC(systemd), noVNC, websockify, Tailscale Serve