+658K −773K. 군대에서 코딩하기

Snyong·2026년 7월 23일

2025년 1월 20일 입대 ~ 2026년 7월 19일 전역

546일 동안 마우스, 키보드, 모니터, 맥북도 없었습니다. 아이폰 하나로 2만명이 사용하는 실서비스를 운영했습니다. 자연스럽게 기존 방식을 벗어나, AI Native하게 개발하게 되었습니다.

  • 1,176 commit, +658K −773K
  • 누적 2만 다운로드, MAU 4,000+
  • 신규 출시한 AI공지: 공지 6,300건 크롤링 → 실유저에게 알림 12만 건 발송

1. 입대 전

스꾸버스는 2023년부터 운영중인, 성균관대 학생을 위한 AI 공지 요약·셔틀버스·캠퍼스 정보 플랫폼입니다. 입대 전까지는 셔틀버스 실시간 위치와 시간표 같은 버스 정보가 중심이었습니다.

개발 방식은 평범했습니다. VSCODE를 열고 직접 타이핑. 막히는 부분은 Gemini 웹에 코드를 복붙해서 물어봤습니다.

혼자 만드는 서비스의 특성상 운영도 곧 저였습니다. 버그 제보가 오면 그날 고쳤고, 학교 시간표가 바뀌면 데이터를 갱신했습니다. 이 환경이 당연했기 때문에, 입대를 앞두고도 별 생각이 없었습니다. 서버 안 죽게 점검하고, 급한 건 휴가 때 처리하면 되겠지! 정도로만 생각했습니다. 그 생각이 깨지는 데는 하루도 걸리지 않았습니다.


2. 훈련소

입대 당일 오후 4시 49분, Google Play Console에서 메일이 왔습니다.

본인 인증을 완료할 수 없습니다. 개발자 계정으로 Google Play에 앱을 게시할 수 없습니다.

이어진 후속 메일은 더 구체적이었습니다. 기한까지 문제를 해결하지 않으면 개발자 프로필과 관련 앱이 Google Play에서 삭제된다. 2만 명이 설치한 앱이, 코드 문제가 아닌 정책 미준수로 스토어에서 삭제될 위기였습니다.

문제는 제가 훈련소에 있다는 것이었습니다. 본인 인증을 위해 신분증 촬영이 필요한데, 카메라를 쓸 수 없었습니다. 설상가상으로 이미 인증 시도 횟수를 초과해서 고객센터로 직접 문의해야 했습니다. 주말에 주어지는 폰 사용시간은 1시간뿐. 그 1시간 동안 할 수 있는 일이라곤 상황을 파악하고, 구글에 이의신청과 항의 메일을 보내는 것뿐이었습니다.

결국 수료식 날 부모님이 가져다주신 여권으로 인증을 통과했습니다.

코드는 한 줄도 못 쓰는 5주 동안 새로운 사실을 배웠습니다. 서비스는 내가 군대에 있다는 사정을 봐주지 않는다는 것입니다. 플랫폼 정책도, 유저의 버그 제보도, 서버 장애도 제 상황과 무관하게 옵니다. 자대에 가면 어떻게든 이 서비스를 원격으로 다룰 방법을 만들어야 했습니다.


3. 자대

자대에서는 일과 후에 개인 폰과, 사지방 컴퓨터를 쓸 수 있었습니다. 이제 접근은 자유로워졌지만 그 다음 문제가 남아있었습니다.

3-1. 물리적으로 불가능했던 것

처음에는 사지방 컴퓨터를 최대한 활용해보려 했습니다.

  • Guacamole 웹 원격접속
    클릭 한 번에 화면 반영까지 3초가 걸렸습니다. (기적의 0.3FPS…)
    코드를 "읽는" 것조차 고역이었고, 타이핑은 말할 것도 없었습니다.
    초반에는 어떻게든 참고 사용했지만 코드 완성보다 인성이 나빠지는게 빠를 것 같아 포기했습니다.
  • VSCode Remote
    자동완성이 동작하지 않았고, 한글 주석과 영어 코드가 섞이면 멀쩡한 코드에 문법 오류가 표시됐습니다. 앱 개발에 필수인 시뮬레이터는 사용할 수 있는 방법이 없어 현실적으로 개발이 불가능했습니다.
  • 아이폰 + TeamViewer
    집에 있는 맥에 폰으로 원격 접속했습니다. 팀뷰어가 최적화가 잘 되어있어 프레임이나 조작의 어려움은 없었습니다. 진짜 어려움은 6.12인치 화면을 손가락으로 확대해가며 코드를 한 줄씩 읽고, 소프트 키보드로 타이핑한다는 것 자체였습니다.

