1. 시작하며: ‘코드를 고쳤는데 왜 반영이 안 되지?’
오랜만에 R 코드를 수정했을 때의 이야기입니다. 한글 인코딩 오류가 발생했는데 Java 코드 수정만으로는 해결되지 않는 상황이었습니다. 그래서 R 코드도 확인해 보고자 .R 파일을 열어 코드를 일부 수정하고 로그 출력을 추가했습니다. 이후 서비스를 재시작하고 결과를 확인했는데 인코딩 오류는 그대로였고, 제가 추가한 로그조차 어디에서도 찾아볼 수 없었습니다.
로그를 추가했는데 왜 출력이 안 되지?
R은 인터프리터 언어라서, 파일만 바꾸면 바로 반영되는 거 아닌가?
결론부터 얘기하면, ‘소스코드 수정 = 서비스 반영’이 아니었습니다. 우리 팀의 서비스는 R 스크립트를 그대로 실행하는 방식이 아닌, 여러 .R 파일들을 묶어서 만든 R 패키지를 설치해서 사용하는 구조였기 때문입니다. 즉, 반드시 거쳐야 하는 중간 단계가 있었는데 오랜만의 R 개발로 이를 놓친 것이 원인이었습니다.
소스코드 수정
→ <빌드 / 패키징 / 배포>
→ 운영 서비스에서 새 버전을 사용
이 글에서는 이 질문에 답해 보려고 합니다.
- 왜 굳이 패키지로 묶고, 빌드 과정을 거칠까?
- 패키지 기반의 파이프라인에서는 어떤 단계를 통해 서비스에 반영될까?
- R 환경에서는 이 단계들이 어떤 파일/명령어와 연결될까?
2. 빌드·배포에 있어서: 패키지 기반 vs 소스코드 기반
1). 소스코드 기반: 빠르지만 언제 수정될지 모르는 원고
많은 사람이 R이나 Python을 떠올릴 때 생각하는 개발 방식은 다음과 같습니다.
source(“script.R”)
run_analysis()
파일을 고치고, 저장하고, 바로 source()로 실행하는 방식입니다. 개인 작업이나 실험적인 코드를 작성할 때는 정말 편리합니다. 이 편리함에 따라 장점과 단점이 명확합니다.
- 장점
- 수정 후 바로 실행 가능 → 피드백 루프가 매우 짧음
- 노트북(Notebook), 임시 분석, 1회성 스크립트에 최적
- 단점
- 같은 파일이 서버/개발자 PC마다 조금씩 다른 버전으로 존재하기 쉬움
- 현재 운영 환경에서 정확히 어느 버전이 실행 중인지 추적하기 어려움
- 과거의 결과를 다시 도출하거나, 장애 상황을 재현하기 힘듦
- 롤백(Rollback) 개념이 모호함 (‘이전 script.R 파일을 어디서 다시 구하지…?’)
개인용으로는 괜찮지만, 팀이나 서비스 단위로 운영하기에는 안정성이 떨어지는 방식입니다.
2). 패키지 기반: 느리지만 판본별로 동일한 책
패키지 기반 구조는 접근 방식이 다릅니다. 여러 .R 파일과 메타데이터를 묶어 하나의 R 패키지(완제품)를 만듭니다. 운영 환경에서는 이렇게 생성된 패키지(완제품)만 로딩해서 사용합니다. 이렇게 하면 장단점이 뒤바뀝니다.
- 장점
- 명확한 버전 관리: <운영 서버는 현재 myservice 1.2.3 버전으로 구동되고 있다>와 같이 버전·의존성·환경을 패키지 단위로 고정할 수 있음
- 배포 및 롤백의 기준: 운영에 배포된 패키지 파일 그 자체가 배포 단위이자 롤백 단위가 됨
- 재현 가능성: 장애가 발생해도 <그 환경에 설치되어 있던 패키지 버전과 의존성>을 재설치하면 동일한 환경을 완벽히 재현 가능
- 단점
- 코드 한 줄만 고쳐도 <빌드 → 설치> 과정을 다시 거쳐야 함
- 인터프리터 언어인데 이렇게까지 해야 하나? 라는 의문이 들 수 있음
즉, 소스코드 기반 방식은 실행 속도와 편의성에서 좋지만, 운영·협업·장기 유지보수까지 고려하면 패키지 기반 방식이 통제가 훨씬 용이합니다.
3). 엔터프라이즈 환경에서 패키지 기반을 택하는 이유
상용되는 서비스와 개인의 소규모 프로젝트 사이에는 큰 차이가 있습니다.
- 개인: 지금 내 컴퓨터에서만 잘 돌아가면 된다
- 서비스: 언제, 어디서, 누가 돌려도 같은 퍼포먼스가 나와야 한다
특히 고객사에 납품하는 고도화된 솔루션의 경우 다음 요건들이 필수적입니다.
- 여러 고객사와 서버에서 동일한 비즈니스 로직을 보장해야 합니다.
- 장애 발생 시, 그 상황에서 구동되던 코드와 환경을 그대로를 재현할 수 있어야 합니다.
- 버전 업그레이드, 롤백, 패치 등의 이슈를 통제 가능한 단위로 관리해야 합니다.
이러한 요구를 만족시키기 위해 운영팀은 패키지 기반 빌드·배포 파이프라인을 설계하게 됩니다.
정리하면
소스코드 기반은 빠르지만 변수가 상당히 많고
패키지 기반은 느리지만 과정을 통제할 수 있습니다.
그렇기에 운영 서비스는 자연스럽게 후자를 선택하게 됩니다.
3. 패키지 시스템의 공통 파이프라인 5단계
이제 R이라는 언어에서 잠시 벗어나, <패키지 기반 시스템>을 일반적인 모델로 바라보겠습니다. 패키지를 빌드하고 배포하는 과정은 언어나 플랫폼이 달라도 대체로 비슷한 5단계를 거칩니다.

