Jenkins + Docker + Docker Compose CI 환경 구성기 (Feat. 고생길 오픈)
최근 개인 프로젝트에서 CI/CD를 좀 더 자동화해보고 싶어서 Jenkins를 띄웠다.
간단히 생각했다. Jenkins 띄우고, GitHub push 트리거 걸고, 테스트 빌드만 돌리면 끝 아니야?
근데 역시 개발이란 게 간단한 법이 없다.
이번 글은 Jenkins에서 Docker와 Docker Compose를 함께 사용하는 데 겪었던 삽질 + 해결 과정을 정리한 글이다.
결론부터 말하자면 아직 완전한 성공은 아니지만, 그 과정에서 많이 배웠고, 나중에 나처럼 시도할 사람에게 도움이 되면 좋겠다는 마음으로 남긴다.
1. 목표
- GitHub push 시 Jenkins에서 테스트 코드 실행
- 테스트 통과 시 docker-compose build 및 up 까지 자동으로 실행
- 필요한 환경: Spring Boot + MySQL
내 프로젝트는 Docker 기반으로 작동한다.
즉, 단순히 ./gradlew build로 끝나는 게 아니라, DB도 붙고, 설정 파일도 도커에 맞춰져 있어서 실제로 docker-compose up 해보지 않으면 아무것도 보장되지 않는다.
2. 처음의 접근: Jenkins 이미지 그대로 사용하기
처음엔 이렇게 docker-compose.yml을 구성했다.
jenkins:
image: jenkins/jenkins:lts
ports:
- "9090:8080"
volumes:
- ./jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/local/bin/docker:/usr/bin/docker
그리고 Jenkins Job 안에서 아래처럼 스크립트를 짰다.
./gradlew test
docker-compose up --build -d
근데 빌드 로그에서 다음과 같은 에러를 만났다.
/tmp/jenkinsxxxxx.sh: line 13: docker: command not found
응? docker 명령어를 못 찾는다고?
3. 원인: Jenkins 컨테이너 안에 docker 명령어가 없었다
그렇다. 내가 쓴 Jenkins 이미지 (jenkins/jenkins:lts)는 docker CLI 자체가 설치되어 있지 않았다.
심지어 docker.sock을 mount해놨는데도, docker 명령어가 없으니 아무 소용이 없었던 거다.
4. 해결 시도 1: Jenkins 컨테이너 내부에 수동으로 설치
Jenkins 컨테이너 안으로 들어가서 아래처럼 docker CLI를 설치해봤다.
apt-get update
apt-get install ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64] ..." > /etc/apt/sources.list.d/docker.list
apt-get update
apt-get install docker-ce docker-ce-cli
설치는 되었지만 문제는 컨테이너 재시작 시 초기화된다는 것.
그래서 Dockerfile을 따로 만들어 Jenkins 컨테이너를 커스터마이징하기로 결정했다.
5. 해결 시도 2: Dockerfile로 Jenkins + Docker CLI 이미지 만들기
FROM jenkins/jenkins:lts
USER root
RUN apt-get update && \
apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common && \
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - && \
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" && \
apt-get update && \
apt-get install -y docker-ce-cli
RUN usermod -aG docker jenkins
USER jenkins
이렇게 하고 docker-compose.yml에서는 기존에 쓰던 image: jenkins/jenkins:lts 대신 아래처럼 수정했다.
jenkins:
build:
context: .
dockerfile: jenkins/Dockerfile
그리고 다시 docker-compose up --build!
이번엔 docker 명령어는 잘 작동했다. 한 걸음 전진.
6. 다음 장벽: 도커 내부에서 또 다른 도커? 🌀
Docker Compose를 통해 띄운 Spring Boot + MySQL 서비스를 Jenkins가 내부에서 접근하려고 하니… 헬스 체크도 필요하고, 의존 서비스 간 통신도 제대로 되야 한다.
그래서 docker-compose up 직후 아래처럼 health check를 넣었다.
for i in {1..10}; do
if curl -s http://localhost:8080/actuator/health | grep UP; then
echo "서비스가 살아있습니다"
break
fi
echo "대기 중..."
sleep 3
done
이건 현재 설정 중이지만, 여전히 도커 네트워크 문제나 타이밍 이슈가 남아 있어서 안정화에는 시간이 더 필요해 보인다.
7. 느낀 점
- Jenkins는 뭐든 커스터마이징 가능한 게 장점이지만, 반대로 진입장벽이 높다
- GitHub Actions처럼 서버 없는 CI가 더 편하긴 하다
- 하지만 직접 환경을 구성하면서 Docker가 실제로 어떻게 도는지 깊게 이해할 수 있었다
- 아직 Jenkins에서 도커 환경 통합 테스트까지 완전 자동화한 건 아니지만, 이 과정은 굉장히 값진 경험이었다
8. 다음 목표
- docker-compose up 이후 실제 API 테스트 자동화
- 통합 테스트와 연동
- 실패 시 Slack 알림 등
지금까지 시도했던 내용들이다. 지피티에게 많이 물어본 만큼 해당 내용을 바탕으로 블로그를 작성해달라고 했다.
이 프로젝트를 손대기 시작한게 오래전이기도 하고.. 기억할 겸.. 근데 확실히 나보다 글을 일목요연하게 잘쓴다. 아직도 사람이라고 보기엔 어색한 문장들이 많긴 하지만 내용이 적절히 잘 들어갔으니 만족하고 있다.
다시 읽어보니 직접 실행은 안하고 지피티에게 듣기만 한 내용들도 있었는데, 뭐... 아직 해결은 못했다.
지금까지의 내용들이 정리가 되었으니 이제 계속 시도해보자.
일단 볼륨에 추가하는 것으로는 해결되지 않는 다는 것을 알게 되었다.
jenkins 이미지 안에 docker cli 를 설치해야하는 모양이었다.
다른 사람들 보면 빌드로 끝내서 docker compose up 을 시행하지 않는 방법에 대해서도 생각했는데.
지피티 말로써는 다음과 같은 결론이 나왔다.
🔍 왜 빌드만으로 부족할까?
./gradlew build는 다음까지만 확인해 줘:
- 코드가 잘 컴파일 되는지
- 단위 테스트가 잘 통과되는지
하지만 실제 문제는 아래에서 발생할 수 있어:
예시 상황빌드로는 확인 불가
DB 연결이 실제로 잘 되는가? | ❌ |
도커 환경에서 application.yml 설정이 잘 적용되는가? | ❌ |
JPA 쿼리가 MySQL에서 잘 작동하는가? | ❌ |
다른 컨테이너 (ex. Redis, Kafka) 와의 통신이 되는가? | ❌ |
그래서 docker-compose로 실제로 앱을 띄워보고 테스트해보는 건 매우 합리적인 선택이야.
https://cloudwithbass.tistory.com/33
[Jenkins] 젠킨스 파이프라인: 깃 푸시부터 인수 테스트까지
Continuous Delivery with Docker and Jenkins의 챕터 5까지 학습하며 만든 최종 Jenkinsfile입니다. git push하면 자동으로 파이프라인을 빌드하도록 콘솔에서 트리거를 구성했습니다.Jenkins 복습을 위해 스스로
cloudwithbass.tistory.com
이분의 블로그를 참고해서 계속 진행해본다
'공부용 > 스프링 || 스프링부트' 카테고리의 다른 글
[스프링 jenkins] ci/cd 마저하기 (0) | 2025.04.23 |
---|---|
[스프링] 목표 찾기 (0) | 2025.04.15 |
[스프링부트] 버그 수정기 (0) | 2025.03.26 |
테스트코드 작성하기 (0) | 2025.02.25 |
습관 체크 기능 제작하기 (0) | 2025.02.21 |