어떤 원격 도구를 쓰든 환경을 개선해서 기존 방식의 개발을 이어가는 길은 없었습니다. 자연스럽게 개발 방식 자체를 바꾸는 것에 관심을 가지게 되었습니다.

3-2. Gemini Web

처음에는 아는 게 Gemini 뿐이라, 입대 전에 사용하던 대로 진행했습니다. Gemini 웹에 코드를 복붙하고, 생성된 코드를 다시 복붙해서 붙여넣는 방식. 그런데 폰으로 이 방식을 반복하며, 금방 지속 가능하지 않다는 걸 깨닫게 됐습니다.

  1. context를 매번 첨부해야 했습니다.
    관련 파일을 일일이 찾아 복사해 넣지 않으면 Gemini는 프로젝트를 이해하지 못했습니다.
    폰에서 이 작업은 개발보다 더 큰 비용이었습니다.
  2. AI가 랜덤코드 조각 생성기 이상이 될 수 없었습니다. 터미널도, 시뮬레이터도, 빌드 환경도 모르니, 프로젝트가 커지고 설정, 인프라, 의존성이 복합적으로 얽힐수록 단편적인 코드 생성만으로는 아무것도 굴러가지 않았습니다.

3-3. Gemini Web → Claude Code

이러한 문제점을 해결하기 위해 2026년 초, Claude Code를 사용하기 시작했습니다. 터미널 기반이라 tmux 세션에 붙여두면 폰에서도 이어서 작업할 수 있었고, 이후에는 원격 제어 도구(happy, claude remote-control)로 세션 자체를 폰에서 다뤘습니다.

CC는 직접 파일을 읽고, 수정하고, 터미널을 돌리고, 시뮬레이터를 띄우고, MCP로 외부 도구까지 다룰 수 있었습니다. 도구가 바뀜에 따라 제 역할도 크게 바뀌었습니다. 단순히 코드를 쳐서 기능을 구현하는 고민에서, 아키텍처를 결정하고 결과물을 검증하는 고민으로 이동했습니다. 폰에서 보는 건 코드 diff가 아니라 계획(plan mode), 테스트 결과(TDD), 그리고 질문(AskUserQuestion)이었습니다.

물론 완벽한 방식은 아니었습니다. CC는 예측 가능한 방식으로 실패했고(환각, regression, 스코프 이탈 등) 실패지점마다 새로운 방법을 도입해야 했습니다. (공식문서 스냅샷 고정, 버그 수정마다 재현 테스트 동반, LESSONS.md 축적, plan 승인 루프, main 편집 차단 hook)

→ 이 워크플로우는 추후 별도 글로 정리할 예정입니다.

3-4. 스꾸버스 AI공지

단순히 가능성을 확인하는데 그치지 않고, 2026년 5월 26일 스꾸버스 AI공지 기능을 신규 출시했습니다.
크롤러·AI 파이프라인·API 서버·발송 함수로 구성된 분산 시스템을 구현하였습니다.

  • 크롤러가 학교 137개 부서/게시판을 크롤링
  • AI가 공지를 요약/분류(마감일 추출, 대상 학과 판별 포함)한 뒤 DB에 저장
  • 앱에서 관심 설정한 사용자에게 FCM 푸시

약 3개월(2026-04-19 ~ 07-23) 간의 운영지표는 다음과 같습니다:

지표숫자
크롤 대상 출처137개 게시판
수집한 공지6,300건 (본문 크롤 성공률 94.7%)
AI 요약 완료5,966건
알림 발송 (공지 단위)3,406건, 발송 실패 0건
알림 전송 (기기 단위)121,027건
공지화면 평균 참여시간7분 47초

→ 공지 유형을 어떻게 분류할지, AI 콜을 몇 번으로 설계할지, 세 개의 서비스가 하나의 문서를 어떻게 나눠 갖는지 같은 설계 이야기는 다음 글에서 다룰 예정입니다.

3-5. 프로덕션 서버 장애

AI공지 기능을 개발하던 2026년 4월 10일, PR을 머지하자 배포가 실패했습니다. 새 컨테이너가 헬스체크(30초, 6회)를 실패했고, 미리 구성해둔 자동 롤백을 통해 이전 커밋으로 되돌아갔습니다. 빠르게 원인을 찾아 해결했습니다.

  1. gh run view --log-failed로 실패 로그 확보 → 컨테이너가 startup에서 process.exit(1)로 죽고 있었습니다.
  2. config의 필수 변수 목록에 새 변수를 추가했는데, 프로덕션 VM의 .env에는 그 변수가 없었습니다. Docker unless-stopped 정책 때문에 죽고-재시작을 무한 반복하는 crash loop였습니다.
  3. 폰으로 VM에 SSH 접속 → .env 백업 후 변수 추가 → gh run rerun --failed.