5단계 파이프라인
- 소스 작성 (Source)
- 비즈니스 로직, 도메인 코드, 설정, 스크립트 등 실제로 기하는 코드를 작성하는 단계입니다.
- 의존성 정의 (Dependencies)
- 프로젝트가 어떤 라이브러리·런타임·버전에 의존하는지 선언하는 단계입니다.
- 여기에 작성된 정보는 개발 환경 또는 운영 환경을 동일하게 재현하는 토대가 됩니다.
- 빌드 및 패키징 (Build & Packaging)
- 소스 코드와 의존성 정보 등을 검사·변환·컴파일하고, 배포 가능한 패키지 형태로 묶는 단계입니다.
- 이 과정에서 문법 오류 / 메타데이터 오류 / 테스트 실패 등을 사전에 잡아냅니다.
- 언어나 도구에 따라 컴파일이나 바이트코드 생성이 포함되기도 합니다.
- 배포 (Deploy)
- 빌드 산출물인 패키지를 사내 패키지 저장소, 아티팩트 서버, 파일 서버 등에 업로드하는 단계입니다.
- 실행 (Run)
- 운영 환경에서 특정 버전 패키지를 다운로드 및 설치하고 로드하여 실제 서비스를 구동하는 단계입니다.
도서 출판 프로세스와 비교하며 이해하기
패키지 기반의 빌드·배포 파이프라인은 책을 출판하는 과정과 굉장히 닮아 있습니다.
- 소스 작성 = 원고 집필
- 코드 / 함수 / 스크립트를 작성하는 것은 작가가 원고의 초안을 쓰는 것과 같습니다.
- 의존성 정의 = 출판 규격 및 참고문헌 정리
- 설정 문서에 의존 패키지와 메타데이터를 정의하는 일은 책의 판권 정보 / 참고문헌 / 판형 / 용지 규격 등을 정리하는 작업과 비슷합니다.
- 빌드 및 패키징 = 편집·교정·제본으로 <책 한 권> 만들기
- 소스와 의존성 정보 등을 빌드하여 패키지 파일로 만드는 단계는, <책 한 권>을 만드는 과정과 닮았습니다. 이는 편집자와 디자이너가 원고를 교정하고 조판하여 표지와 목차를 붙인 뒤 실제 서점에 내놓을 수 있게 제본하는 과정입니다.
- 배포 = 서점·온라인 서점에 입고
- 빌드가 끝난 패키지 파일을 패키지 저장소나 서버에 올리는 것은, 완성된 책을 출판사 물류센터에서 서점이나 온라인 서점에 입고시키는 것과 유사합니다.
- 실행 = 독자가 책을 구입해 읽고 활용하기
- 애플리케이션이 패키지를 로드하고 함수를 호출해 실제 서비스를 제공하는 것은, 독자가 서점에서 책을 구입하고 펼쳐 읽으며 그 내용을 지식으로 활용하는 순간과 맞춰 볼 수 있습니다다.

