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 접속 화면, 연결 버튼 하나만 있는 심플한 진입점 _링크를 열면 뜨는 noVNC 첫 화면. 연결 버튼 하나 누르면 VNC 비밀번호 입력창이 뜨고, 그다음 바로 데스크톱이 보인다._

열어보니 낯선 화면이 떴다

접속 링크를 열었더니 처음 보는 배경화면이 나왔다. 순간 "어, 이거 내가 아는 우분투가 아닌데" 싶었다. 알고 보니 별거 아니었다. 이 서버가 GUI로 로그인된 적이 한 번도 없어서, XFCE가 이 계정으로 처음 실행되면서 기본 테마를 새로 깐 것뿐이었다.

배경화면에 그려진 동물도 낯설었는데, 확인해보니 너뱃(Numbat)이었다. 호주에만 사는 유대류 동물로, 쥐랑 닮았지만 사실 개미핥기에 가깝다. 우분투 24.04의 공식 코드네임이 "Noble Numbat"이라서, 기본 배경화면 세트에 너뱃 캐릭터가 들어 있던 거였다. 홈 디렉토리를 열어보니 development, docker 폴더가 그대로 있고, 터미널에서 docker ps를 쳐보니 운영 중인 컨테이너들이 다 보였다. 배경화면만 낯설었지, 안은 완전히 내 서버였다.

XFCE 기본 배경화면으로 뜬 첫 데스크톱 화면 _한 번도 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

Posts