본문 바로가기
서버, 인프라

Ubuntu 서버에 Claude Code + Codex 올려봤더니, 개발 방식이 달라졌어요

by 요즘IT 2026. 6. 2.

처음엔 저도 그냥 로컬에서 썼어요.

Claude Code 터미널 켜고, 이것저것 시키고. 그러다 문득 이런 생각이 들더라고요.

"얘가 실수로 뭔가 지우면 어떡하지?"

그 불안감 한 번쯤 느껴보셨죠?

그래서 아예 Ubuntu 서버에 AI 개발 환경을 분리해서 올려봤어요. Hetzner 서버 기준으로요.

결론부터 말하면, 생각보다 훨씬 강력했고, 구조 설계를 잘못하면 진짜 사고 납니다.


왜 로컬이 아니라 서버인가요?

질문 당연하죠. 저도 처음엔 그랬거든요.

근데 로컬에서 Claude Code 돌리다 보면 문제가 생겨요.

  • 개발 환경이 프로젝트마다 충돌남
  • AI가 수정한 파일이 어떤 건지 추적이 힘듦
  • 다른 기기에서 이어서 작업하려면 동기화 문제가 생김

서버에 올리면 이게 싹 해결돼요. AI가 항상 같은 환경에서, 같은 코드를 보고 작업하거든요.

거기에 Docker까지 얹으면 완전히 다른 수준이 됩니다.


핵심은 "영역 분리"예요

도커 작업 공간 아키텍처
도커 작업 공간 아키텍처

도커 작업 공간 아키텍처

제가 구성한 구조는 이렇게 생겼어요.

 
 
text
/opt
├── app          ← 운영 서버 (Nginx, Jenkins, 실제 배포)
└── workspace    ← AI 작업 공간 (Claude Code, Codex가 여기만 봄)

처음에 저는 /opt/app을 바로 마운트하려 했어요. 편하잖아요, AI가 배포까지 바로 해주면.

근데 그게 문제였죠.

AI가 실수로 운영 파일을 건드린 순간, 복구가 보장이 안 되거든요. 실제로 비슷한 경험 한 번 했고, 그때 구조를 싹 다시 잡았어요.

지금은 AI는 workspace만 볼 수 있고, 운영 반영은 Jenkins가 담당해요.


Docker로 AI 두 개를 같이 올리는 방법

Claude Code와 Codex를 각각 컨테이너로 올렸어요.

 
 
bash
# Claude Code 컨테이너
docker run -dit \
  --name claude-code \
  -v /opt/workspace:/workspace \
  -w /workspace \
  claude-code

# Codex 컨테이너
docker run -dit \
  --name codex \
  -v /opt/workspace:/workspace \
  -w /workspace \
  codex-cli

두 AI가 /opt/workspace를 동시에 바라보게 되는 구조예요.

여기서 뭐가 가능하냐면요.

  • git clone, 코드 수정, commit
  • docker build, 배포 명령 실행
  • 로그 분석, 에러 확인

이게 전부 가능해져요. 사람이 개입하지 않아도.

솔직히 처음엔 좀 무서웠어요. AI가 commit을 직접 날린다는 게.


실제로 만난 에러 (이게 포인트예요)

어느 날 AI가 docker-compose를 수정하고 배포를 시도했는데, 이런 에러가 떴어요.

 
 
text
Conflict. The container name "/cymap-db" is already in use

원인은 간단해요. 이미 PostgreSQL 컨테이너가 떠 있는데, compose가 DB를 새로 만들려 한 거죠.

어? 이상하죠? AI가 상황을 제대로 파악 못한 거잖아요.

맞아요. AI도 현재 서버 상태를 정확히 모를 때가 있어요. 그래서 저는 AI한테 항상 이렇게 요청해요.

  1. 수정 전 현재 상태 분석 먼저
  2. 어떤 파일을 어떻게 바꿀 건지 설명 먼저
  3. 그다음에 실행

이 순서 안 지키면 진짜 사고 납니다.


Nginx도 Docker, GitHub SSH도 서버에서 바로

Nginx reverse proxy Docker network diagram
Nginx reverse proxy Docker network diagram

Nginx도 컨테이너로 올려서 서브도메인별로 프록시를 걸어뒀어요.

 
 
nginx
server {
    listen 443 ssl;
    server_name cymap.nxex.kr;

    location /api/ {
        proxy_pass http://cymap-backend:8000;
    }
}

컨테이너 이름으로 바로 연결되니까 IP 관리 안 해도 되는 게 편하더라고요.

GitHub 연결은 서버에 SSH 키 등록해서 해결했어요.

 
 
bash
ssh-keygen -t ed25519
ssh -T git@github.com

이렇게 하면 AI가 서버에서 바로 git push까지 할 수 있어요.


실제로 뭐가 달라졌나요?

생산성 얘기를 안 할 수가 없어요.

반복 작업, 로그 보면서 원인 찾기, 환경 변수 설정, 컨테이너 재시작. 이런 거 다 AI한테 맡기니까 저는 로직이랑 구조에 집중할 수 있더라고요.

근데 여기서 반전이 있어요.

AI를 믿으면 안 됩니다. 믿되 구조로 막아야 해요.

결국 핵심은 이거예요.

AI가 건드릴 수 있는 영역과 건드리면 안 되는 영역을 아키텍처 수준에서 분리하는 것.

이게 잘 되면 강력한 도구고, 안 되면 그냥 사고 유발 장치예요.

지금 저는 workspace, 운영 서버, Jenkins 배포 영역을 전부 나눠서 운영하고 있고, 이 구조 위에서 Claude Code + Codex를 쓰는 게 꽤 안정적으로 돌아가고 있습니다.

서버에 AI 개발 환경 한 번 올려보세요. 로컬이랑 느낌이 완전히 달라요.