핵심은 이것입니다.
언어와 생태계가 달라도 패키지 기반 시스템은 보통 이 5단계를 거칩니다.
R 개발 또한 이 일반적인 프로세스에 대입하여 이해하면 복잡해 보이던 과정이 훨씬 단순하게 다가옵니다.
4. R에서의 5단계 파이프라인
R 패키지 개발 흐름 요약
R 개발자의 관점에서 보면 다음과 같은 워크플로우가 됩니다.
R/ 폴더에 소스 코드를 작성하고
→ DESCRIPTION 파일에 의존성과 메타데이터를 정리한 뒤
→ R CMD build 나 RStudio의 Build 기능을 이용해 패키지 파일(.tar.gz)을 만들고
→ R CMD INSTALL 명령으로 서버 라이브러리에 설치한 후
→ 최종적으로 애플리케이션에서 library(패키지명)으로 로드하여 사용하는 흐름입니다.
이제 이 흐름을 앞서 설명한 5단계 파이프라인에 맞춰 표로 정리해 보겠습니다.
표로 보는 R의 5단계 파이프라인
| 단계 | 주요 역할 | R 환경에서의 파일 및 명령어 |
| [1]소스 작성 | 비즈니스 로직 구현, 버그 수정 등 실제 코드를 작성하는 단계 | R/ 폴더의 .R 파일에 함수·스크립트를 작성 및 수정 |
| [2]의존성·메타데이터 정의 | 패키지 이름, 버전, 필요한 다른 패키지 등을 선언하는 단계 | DESCRIPTION, usethis::use_package() |
| [3]빌드·패키징 | 소스코드, 데이터, 문서를 빌드해서 하나의 ‘설치 가능한 패키지 파일’로 만드는 단계 | R CMD build, RStudio의 Build, devtools::build() → myservice_1.0.0.tar.gz |
| [4]배포·설치 | 빌드된 패키지를 목표 환경 (서버/저장소/라이브러리 경로)에 배포·설치하는 단계 | R CMD INSTALL, 커스텀 스크립트 실행 |
| [5]로드·실행 | 애플리케이션 또는 사용자가 설치된 패키지를 실제 서비스/코드에서 로드하고 사용하는 단계 | library(myservice), myservice::run_job(), 앱 구동 시 호출 |
주목할 만한 포인트는
- 평소에 코드를 작성하며 주로 마주하는 것은 1~2단계(코드, DESCRIPTION)이지만
- 실제 운영에서 서비스가 사용하는 것은 3~5단계를 거쳐 완성된 패키지라는 점입니다.
- 그렇기에 .R 파일만 고쳐서는 아무 일도 일어나지 않으며, 빌드→배포→로드까지 진행되어야 비로소 변경사항이 서비스에 반영됩니다.
5. 정리하며: 패키지 시스템을 통한 전체 맥락 이해
R에서의 빌드·배포 파이프라인

