"코드를 저장하고 git push 한 번 했더니, 몇 분 뒤에 실제 사이트가 바뀌어 있더라고요." 처음 이 광경을 봤을 때 저는 솔직히 좀 무서웠습니다. 내가 아무것도 안 했는데 서버가 알아서 바뀐다니, 이거 귀신 붙은 거 아닌가 싶었죠. 그런데 알고 보니 그게 바로 요즘 개발 현장에서 당연하게 쓰는 CI/CD라는 겁니다.
저는 코딩을 늦게 시작한 사람입니다. 그래서 "CI/CD 파이프라인 구축했어요" 같은 문장을 들으면 눈앞이 캄캄했어요. 파이프? 파이프가 왜 코딩에 나와? 이런 심정이었죠. 그런데 막상 알고 보니, 이건 겁먹을 개념이 전혀 아니었습니다. 오히려 귀찮고 실수 잦은 일을 기계에게 시키는, 게으른 사람에게 딱 좋은 도구였어요.
이 글은 CI/CD라는 말만 들어도 가슴이 답답해지는 분들을 위한 글입니다. 코드 한 줄 안 나옵니다(끝에 아주 짧은 개념 예시 몇 줄만 나오고, 그것도 한 줄씩 풀어드립니다). 대신 "이게 대체 왜 필요하고, 무슨 일을 대신 해주는가"를 부엌 이야기, 빨래 이야기로 천천히 풀어보겠습니다. 겁먹지 마세요. 저도 그랬으니까요.
미리 결론부터 말씀드리면 이렇습니다. CI/CD의 핵심은 딱 한 문장이에요. "사람이 손으로 하면 실수하고 지치는 반복 작업을, 기계에게 정확하게 시키는 것." 이 문장만 마음에 담고 가셔도 오늘 글의 절반은 이해하신 겁니다. 나머지 절반은 "그래서 구체적으로 뭘, 어떤 순서로 기계에게 시키느냐"를 살펴보는 거고요. 그럼 천천히 시작해볼게요.
CI/CD는 식당 주방의 자동 컨베이어입니다. 요리사(개발자)가 재료(코드)를 컨베이어에 올려두기만 하면, 검수 → 조리 → 접시에 담기 → 손님상까지 기계가 알아서 끝냅니다. 사람은 재료를 잘 올리는 데만 집중하면 돼요.
손빨래 시절: 예전엔 배포가 '의식'이었습니다
CI/CD를 이해하려면, 먼저 그게 없던 시절이 얼마나 고달팠는지를 아셔야 합니다. 제가 처음 만든 웹사이트를 세상에 올리던 날을 아직도 기억해요. '배포'라는 게 이런 순서였습니다.
먼저 내 컴퓨터에서 파일을 하나하나 챙깁니다. 그다음 FTP라는 프로그램을 켜서, 마치 이삿짐 옮기듯 파일을 서버로 하나씩 끌어다 올립니다. 그러다 중간에 하나를 빠뜨리면? 사이트가 깨집니다. 실수로 옛날 파일을 덮어쓰면? 어제 고친 게 사라집니다. 다 올린 뒤엔 서버에 접속해서 검은 화면(터미널)에 알 수 없는 명령어를 조심조심 타이핑합니다. 한 글자 틀리면 서버가 멈추고요.
이 모든 과정을 저는 "배포 의식(儀式)"이라고 불렀습니다. 무슨 제사 지내듯 긴장하면서, 절대 실수하면 안 된다는 압박 속에서, 손을 덜덜 떨면서 했거든요. 그리고 사람이 하는 일이니 당연히 실수가 났습니다. 금요일 저녁에 배포했다가 주말 내내 사이트가 죽어 있던 적도 있어요. 이걸 개발 바닥에서는 농담 반 진담 반으로 "금요일엔 배포하지 마라"라고 합니다.
더 서러웠던 건, 이 배포 방법이 제 머릿속에만 있었다는 점입니다. "먼저 이 폴더 올리고, 그다음 서버 접속해서 이 명령 치고, 아 참 이 파일은 빼고…" 이런 순서가 어디 적혀 있지도 않고 그냥 제 경험으로만 굴러갔어요. 그러다 제가 며칠 자리를 비우면, 아무도 배포를 못 했습니다. 회사에서 이런 사람을 "버스 지수(bus factor)가 1"이라고 부르더군요. 그 한 사람이 버스에 치이면(혹은 그냥 휴가만 가도) 프로젝트가 멈춘다는 뜻입니다. 웃기지만 하나도 안 웃긴 상황이죠.
그리고 배포가 무서우니 자연히 미루게 됩니다. "이번 주는 그냥 넘기고 다음에 몰아서 올리자." 그렇게 미루고 미루다 한 달치를 한 번에 올리면, 뭔가 터졌을 때 도대체 이 중 어느 변경이 범인인지 알 길이 없었어요. 배포가 무서워서 미루고, 미뤄서 덩치가 커지고, 덩치가 커져서 더 무서워지는 악순환. 이게 손빨래 시절의 진짜 고통이었습니다.
손빨래를 생각해보세요. 옷을 빨래판에 대고, 비누칠하고, 문지르고, 헹구고, 짜고, 너는 것까지 전부 손으로 합니다. 힘들고, 오래 걸리고, 어쩌다 한 번은 옷을 상하게 하죠. 옛날 수동 배포가 딱 이랬습니다. 그런데 세탁기가 나왔어요. 빨래를 넣고 세제를 넣고 버튼만 누르면 세탁 → 헹굼 → 탈수까지 알아서 끝. CI/CD는 개발 세계의 세탁기입니다. 한번 세팅해두면, 그다음부터는 버튼(사실은 코드 저장) 한 번이면 됩니다.
재미있는 건, 세탁기가 나왔다고 해서 사람이 할 일이 없어진 게 아니라는 점이에요. 대신 사람은 더 중요한 일에 집중하게 됐죠. 빨래를 문지르는 대신, 어떤 옷을 살지 고르고 어떻게 입을지 궁리하는 시간이 늘어난 겁니다. CI/CD도 마찬가지입니다. 배포라는 단순 노동에서 해방된 개발자는, 그 시간에 "무엇을 만들지, 어떻게 하면 더 좋을지"라는 진짜 창의적인 고민에 힘을 쏟게 됩니다. 자동화의 진짜 선물은 '시간 절약'을 넘어 '집중의 방향을 바꿔주는 것'이에요.
CI가 뭔가요 — 여러 명의 요리를 자주 합쳐서 맛보는 일
CI/CD는 사실 두 글자짜리 약자 두 개가 붙은 겁니다. 먼저 앞의 CI부터 보죠. CI는 Continuous Integration, 우리말로 '지속적 통합'입니다. 말이 딱딱하죠? 쉽게 풀면 이렇습니다.
큰 프로젝트는 보통 여러 사람이 같이 만듭니다. 요리로 비유하면, A는 국을 끓이고, B는 밥을 짓고, C는 반찬을 만드는 식이죠. 그런데 각자 따로 며칠씩 요리만 하고 서로 한 번도 안 맞춰보면 어떻게 될까요? 나중에 상을 차리는 순간, 국은 너무 짜고 밥은 질고 반찬은 다 매워서 도무지 한 상이 안 되는 참사가 벌어집니다.
그래서 CI의 핵심은 "각자 만든 코드를 자주자주 합치고, 합칠 때마다 곧바로 맛을 본다"입니다. 여기서 '맛을 본다'가 바로 자동 검사예요. 코드를 합칠 때마다 컴퓨터가 알아서 두 가지를 확인합니다.
- 빌드(build): 이 코드가 애초에 제대로 조립되긴 하는지. 요리로 치면 재료들이 실제로 하나의 음식으로 만들어지긴 하는지 확인하는 단계입니다.
- 테스트(test): 만들어진 게 제대로 작동하는지. 미리 만들어둔 '검사 항목'을 하나하나 돌려보며 "로그인 되나? 계산 맞나? 버튼 눌리나?"를 자동으로 확인합니다.
이걸 합칠 때마다 매번, 사람 손 안 대고 자동으로 한다는 게 CI의 전부입니다. 어렵지 않죠? 이름에 '지속적(Continuous)'이 붙은 이유가 바로 이거예요. 어쩌다 한 번 몰아서 검사하는 게 아니라, 코드가 바뀔 때마다 끊임없이 계속 검사한다는 뜻이거든요. 검사가 특별한 이벤트가 아니라 숨쉬듯 늘 돌아가는 배경이 되는 겁니다.
제가 CI를 처음 겪고 놀랐던 건, 실수가 '작을 때' 잡힌다는 점이었습니다. 예전엔 오타 하나, 빠뜨린 부품 하나가 몇 주씩 숨어 있다가 배포 순간에야 "펑" 하고 터졌어요. 그런데 CI를 붙이니, 코드를 합치자마자 몇 분 안에 "여기 이거 조립 안 됩니다", "여기 테스트 하나 깨졌어요" 하고 알려주더라고요. 문제가 방금 만든 따끈따끈한 상태일 때 잡히니, 기억도 생생하고 고치기도 쉬웠습니다. 시간이 지나 식어버린 문제를 찾는 것과는 난이도가 하늘과 땅 차이예요.
또 하나. CI는 "내 컴퓨터에선 됐는데요"라는 변명을 없애줍니다. 개발자들끼리 가장 많이 하는 말이자 가장 골치 아픈 말이 이겁니다. 내 노트북에선 멀쩡히 돌아가는데 남의 컴퓨터나 서버에선 안 되는 상황이죠. CI는 항상 '똑같이 깨끗한 공용 부엌'에서 검사를 돌리기 때문에, 내 컴퓨터에만 몰래 깔려 있던 뭔가 덕분에 됐던 건지, 진짜로 코드가 멀쩡한 건지를 정직하게 가려줍니다. 이 '공용 부엌'이라는 개념은 뒤에서 다룰 컨테이너 이야기와도 이어집니다. 컨테이너는 아예 "어디서 돌리든 똑같은 부엌"을 통째로 싸서 들고 다니는 기술이거든요.
CD가 뭔가요 — 전달(Delivery)과 배포(Deployment)는 다릅니다
이제 뒤의 CD입니다. 여기서 많은 분이 헷갈려 하시는데, CD는 사실 두 가지 뜻이 있습니다. 둘 다 약자가 CD라서 그렇습니다.
- Continuous Delivery(지속적 전달)
- Continuous Deployment(지속적 배포)
이 둘의 차이를 저는 이렇게 외웠습니다. Delivery(전달)는 "버튼 하나만 남겨두는 것"이고, Deployment(배포)는 "그 버튼마저 없애고 자동으로 끝까지 가는 것"입니다. 두 단어가 워낙 비슷하게 생겨서, 사실 원어민 개발자들도 종종 헷갈려 합니다. 그러니 "나만 헷갈리나?" 하고 자책하지 마세요. 둘의 공통점은 "배포 직전까지는 무조건 자동"이라는 거고, 차이점은 "마지막 배포 순간에 사람이 손을 대느냐 마느냐" 딱 그것 하나뿐입니다.
요리 컨베이어로 다시 볼게요. 검수와 조리, 접시에 담기까지 전부 자동으로 끝나서 음식이 '나갈 준비 완료' 상태로 대기하고 있습니다. 여기서 마지막에 사람이 "자, 이거 손님상에 내가!" 하고 벨을 한 번 눌러야 나가면 그게 Delivery입니다. 반대로 그 벨조차 필요 없이, 준비되는 즉시 자동으로 손님상까지 나가면 그게 Deployment고요.
| 구분 | Continuous Delivery (지속적 전달) | Continuous Deployment (지속적 배포) |
|---|---|---|
| 한 줄 요약 | 버튼 한 번만 누르면 배포 | 버튼도 없이 자동 배포 |
| 사람의 개입 | 마지막 '배포 승인'은 사람이 | 사람 개입 없음(전 과정 자동) |
| 비유 | 음식 준비 끝, 나가라는 벨만 남음 | 준비되는 즉시 손님상까지 자동 |
| 장점 | 마지막에 사람이 한 번 확인 가능 | 가장 빠르고 손이 안 감 |
| 어울리는 곳 | 신중해야 하는 서비스, 규제 있는 업종 | 테스트가 탄탄하고 자주 배포하는 팀 |
초보 입장에서는 이 구분에 너무 매달릴 필요는 없습니다. 대부분 그냥 뭉뚱그려 "CI/CD"라고 부르거든요. 다만 누군가 "우리는 Delivery까지만 자동이고 배포는 사람이 승인해요"라고 하면, "아, 마지막 벨은 사람이 누르는 방식이구나" 하고 알아들으시면 됩니다.
그럼 둘 중 뭐가 더 좋은 걸까요? 정답은 없습니다. 서비스의 성격에 따라 다릅니다. 예를 들어 은행이나 병원처럼 한 번의 실수가 큰 사고로 이어지는 곳은, 마지막에 사람이 한 번 더 눈으로 확인하는 Delivery 방식을 선호합니다. "자동으로 다 준비는 해두되, 진짜 내보내는 결정은 책임자가 한다"는 거죠. 반대로 하루에도 수십 번씩 자잘한 개선을 내보내는 서비스라면, 그때마다 사람이 버튼을 누르는 게 오히려 병목입니다. 그래서 테스트를 아주 촘촘히 깔아두고 벨까지 자동으로 눌러버리는 Deployment로 갑니다.
제가 드리고 싶은 조언은 이겁니다. 처음엔 무조건 Delivery로 시작하세요. 자동으로 준비까지만 해두고, 마지막 배포 버튼은 내가 직접 누르는 겁니다. 자동화가 어디까지 잘 도는지 내 눈으로 몇 번 확인하고 신뢰가 쌓인 뒤에, 그때 버튼을 없애도 늦지 않아요. 처음부터 끝까지 다 자동으로 맡겼다가 놀라는 것보다, 한 발씩 자동화의 고삐를 풀어주는 편이 훨씬 마음이 편합니다.
운전을 배울 때를 떠올려보세요. 처음부터 눈 감고 자율주행에 맡기는 사람은 없죠. 손에 익을 때까지는 내가 핸들을 잡고, 브레이크에 발을 올려두고 다닙니다. 그러다 도로가 익숙해지면 조금씩 긴장을 풀고요. CI/CD도 똑같습니다. 마지막 배포 버튼을 내 손에 쥐고 있는 Delivery 단계가 바로 그 '초보 운전' 시기예요. 서두르지 않아도 됩니다. 내가 편해지는 속도에 맞춰서 자동화를 늘려가면 돼요.
파이프라인이 뭔가요 — 컨베이어 벨트 그 자체
CI/CD 얘기를 하면 꼭 파이프라인(pipeline)이라는 단어가 나옵니다. 저를 그렇게 겁줬던 그 '파이프'요. 그런데 별거 아닙니다. 파이프라인은 그냥 "코드가 실제 서비스가 되기까지 거쳐 가는 컨베이어 벨트 전체"를 말합니다.
공장 컨베이어 벨트를 떠올려보세요. 한쪽 끝에 재료를 올리면, 벨트를 따라 흘러가면서 여러 작업대를 차례로 통과하고, 반대쪽 끝에서 완제품이 나옵니다. CI/CD 파이프라인도 똑같습니다. 한쪽 끝에 코드를 올리면(push), 정해진 단계들을 차례로 통과해서, 반대쪽 끝에서 '배포된 서비스'가 나옵니다.
재료 올리기
조립하기
맛보기
시식용 상차림
손님상으로
여기서 중요한 게 하나 있습니다. 이 벨트는 중간에 문제가 생기면 자동으로 멈춘다는 겁니다. 테스트에서 하나라도 실패하면, 벨트가 딱 멈추고 그다음 단계(배포)로 넘어가지 않아요. 상한 재료가 들어오면 컨베이어가 스톱하는 겁니다. 그래서 망가진 코드가 실제 서비스까지 흘러가는 사고를 막아줍니다. 이게 손빨래 시절엔 없던, CI/CD의 가장 든든한 안전장치예요.
그리고 단계의 순서에도 다 이유가 있습니다. 왜 빌드가 테스트보다 먼저고, 테스트가 배포보다 먼저일까요? 값싸고 빠른 검사를 앞에 두고, 비싸고 위험한 일을 뒤에 두기 위해서입니다. 조립조차 안 되는 코드라면 테스트를 돌려볼 것도 없이 바로 걸러내는 게 이득이죠. 마찬가지로 테스트에서 걸릴 코드라면 배포까지 갈 것도 없이 앞에서 멈추는 게 안전하고요. 이렇게 "싼 검사 → 비싼 검사 → 진짜 배포" 순서로 걸러내면, 문제를 가장 빠르고 저렴하게 잡아낼 수 있습니다. 공항 보안검색을 여러 겹으로 두는 것과 같은 원리예요.
여기서 한 가지 오해를 풀고 갈게요. 파이프라인이라고 하면 뭔가 거창한 설비를 새로 사서 설치해야 할 것 같지만, 실제로는 글로 적은 순서표 한 장에 가깝습니다. "이런 일이 생기면(트리거), 이 순서대로 이걸 해라(단계들)"를 텍스트 파일 하나에 적어두면, 도구가 그걸 읽고 그대로 실행해주는 거예요. 그래서 이 순서표를 "코드로 된 설정(configuration as code)"이라고도 부릅니다. 순서가 코드로 남으니, 아까 말한 "그 사람 머릿속에만 있던 배포법" 문제가 자연히 사라집니다. 누구나 그 파일만 열어보면 우리 팀이 어떻게 배포하는지 알 수 있으니까요.
또 하나 기억할 만한 점은, 파이프라인은 한 번에 완성하는 게 아니라 자라난다는 겁니다. 처음엔 "빌드만 확인" 하는 아주 짧은 벨트로 시작해서, 익숙해지면 테스트를 붙이고, 그다음 스테이징을 붙이고, 마지막에 자동 배포까지 얹는 식이죠. 저도 처음부터 다섯 단계를 다 만들지 않았어요. 두 칸짜리 벨트로 시작해서 조금씩 칸을 늘려갔습니다. 그러니 "이 많은 걸 언제 다 하지?" 하고 지레 겁먹지 마세요.
파이프라인의 각 단계 하나씩 뜯어보기
이제 컨베이어의 작업대들을 하나씩 살펴볼게요. 각 단계가 무슨 일을 하는지만 알면, 나중에 실제로 만들 때도 전혀 안 무섭습니다.
소스 / 트리거 — "벨트를 언제 돌릴까"
파이프라인이 언제 시작될지를 정하는 신호입니다. 보통 "누군가 코드를 push하면" 또는 "PR을 올리면" 자동으로 벨트가 돌기 시작해요. 요리사가 재료를 컨베이어에 올려놓는 순간, 센서가 감지해서 기계가 켜지는 거죠. 이걸 트리거(trigger, 방아쇠)라고 부릅니다.
빌드 — "재료를 하나의 음식으로 조립"
흩어진 코드 파일들과 필요한 부품들을 모아서, 실제로 돌아갈 수 있는 하나의 결과물로 만드는 단계입니다. 이 단계에서 애초에 조립이 안 되면(오타 하나로도 그럴 수 있어요) 벨트가 여기서 멈춥니다. 덕분에 "내 컴퓨터에선 됐는데 서버에선 안 되네?" 하는 사고를 미리 잡습니다.
자동 테스트 — "내가기 전에 맛보기"
미리 만들어둔 검사 항목들을 컴퓨터가 하나하나 자동으로 돌려봅니다. "덧셈이 맞나? 로그인 되나? 결제가 되나?" 사람이 매번 손으로 클릭해가며 확인하던 걸 기계가 몇 초 만에 끝내줍니다. 하나라도 실패하면 여기서 벨트가 멈추고, 개발자에게 "몇 번 검사가 실패했다"고 알려줍니다.
배포 — "드디어 손님상으로"
모든 검사를 통과한 결과물을 실제 서버에 올립니다. 손빨래 시절엔 FTP로 벌벌 떨며 하던 그 일을, 이제 기계가 정해진 순서 그대로 정확하게 처리합니다. 사람이 손댈 일이 없으니 실수도 없어요.
롤백 — "이상하면 어제 상태로 되돌리기"
배포했는데 뭔가 문제가 생겼다면? 좋은 파이프라인은 '바로 직전 멀쩡했던 버전'으로 순식간에 되돌릴 수 있게 해줍니다. 새 메뉴가 이상하다는 컴플레인이 들어오면, 검증된 예전 메뉴로 즉시 바꿔 내는 셈이죠. 이 '되돌리기(rollback)'가 있어서 자동 배포가 무섭지 않은 겁니다.
보세요. 다섯 단계뿐입니다. 그리고 그중 사람이 신경 쓸 건 사실상 1번(코드 잘 올리기)과, 문제 생겼을 때 5번(되돌리기 버튼 누르기)뿐이에요. 나머지 2·3·4번은 기계가 다 합니다.
실제로는 이렇게 흘러갑니다 — 어느 하루
말로만 하면 감이 잘 안 오실 테니, 실제 하루를 그려볼게요. 제가 오타 하나를 고쳤다고 해봅시다. 버튼 색깔을 바꾸는 아주 사소한 수정이에요.
오전 10시 3분, 저는 코드를 고치고 git push 한 줄을 칩니다. 여기까지가 제 일의 전부예요. 그다음부터는 제가 커피를 타러 가는 동안 컨베이어가 알아서 돕니다. 10시 3분 30초, 트리거가 "어? 새 코드가 올라왔네" 하고 벨트를 켭니다. 10시 4분, 빌드가 시작돼 코드가 제대로 조립되는지 확인합니다. 통과. 10시 5분, 자동 테스트가 수십 개의 검사 항목을 좌르륵 돌립니다. 로그인도 되고, 계산도 맞고, 버튼도 눌립니다. 전부 초록불. 10시 7분, 배포가 시작되고 실제 서버에 새 코드가 올라갑니다. 10시 8분, 제 커피가 아직 안 식었는데 이미 사이트의 버튼 색이 바뀌어 있습니다.
만약 이 과정 중 어디선가 문제가 생겼다면요? 예를 들어 10시 5분 테스트에서 "로그인 검사 실패"가 떴다고 칩시다. 그 순간 벨트는 딱 멈추고, 배포는 진행되지 않습니다. 그리고 제 화면(또는 메신저)에 "테스트 실패: 로그인 검사"라는 빨간 알림이 뜹니다. 저는 커피잔을 내려놓고 그 부분만 고쳐서 다시 push하면 되죠. 망가진 버튼이 손님에게 나가는 일은 없었습니다. 손빨래 시절이었다면 그냥 배포해버리고, 손님 항의를 받고 나서야 부랴부랴 고쳤을 상황이에요.
이 하루 시나리오가 CI/CD의 전부입니다. 화려하지 않아요. 그냥 지루할 만큼 조용하고 정확하게, 매번 똑같이 돌아갑니다. 그리고 바로 그 '지루한 정확함'이 우리가 원하던 겁니다. 배포는 스릴 넘치는 이벤트가 아니라, 물 흐르듯 조용한 일상이 되어야 하니까요.
여기에 하나만 더 얹자면, 좋은 파이프라인은 배포로 끝나지 않고 배포 이후를 지켜보는 눈까지 갖춥니다. 배포가 됐다고 끝이 아니라, "새 코드가 실제로 잘 돌아가고 있나? 에러가 갑자기 늘진 않았나?"를 계속 관찰하는 거죠. 컨베이어로 음식을 내보낸 뒤에도 홀을 살피며 손님 반응을 확인하는 것과 같습니다. 이 관찰(모니터링) 덕분에, 문제가 생기면 손님이 항의하기 전에 우리가 먼저 알아채고 롤백할 수 있습니다. 이 부분은 조금 더 깊은 주제라 여기서는 "배포 후에도 지켜본다" 정도만 기억해두시면 충분해요.
CI/CD가 정말로 뭘 바꿔주나 — 수동 배포와 나란히 비교
"그래서 이걸 하면 뭐가 좋은데요?"라는 질문에 답할 차례입니다. 제가 직접 손빨래 배포와 세탁기 배포를 다 겪어본 사람으로서, 솔직하게 비교해드릴게요.
👎 수동 배포 (손빨래)
- 배포 한 번에 30분~몇 시간씩 걸림
- 파일 빠뜨리기, 덮어쓰기 같은 실수가 잦음
- 무서워서 자주 못 하고, 한꺼번에 몰아서 배포
- 몰아서 하니 문제 생기면 원인 찾기 어려움
- 문제 나면 되돌리기도 손으로, 그것도 벌벌 떨며
- "그 사람만 배포할 줄 앎" — 특정인에게 의존
👍 CI/CD (세탁기)
- 코드 저장하면 몇 분 만에 자동 배포
- 정해진 순서를 기계가 처리 → 사람 실수 제거
- 겁이 안 나니 작게, 자주 배포 가능
- 조금씩 배포하니 문제 나도 원인이 좁혀짐
- 문제 나면 버튼 한 번(혹은 자동)으로 롤백
- 절차가 코드로 남아 누구나 배포 가능
제가 가장 크게 체감한 건 세 번째, "작게 자주"였습니다. 수동 배포 시절엔 배포가 무서우니까 웬만하면 미뤘어요. 그러다 2주치를 한 번에 올리니 어디서 뭐가 터졌는지 알 수가 없었죠. CI/CD를 붙이고 나선 하루에도 몇 번씩 작게작게 올렸습니다. 뭐가 잘못돼도 방금 올린 그 작은 변경만 보면 되니, 원인 찾기가 훨씬 쉬워졌어요. 이 '작게 자주'가 주는 안정감은 정말 큽니다.
두 번째로 크게 느낀 건 마음의 평화였습니다. 이건 표에 잘 안 적히는 항목인데요, 손빨래 시절엔 배포 버튼을 누를 때마다 심장이 쫄깃했어요. "이번엔 안 터지겠지?" 하는 불안 속에서요. 그런데 CI/CD를 붙이고 나선, 어차피 테스트를 통과 못 하면 배포가 안 되니까 마음이 편해지더라고요. 벨트에 안전장치가 달려 있다는 걸 아니까, 재료를 올려놓고 커피 한 잔 마시러 갈 수 있게 된 겁니다. 이 심리적 여유가 생각보다 일의 질을 많이 바꿔놓습니다.
물론 CI/CD가 만능은 아닙니다. 초기에 컨베이어를 세팅하는 수고가 들고, 테스트를 갖추는 데도 시간이 필요합니다. 도구를 익히는 학습 곡선도 있고요. 하지만 이건 세탁기를 처음 사서 설치하고 사용법을 익히는 것과 같습니다. 처음 하루 이틀은 귀찮지만, 그 뒤로 평생 빨래를 손으로 안 해도 되잖아요. 초기 비용을 조금 치르고 나면, 그 뒤로는 계속 이득만 쌓입니다.
그리고 이 이득은 시간이 갈수록 복리처럼 불어납니다. 배포를 100번 한다고 치면, 손빨래 방식은 매번 똑같이 긴장하고 똑같이 시간을 씁니다. 100번이면 그 고생이 고스란히 100배죠. 반면 CI/CD는 처음 한 번 세팅하는 수고만 치르면, 그다음 99번은 거의 공짜로 따라옵니다. 배포를 많이 하는 프로젝트일수록 이 차이는 어마어마하게 벌어져요. 그래서 저는 "이 프로젝트를 앞으로도 계속 고쳐나갈 건가?"라는 질문에 '그렇다'는 답이 나오면, 웬만하면 초반에 컨베이어부터 깔라고 권합니다.
역설적이게도, 자주 배포할수록 배포가 안전해집니다. 큰 배를 어쩌다 한 번 옮기는 것보다, 작은 조각배를 여러 번 옮기는 게 뒤집힐 위험이 적으니까요.
이 역설을 한 번 더 풀어드리고 싶어요. 많은 분이 "배포는 위험하니까 되도록 적게 하는 게 안전하다"고 생각합니다. 손빨래 시절엔 맞는 말이었어요. 배포 자체가 사고 덩어리였으니까요. 그런데 CI/CD를 붙이면 이 상식이 뒤집힙니다. 배포가 안전하고 값싸지니까, 오히려 자주 할수록 각 배포의 덩치가 작아지고, 덩치가 작으니 사고 확률도 줄고, 사고가 나도 되돌리기가 쉬워지는 선순환이 생깁니다. "무서우니까 미룬다"가 "안전하니까 자주 한다"로 바뀌는 거죠. 이 사고방식의 전환이야말로 CI/CD가 가져다주는 가장 값진 변화라고 저는 생각합니다.
나에게도 CI/CD가 필요할까 — 도입 신호들
"좋은 건 알겠는데, 나처럼 작게 하는 사람에게도 필요한가요?" 아주 좋은 질문입니다. 모든 상황에 CI/CD가 반드시 필요한 건 아니에요. 예를 들어 딱 한 번 만들고 다시는 안 고칠 페이지라면, 굳이 컨베이어를 세우는 수고가 아까울 수 있습니다. 그래서 "이런 신호가 보이면 도입할 때가 됐다"는 기준을 몇 개 드릴게요.
같은 배포 작업을 반복하고 있다
매번 똑같은 파일 올리기, 똑같은 명령 치기를 손으로 반복하고 있다면, 그건 기계에게 넘기라는 신호입니다. 컴퓨터는 반복을 지치지도 틀리지도 않고 해내니까요.
배포할 때마다 긴장된다
배포가 무섭다는 건 그만큼 실수 여지가 많다는 뜻입니다. 그 두려움 자체가 자동화가 필요하다는 가장 정직한 신호예요.
같이 만드는 사람이 생겼다
혼자일 땐 대충 넘어가도, 둘만 돼도 코드 충돌과 "누가 뭘 올렸지?" 문제가 시작됩니다. 이때가 CI를 붙이기 딱 좋은 시점입니다.
배포하고 나서야 버그를 발견한다
손님상에 나가고 나서 음식이 상한 걸 알면 이미 늦죠. 자동 테스트를 앞단에 두면, 문제를 손님이 아니라 컨베이어가 먼저 잡습니다.
이 중 두 개 이상 고개가 끄덕여진다면, 지금이 시작할 때입니다. 반대로 하나도 해당 안 되면, 아직은 급하지 않으니 개념만 알아두고 넘어가셔도 괜찮아요. 도구는 필요할 때 붙이면 되는 거니까요. 다만 한 가지, "지금은 작으니까 나중에" 하고 계속 미루다 보면, 정작 프로젝트가 커져서 정말 필요해졌을 땐 이미 손댈 곳이 너무 많아져 있는 경우가 많습니다. 작을 때 세팅해두면 컨베이어도 작아서 만들기 쉽고, 프로젝트와 함께 자연스럽게 자라납니다. 그러니 "조금 이르다 싶을 때"가 사실 가장 좋은 타이밍이에요.
대표 도구들 — 뭘로 컨베이어를 만들까
CI/CD는 개념이고, 그걸 실제로 굴려주는 '컨베이어 기계'에 해당하는 도구들이 여럿 있습니다. 이름만 들어보셨을 법한 것들을 한 줄씩 정리했어요. 지금 다 외울 필요는 전혀 없습니다. "아, 이런 것들이 있구나" 정도면 충분해요.
| 도구 | 한 줄 특징 |
|---|---|
| GitHub Actions | 코드를 GitHub에 올려 쓴다면 별도 설치 없이 바로 시작. 설정이 비교적 직관적이라 입문에 부담이 적음 |
| GitLab CI | GitLab을 쓰는 팀이라면 자연스럽게 딸려오는 CI/CD. 저장소와 한 몸처럼 붙어 있음 |
| Jenkins | 오래되고 강력하며 자유도가 높음. 대신 직접 설치·관리해야 하고 설정 손이 많이 가는 편 |
| CircleCI | 클라우드 기반 CI/CD 서비스. 속도와 설정 편의를 강점으로 내세움 |
이 밖에도 도구는 많습니다. 그런데 지금 막 시작하는 분, 특히 비개발자거나 소규모 프로젝트라면 저는 개인적으로 GitHub Actions로 첫발을 떼보시길 권합니다. 이미 많은 분이 코드를 GitHub에 올려 쓰고 있고, 그렇다면 추가로 뭘 설치할 것도 없이 파일 하나만 만들면 바로 컨베이어가 돌기 때문이에요. 물론 "무조건 이게 정답"은 아닙니다. 팀이 이미 다른 도구를 쓰고 있다면 그걸 따라가는 게 맞고요. 다만 "혼자 처음 배워본다"면 진입 문턱이 낮은 쪽이 좋다는 이야기입니다. GitHub Actions로 실제 컨베이어를 만들어보는 실습은 GitHub Actions 글에서 손잡고 따라 해봅니다.
도구를 고를 때 초보가 흔히 저지르는 실수가 있습니다. "어떤 게 제일 좋은 도구인가"를 며칠씩 검색하며 비교표만 만들다가, 정작 아무것도 시작 못 하는 거예요. 저도 그랬습니다. 그런데 돌아보면 그 시간에 그냥 아무거나 하나 골라서 컨베이어를 한 번 돌려봤으면 훨씬 많이 배웠을 겁니다. 도구는 나중에 얼마든지 바꿀 수 있어요. 개념이 같으니까요. 완벽한 선택보다 일단 시작이 백 배 낫습니다.
그럼 무료로 쓸 수 있냐고요? 대부분 개인이나 소규모가 가볍게 쓸 만한 무료 범위를 제공합니다. 다만 얼마나 오래, 얼마나 많이 돌릴 수 있는지 같은 조건은 서비스마다 다르고 수시로 바뀌니, 정확한 건 각 도구의 공식 요금 페이지에서 확인하시는 게 안전합니다. 제가 여기서 "얼마까지 무료"라고 숫자를 적어드리면, 이 글을 나중에 읽는 분께 틀린 정보가 될 수 있거든요.
아주 간단한 개념 예시 — 말로 먼저, 그다음 코드 흉내만
이제 딱 한 번, 코드 비슷한 걸 보여드릴게요. 겁먹지 마세요. 외우라는 것도, 지금 따라 치라는 것도 아닙니다. "아, 이렇게 생겼구나" 하고 눈에 익히기만 하면 됩니다. 저도 처음 이런 파일을 봤을 땐 외계어 같았는데, 몇 번 들여다보니 결국 "언제, 무엇을, 어떤 순서로"를 적은 목록일 뿐이더라고요.
먼저 우리가 만들고 싶은 걸 말로 풀어볼게요. 이렇게 하고 싶은 겁니다.
"main이라는 대표 코드 창고에 새 코드가 올라오면(push), 자동으로 테스트를 돌려라. 테스트를 통과하면, 그때 서버에 배포해라."
이걸 CI/CD 도구가 알아듣는 형태(YAML이라는 형식)로 적으면 대략 이런 느낌입니다. 한 줄씩 무슨 뜻인지 옆에 풀어드릴게요.
| 개념 코드(느낌만) | 사람 말로 풀면 |
|---|---|
on: push (main) | "main 창고에 코드가 올라오면 벨트를 돌려라" (트리거) |
jobs: | "할 일 목록은 다음과 같다" |
- run: 테스트 | "먼저 자동 테스트를 돌려라" (통과 못 하면 여기서 멈춤) |
- run: 배포 | "테스트를 통과했으면 이제 서버에 배포해라" |
정말 이게 다예요. "언제(on) → 무슨 일들을(jobs) → 어떤 순서로(run 목록)". 마치 요리 레시피 같죠? "손님이 주문하면 → 이 재료들로 → 이 순서대로 조리해라." CI/CD 설정 파일은 결국 컨베이어에게 주는 레시피 카드일 뿐입니다.
혹시 YAML이라는 말에 또 겁이 나셨나요? 이것도 별거 아닙니다. YAML은 그냥 사람이 읽기 편하게 만든 '목록 적는 형식'이에요. 프로그래밍 언어가 아니라, 장 볼 목록이나 할 일 목록을 들여쓰기로 정리해둔 메모지에 가깝습니다. 규칙이라고 해봐야 "줄 맞춰서 들여쓰기 잘하기" 정도가 거의 전부고요. 실제로 CI/CD를 시작할 때는 이 YAML을 백지에서 쓰는 게 아니라, 잘 만들어진 예시를 복사해와서 이름 몇 개만 내 것으로 바꾸는 식으로 합니다. 그러니 "형식을 외워야 한다"는 부담은 완전히 내려놓으셔도 됩니다.
여기서 main이라는 대표 창고, 그리고 코드를 합치기 전에 검토받는 절차 같은 이야기가 궁금하시면 브랜치 전략 글과 PR·코드리뷰 글을 먼저 보고 오시면 훨씬 잘 이해됩니다. CI/CD는 그 위에 얹히는 자동화라, 창고와 합치기 개념을 알면 그림이 한번에 그려지거든요.
조금 더 현실적인 그림을 그려볼게요. 실제 팀에서는 보통 이렇게 씁니다. 어떤 개발자가 새 기능을 만들어서 PR(합쳐달라는 요청)을 올리면, 그 순간 CI가 자동으로 돌면서 "이 코드 합쳐도 안전한지" 검사합니다. 검사가 초록불이면 그때 사람이 코드를 리뷰하고 합치기(merge)를 하고요. 그렇게 main 창고에 합쳐지는 순간, 이번엔 CD가 자동으로 돌면서 실제 서버에 배포합니다. 즉 CI는 '합치기 전 문지기', CD는 '합친 뒤 배달부' 역할을 하는 셈이에요. 이 둘이 한 세트로 맞물려 돌아가는 게 CI/CD입니다.
이 흐름의 아름다운 점은, 사람은 '판단'만 하고 '노동'은 기계가 한다는 데 있습니다. 코드가 좋은지 나쁜지 판단(리뷰)은 사람이 하되, 검사하고 조립하고 나르는 반복 노동은 전부 컨베이어가 하는 거죠. 사람의 시간을 정말 사람다운 일에 쓰게 해준다는 점에서, 저는 CI/CD가 단순한 편의 도구를 넘어선다고 생각합니다.
초보가 흔히 밟는 지뢰 & 해결법
제가 직접 밟아본 지뢰들입니다. 미리 알아두면 안 밟으실 수 있어요.
👎 이렇게 하면 사고 납니다
- 테스트 없이 자동 배포 — 검사 항목이 하나도 없는데 자동 배포만 켜두면, 망가진 코드가 그대로 손님상까지 직행합니다. 안전장치 없는 컨베이어예요.
- 비밀키를 코드에 그대로 적기 — 서버 비밀번호, API 열쇠 같은 걸 코드 파일에 적어 올리면, 창고를 보는 모든 사람에게 열쇠를 나눠주는 꼴입니다.
- 실패 알림 무시 — 빨간불(테스트 실패)이 떴는데 "나중에 봐야지" 하고 계속 쌓아두면, 나중엔 뭐가 진짜 문제인지 분간이 안 됩니다.
- 롤백 방법을 안 만들어둠 — 배포는 자동인데 되돌리는 법을 모르면, 사고 났을 때 손빨래 시절보다 더 당황합니다.
👍 이렇게 하세요
- 작게라도 테스트를 먼저 — 완벽하지 않아도 됩니다. "핵심 기능 몇 개라도 검사"부터 시작하세요. 컨베이어에 센서를 다는 겁니다.
- 비밀값은 '시크릿(secret)'으로 — 대부분의 도구엔 비밀값을 안전하게 따로 보관하는 금고 기능이 있습니다. 코드엔 "금고에서 꺼내 쓴다"고만 적으세요.
- 빨간불은 그 즉시 처리 — 실패하면 벨트가 멈춰 있는 상태입니다. 바로 고쳐서 초록불로 만드는 걸 습관으로.
- 롤백을 미리 연습 — 사고 나기 전에 "되돌리기"를 한 번 해보세요. 실제 상황에서 안 떨립니다.
비밀키 이야기를 조금만 더 할게요. 왜 이게 그렇게 위험한지 실감이 안 날 수 있거든요. 코드 창고(특히 공개 창고)는 생각보다 많은 사람이 들여다볼 수 있고, 심지어 이런 비밀키만 자동으로 훑어 찾아내는 프로그램들이 24시간 돌아다닙니다. 서버 비밀번호나 결제 열쇠를 코드에 적어 올리는 순간, 그건 대문에 열쇠를 테이프로 붙여두는 것과 같아요. "설마 누가 보겠어"가 아니라 "반드시 누군가 본다"고 생각하셔야 합니다. 그래서 비밀값은 항상 도구가 제공하는 금고(시크릿)에 넣어두고, 코드에는 "금고 3번 칸에서 꺼내 써"라는 이름표만 적는 겁니다.
또 하나 초보가 자주 하는 실수는 테스트를 형식적으로만 만드는 것입니다. 검사 항목을 만들긴 했는데, 실제로는 아무것도 제대로 확인하지 않는 '무늬만 테스트' 말이에요. 이러면 초록불은 뜨는데 실제로는 아무 보장이 없는, 가짜 안심을 하게 됩니다. 센서가 달려는 있는데 전원이 꺼진 컨베이어인 셈이죠. 테스트는 개수가 아니라 "정말 중요한 걸 확인하고 있는가"가 핵심입니다. 로그인, 결제, 핵심 계산처럼 깨지면 큰일 나는 것부터 검사하세요.
자주 묻는 질문(FAQ)
Q. 저는 혼자 개발하는데도 CI/CD가 필요한가요?
A. "여러 명이 합칠 때" 유용한 CI 부분은 혼자면 덜 중요할 수 있습니다. 하지만 "저장하면 자동 검사·배포"라는 CD의 편안함은 혼자여도 아주 큽니다. 배포 실수로 밤을 새워본 적 있다면, 혼자라도 충분히 값어치를 합니다. 게다가 '혼자'라는 건 다르게 말하면 '나 말고 실수를 잡아줄 사람이 없다'는 뜻이기도 해요. 그럴수록 기계 문지기 하나가 옆에 있는 게 든든합니다.
Q. 롤백은 정말 버튼 하나로 되나요? 데이터도 되돌아가나요?
A. 코드를 이전 버전으로 되돌리는 건 잘 갖춰두면 정말 간단합니다. 다만 주의할 점이 있어요. 데이터(예: 고객이 그새 입력한 정보)까지 저절로 되돌아가는 건 아닙니다. 코드는 어제로 돌려도, 그사이 쌓인 데이터는 그대로 남아요. 그래서 데이터 구조를 크게 바꾸는 배포는 롤백이 까다롭습니다. 초보 단계에서는 "코드 롤백은 쉽다, 데이터가 얽히면 신중해야 한다" 정도만 기억해두시면 충분합니다.
Q. 코딩을 잘 못하는데 CI/CD 설정을 할 수 있을까요?
A. 할 수 있습니다. 앞에서 봤듯이 설정 파일은 "언제 → 무슨 일 → 어떤 순서"를 적는 레시피 카드 수준이에요. 게다가 요즘은 잘 만들어진 예시(템플릿)를 복사해서 조금만 고쳐 쓰는 경우가 대부분입니다. 처음부터 백지에 쓰는 게 아니에요. 도구들도 "이런 프로젝트라면 이 설정으로 시작하세요" 하고 기본 틀을 제안해주는 경우가 많으니, 그걸 받아서 이름 몇 개만 바꾸면 첫 컨베이어가 돕니다.
Q. 테스트 코드를 아직 하나도 안 만들었어요. CI/CD 시작하면 안 되나요?
A. 시작해도 됩니다. 처음엔 "빌드가 되는지"만 확인하는 아주 얇은 파이프라인으로 출발해도 충분합니다. 그것만으로도 "조립조차 안 되는 코드"가 배포되는 걸 막아줘요. 테스트는 나중에 하나씩 늘려가면 됩니다.
Q. CI/CD를 쓰면 배포가 정말 몇 초 만에 되나요?
A. 프로젝트 크기에 따라 다릅니다. 작으면 몇 분, 크면 더 걸리기도 해요. 중요한 건 '얼마나 빠른가'보다 '사람이 손 안 대고 정확하게 반복되는가'입니다. 시간은 나중에 줄여나가는 항목이에요.
Q. GitHub Actions, Jenkins… 어느 걸 배워야 손해가 없을까요?
A. 개념은 도구마다 거의 같아서, 하나를 제대로 익히면 다른 걸로 갈아타기 쉽습니다. 그러니 "가장 빨리 성취감을 볼 수 있는 것"부터 하세요. 코드를 GitHub에 올려 쓰신다면 GitHub Actions가 그 출발점으로 무난합니다. 도구 선택에 너무 오래 고민하지 마시고, 일단 하나로 컨베이어가 도는 걸 눈으로 보는 게 훨씬 남습니다.
Q. CI/CD랑 DevOps는 같은 말인가요?
A. 아니에요. DevOps는 "개발(Dev)과 운영(Ops)을 벽 없이 하나로 묶어 빠르고 안정적으로 서비스를 굴리자"는 더 큰 문화이자 사고방식입니다. CI/CD는 그 문화를 실현하는 대표적인 '도구이자 실천법' 중 하나고요. 즉 CI/CD는 DevOps라는 큰 그림 안의 핵심 조각입니다. 큰 그림이 궁금하시면 DevOps 시리즈 개요를 참고하세요.
Q. 배포가 자동이면, 잘못된 코드도 자동으로 나가서 더 위험한 거 아닌가요?
A. 아주 날카로운 걱정인데, 사실은 반대입니다. 자동 배포에는 항상 테스트라는 문지기가 앞에 서 있어서, 검사를 통과 못 한 코드는 애초에 나가질 못합니다. 오히려 사람이 손으로 하던 시절이 검사 없이 그냥 올리는 경우가 많아 더 위험했어요. 물론 이건 "테스트를 제대로 갖췄을 때" 이야기입니다. 그래서 테스트 없이 자동 배포만 켜는 건 앞에서 지뢰라고 짚었던 거고요.
마무리 — 오늘의 체크리스트
여기까지 오셨으면, 이제 "CI/CD 파이프라인 구축"이라는 말이 더는 무섭지 않으실 겁니다. 결국 귀찮고 실수 잦은 배포 일을 기계에게 넘기는 것, 그게 전부니까요. 손빨래를 세탁기에 맡기듯이요.
처음 이 글을 열 때 "CI/CD? 나랑은 먼 이야기겠지"라고 생각하셨다면, 지금은 조금 달라지셨길 바랍니다. 이건 대단한 엔지니어들만의 전유물이 아니라, 배포 실수로 한 번이라도 마음 졸여본 사람이라면 누구나 누릴 자격이 있는 편안함이에요. 코딩을 늦게 시작한 저 같은 사람도 결국 이 세탁기를 돌리고 있으니까요. 여러분이라고 못 할 리 없습니다.
- ✅ CI = 여러 명의 코드를 자주 합치고, 합칠 때마다 자동 검사(빌드+테스트)
- ✅ CD = 검사 통과한 코드를 자동으로 전달(버튼 하나) 또는 배포(버튼도 없이)
- ✅ 파이프라인 = push → 빌드 → 테스트 → (스테이징) → 배포로 이어지는 컨베이어 벨트
- ✅ 문제 생기면 벨트가 자동으로 멈추고, 배포 후엔 롤백으로 되돌린다
- ✅ 비밀키는 절대 코드에 넣지 말고 시크릿(금고)으로
- ✅ 처음엔 얇게 시작하고, 테스트는 작게라도 붙이며 늘려간다
혹시 이 글을 읽으면서도 "그래도 나한텐 좀 어려운 이야기 같은데…" 하는 마음이 드셨다면, 그 감정이 지극히 정상이라는 말씀을 꼭 드리고 싶어요. 저도 처음엔 이 모든 용어가 외국어처럼 들렸습니다. CI, CD, 파이프라인, 트리거, 스테이징, 롤백… 하나씩 뜯어보면 별거 아닌데, 한꺼번에 들으면 벽처럼 느껴지죠. 그런데 신기하게도, 실제로 컨베이어가 한 번 도는 걸 내 눈으로 보고 나면 이 모든 단어가 갑자기 익숙한 친구처럼 다가옵니다. 이해가 실습을 앞서는 게 아니라, 실습이 이해를 데려오는 경우가 훨씬 많거든요.
개념은 이걸로 충분합니다. 이제 남은 건 딱 하나, 직접 한 번 만들어보는 것이에요. 백 번 읽는 것보다 컨베이어가 실제로 도는 걸 한 번 보는 게 훨씬 오래 남습니다. 다음 글에서는 GitHub Actions로 아주 작은 CI/CD 파이프라인을 직접 만들어보기를 손잡고 함께 해볼게요. "코드 저장했더니 알아서 배포되는" 그 마법을, 이번엔 여러분 손으로 직접 부려보시는 겁니다. 거창하게 다섯 단계를 다 만들 필요도 없어요. 딱 "push하면 인사 한 줄 출력하기" 같은 아주 작은 벨트 하나만 돌려봐도, "아, 이거였구나!" 하는 순간이 옵니다.
이 글이 포함된 전체 흐름이 궁금하시면 DevOps 시리즈 개요에서 지도를 먼저 보고 오셔도 좋습니다. 그리고 CI/CD 다음 단계로 자연스럽게 이어지는 컨테이너 이야기도 준비돼 있으니, 배포 자동화가 손에 익으면 그쪽으로 넘어가 보세요. 겁먹지 마시고, 오늘도 한 걸음씩. 저도 그렇게 왔습니다.
(2026년 8월 기준 작성 — 화면·정책은 바뀔 수 있으니 공식 문서를 함께 확인하세요.)
← 기술 블로그 목록으로