생활관에서 장애 인지부터 복구까지 9분 걸렸습니다. 중요한 건 복구가 아니라 그다음 질문이었습니다.

로컬도, CI도, 테스트도 전부 초록불이었는데 왜 프로덕션만 죽었을까?

값이 없으면 조용히 기본값으로 넘어가도록 만들어둔 게 문제였습니다. 안전장치라고 생각했던 fallback이 오히려 dev·CI·prod의 차이를 가리고 있었습니다. 이후 fail-loud 원칙으로 config를 재설계하고, 배포 전 dry-load 검증 단계를 추가했습니다.

이 사건에서 배운 것은 원격에서 개발할 수 있다는 것과, 원격에서 운영 책임을 질 수 있다는 것은 다른 차원의 문제라는 것입니다. 그리고 후자까지 가능해야 프로덕션을 한다고 말할 수 있습니다.


4. 전역

의외로, 어려운 건 코드 생성이 아니었습니다

AI가 코드를 만들어주는 시대에 어려움은 다른 곳에 있었습니다.

  1. 기획
    어떤 기능을 만들지 정했다면, 그걸 어떻게 만들 것인지 치열하게 고민해야 합니다. AI공지라면 워크플로우를 어떻게 구성할지, 공지 유형은 어떻게 분류할지, AI 콜은 몇 번이 적정한지. 코드는 AI가 쓰지만 이 질문들엔 AI가 답을 정해주지 않습니다. 이 과정에서 사용한 시간이 가장 길었고, 가장 가치 있었습니다.
  2. 리뷰
    생성되는 코드의 양은 한 줄씩 검증할 수 있는 양을 아득히 넘습니다. 그래서 직접 모든 줄을 검토하는 대신 구조로 해결했습니다. 리뷰 전용 에이전트를 만들고, 코드가 수정될 때마다 아키텍처 문서를 반드시 갱신하게 강제하고, 스스로는 코드 대신 그 문서를 완전히 이해하는 데 집중했습니다. 생각해보면 사람과 협업할 때도 사람이 쓴 모든 코드를 읽는 대신 계약(문서, 테스트, PR)을 검증합니다. CC와의 협업에서도 중요한 변경은 PR 단위로 잘라, 사람 팀에서 하듯 리뷰했습니다.
  3. 검증
    테스트 통과는 완료 신호가 아니었습니다. 타입체크·테스트·커버리지를 전부 통과한 코드가 실제 런타임에서 실패하는 걸 여러 번 겪었습니다. 반복되는 문제는 TDD로 재현 테스트를 추가하고, CI/CD에 검사를 결합하고, 마지막엔 반드시 실제 디바이스에서 확인했습니다. 세션이 끝나기 전에 검증 절차를 강제하는 stop hook도 구성했습니다.

코드 생성이 값싸진 순간, 병목은 결정과 검증으로 이동했습니다.
그리고 그 두 가지는 여전히, 어쩌면 전보다 더, 사람의 일입니다.

마치며

"군대에서는 개발 못 하지" "군대에서는 몸 건강히 나오기만 해도 잘한거다"라는 말을 입대 전에 정말 많이 들었습니다. 반은 맞습니다. 예전 방식의 개발은 정말로 못 합니다.

하지만 환경 제약은 도구와 워크플로우 설계로 극복 가능한 변수가 됐습니다. 폰 하나로 2만 명이 쓰는 서비스를 운영하고, 신규 기능을 출시하고, 프로덕션 장애를 9분 만에 복구할 수 있었습니다.

환경은 더 이상 변명이 되지 못합니다. 그래서 남는 질문은 하나입니다. 무엇을 만들지 결정하고, 만들어진 것을 검증할 수 있는가. 저는 그 연습을 가장 열악한 조건에서 546일 동안 했습니다.

궁금한 점이나 비슷한 고민이 있다면 편하게 연락 주시면 감사하겠습니다!


이어서 쓸 글들:

  1. 스꾸버스 AI공지 기획
    워크플로우, 공지 유형 분류, AI 콜 최적화
  2. Claude Code 프로덕션 워크플로우
    예측 가능하게 실패하는 CC와 방어 장치

3개의 댓글

comment-user-thumbnail
2026년 7월 28일

고수;

답글 달기
comment-user-thumbnail
2026년 7월 30일

아주 멋지네요 군생활 이후 멋진 브라보 라이프 펼치시길 바라겠습니다.

답글 달기
comment-user-thumbnail
2026년 7월 30일

휴대폰을 쓸수 있군요 요즘은 좋은곳이네

답글 달기