앞으로 R 코드를 수정시, 이 5단계 파이프라인을 머릿속에서 한 번씩 떠올려 보시길 권합니다.
패키지 시스템을 이해했을 때의 실질적인 장점
단순히 기술과 기능을 아는 것을 넘어 이 시스템의 흐름을 명확히 파악하면 다음과 같은 개발 역량을 키울 수 있습니다.
1) 디버깅 및 장애 대응 역량 강화
- ‘어디가 문제지?’ 라며 막연하게 찾는 대신, 소스부터 실행까지 어느 단계에서 끊겼는지 파악하여 원인의 범위를 좁힐 수 있습니다.
- ‘내 로컬은 되는데 서버는 안 돼요’라는 상황을 구조적으로 설명할 수 있습니다. (예: ‘로컬에서 빌드는 성공했는데, 서버 배포 단계가 누락되었거나 애플리케이션이 구버전 패키지를 로드하고 있는 것 같습니다.’)
2) 아키텍처 및 리팩토링 관점의 확장
- R 코드를 단순한 스크립트가 아닌 하나의 <엔진 모듈>로 보고 설계하게 됩니다. 이는 Java/Spring, Python 등 타 언어와의 인터페이스 설계를 용이하게 합니다.
- 기능 단위 분리/통합 기준이 생깁니다. ‘이건 패키지를 나눠야 할 기능인가?’를 빌드·배포 단위 관점에서 판단할 수 있어, 장기적인 관점에서 모듈 구조를 설계하는 안목이 생깁니다.
- 마치 레고 블록처럼, A팀이 만든 <전처리 패키지>를 B팀이 재사용하는 식의 모듈 생태계에 대한 안목이 키워집니다.
3) 명확한 협업 커뮤니케이션
- <이번 배포는 myservice 1.2.3 버전 기준입니다> 라는 말이 팀 내에서 정확히 어떤 코드와 환경을 의미하는지 공유하게 됩니다.
- 코드 리뷰, 배포 승인, 롤백 논의가 <패키지 버전>이라는 구체적인 단위로 이뤄지기 때문에 소통 비용이 줄어듭니다.
4) 운영 및 배포 안정성 확보
- 장애 발생 시 ‘어느 버전의 패키지에서 문제가 났는지’를 면밀히 추적할 수 있습니다.
- 문제가 된 버전의 패키지를 그대로 다시 설치하여 장애 상황을 완전하게 재현할 수 있습니다.
- 운영 환경을 막연한 <소스 묶음>이 아닌 <검증된 패키지와 의존성 집합>으로 관리하는 습관이 생깁니다.
이 글을 요약하여 이렇게 말할 수 있을 것 같습니다.
R 패키지 개발에서 <수정했다>는 말은,
단순히 코드를 고쳤다는 뜻이 아닙니다. 코드 수정만이 아니라 패키지를 빌드하고 배포해서 서버/운영에 올라간 상태까지 포함합니다.
감성적인 표현을 써보면
소스코드는 <개발자가 보는 세계>이고,
패키지는 <서비스가 보는 세계>입니다.
R 코드를 다루면서 이 5단계 파이프라인을 항상 염두에 둔다면 빌드·배포·운영을 하나의 흐름으로 꿰뚫어 보게 되고, 단순한 코딩을 넘어 제품(Product)을 만드는 시야를 갖게 되실 것이라 확신합니다.
참고문헌
실제 구현 방법이나 더 구체적인 세부 규칙이 궁금하시다면, 아래 문서들을 참고해 보세요.
- R Packages (2nd Edition) (Hadley Wickham & Jennifer Bryan)
- R 패키지 개발의 모든 단계(구조, 테스트, 문서화 등)를 초심자 눈높이에서 상세히 설명한 웹 도서입니다.
- Writing R Extensions (CRAN Official)
- R 코어 팀이 제공하는 공식 가이드로 패키지 구조와 CRAN 배포 정책에 대한 가장 정확하고 방대한 기술 문서를 담고 있습니다.
- The targets R package (Will Landau)
- 단순한 패키지 개발을 넘어 R 기반의 데이터 분석 파이프라인을 자동화하고 효율적으로 관리하는 방법을 다룹니다.