이번 포스트에서는 제 포트폴리오 프로젝트에서 Jenkins와 Docker를 사용하여 어떻게 CI/CD를 구축한지, 그 과정에서 겪은 여러 문제들과 그 해결 과정에 대해 이야기해보려고 합니다.
이 포스팅은 jenkins 서버와 운영서버를 구축하며 발생한 오류에 대해서 다루고, 서버를 어떻게 설치하고, 서버내에 docker 설치, jenkins설치, jenkins 기본설정 등에 대해서는 다른 블로그들에 정보가 많기 때문에 약소하게 다룰 예정입니다.
먼저, CI/CD란 무엇인지 간략하게 설명하겠습니다.
CI/CD는 지속적 통합(Continuous Integration)과 지속적 배포(Continuous Deployment)를 의미하는데, 이는 개발자들이 작업한 코드를 지속적으로 통합하면서 빠르고 효율적으로 어플리케이션을 빌드, 테스트, 배포할 수 있는 프로세스입니다.
- 프로젝트의 기본 구조
- 백엔드: Spring Boot
- 데이터베이스: MySQL
- 버전 관리: Git
- CI/CD: Jenkins
- 컨테이너화: Docker
- Jenkins와 Docker를 활용한 CI/CD 구성
Jenkins와 Docker를 사용해 CI/CD를 구성하는 주요 단계는 다음과 같습니다.
- Jenkins 서버 구축
- 소스코드 변경 감지를 위한 Webhook 설정
- 컨테이너 이미지 빌드 및 배포 자동화
그러면 이제 구체적인 과정을 조금 더 디테일하게 살펴보겠습니다.
사진으로만 생략한 단계의 경우, 다른 블로그들에도 많이 나와있는 경우이기 때문에, 이 글은 현재 프로젝트의 CI,CD 구성을 어떻게 했고, 구성을 할 때 만난 오류들을 기록하기 위해 작성하였습니다.
- github로 push
- github webhooks 이용하여 jenkins server에 변화를 전달
- jenkins에서 아래 단계들 실행
- 소스코드 clone
- 테스트 및 빌드 실행
- Dockerfile 이용해서 Docker 이미지 만들고 Docker hub에 push
- CD 를 위해 운영 서버로 도커 이미지 pull 받아오고 run 함
- 운영용 서버에서 docker로 스프링 부트 실행
I. Jenkins 서버 구축
우선, Jenkins 서버를 세팅하기 위해서는 Jenkins가 설치된 도커 이미지를 사용하거나 직접 호스팅 한 서버에 설치하여 구축해야 합니다. 이 작업을 통해 Jenkins를 통해 코드를 빌드하고, 테스트하며, 배포할 수 있는 환경을 마련합니다.
Oracle Cloud 서버 두개를 활용하여 구성하였습니다
Oracle linux server로 구성
- Server에 java 및 docker 설치
- 도커 설치
//패키지 업데이트
sudo yum -y upgrade
//도커 설치
sudo yum -y install docker
//도커 설치 작업이 잘 되었는지 버전 확인
docker -v
//도커 시작
sudo service docker start
//도커 그룹에 사용자 추가 -> docker가 그룹명, opc가 사용자명
sudo usermod -aG docker jenkins
Docker in Docker 방식으로 진행하였다.
😵💫 트러블 슈팅
1. 젠킨스 플러그인 설치 오류
도커에서 jenkins 이미지를 pull 받아와 run 한 후, 플러그인을 설치하려 했는데
자꾸만 거의 모든 플러그인이 설치가 되지 않는 오류를 겪었습니다.
계속 다시 시도해 봐도 똑같이 플러그인이 설치가 안돼서 해당 방법은 포기했으나
해결책을 찾았습니다.
서버에서는 자바 17 버전을 설치했는데, pull 받아온 jenkins는 기본적으로 자바 11 버전이기 때문에
sudo docker run -d --name jenkins -p 8080:8080 jenkins/jenkins:jdk17
자바 17 버전을 pull 받아와 실행했더니 해결되었습니다..
2. 오류: Exception in thread "main" java.lang.RuntimeException: Wrapper properties file '/var/jenkins_home/workspace/PortfoGram/gradle/wrapper/gradle-wrapper.properties' does not exist.
해결책: gradle-wrapper.properties
파일이 존재하지 않는 문제입니다.
해당 파일이 있는지 확인하고, 없다면 프로젝트 구성 시 Gradle Wrapper를 생성해야 합니다.
gradle wrapper
저의 경우에는,. 기존 로컬 스프링 프로젝트의 gradle-wrapper.properties 파일을 복사하여
젠킨스 서버에 복붙하여 해결했습니다.
cd ./wrapper
touch gradle-wrapper.properties
sudo vi gradle-wrapper.properties
3. 오류: ERROR: JAVA_HOME is set to an invalid directory: /usr/lib/jvm/java-17-openjdk-amd64 Please set the JAVA_HOME variable in your environment to match the location of your Java installation.
해결책: JAVA_HOME 환경 변수가 잘못 설정된 것입니다. 올바른 Java 설치 경로로 환경 변수를 변경하여 해결했습니다.
export JAVA_HOME=/usr/lib/jvm/java-<version>-<vendor>
4. 오류: chown: changing ownership of './build/classes/java/main/com/api/PortfoGram/Image/dto/Image$ImageBuilder.class': Operation not permitted
해결책: 권한 문제입니다.
Jenkins 사용자에게 충분한 권한을 부여하거나 루트 권한으로 해당 명령어를 실행하여 해결했습니.
sudo chown -R jenkins:jenkins ./build
5. 오류: docker build -t minimeisme/porfogram:0.1.0 ERROR: "docker buildx build" requires exactly 1 argument. See 'docker buildx build --help'.
해결책: 이 오류는 빌드 명령어의 오타 때문입니다. docker 사용할 때마다 자주 저지르는 실수인데,
docker build 마지막에 마침표를 찍어야 합니다.
docker build -t minimeisme/porfogram:0.1.0 .
6. 오류: ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? Build step 'Execute shell' marked build as failure
해결책: Docker 데몬이 실행 중인지 확인하고, 실행되지 않았다면 다음 명령어로 Docker 데몬을 시작해야 합니다.
sudo systemctl stop docker
sudo systemctl start docker
II. 소스코드 변경 감지를 위한 Webhook 설정
Git 저장소에 Webhook을 설정하여 소스코드에 변동 사항이 있을 경우, 이를 Jenkins 서버에 알려주도록 합니다. 이를 통해 변경 사항을 자동으로 감지하고 빌드 및 배포 프로세스를 자동으로 실행하게 됩니다.
III. 코드 통합 및 테스트 자동화
Jenkins에서 코드를 빌드하고 테스트하기 위한 파이프라인 스크립트를 작성합니다.
이번 프로젝트의 경우 Jenkins를 처음 도입해 봐서, 파이프라인 스크립트가 아닌 FreeStyle로 구성하여 Execute shell을 사용하였습니다.
IV. 컨테이너 이미지 빌드 및 배포 자동화
Docker를 사용해 프로젝트를 컨테이너화합니다. 이를 통해 프로젝트의 전체 환경을 효과적으로 관리할 수 있게 됩니다. 빌드된 이미지에 대해 이미지를 배포할 수 있도록 설계합니다.
이 글은 제 벨로그에서도 확인할 수 있는 글입니다.
포트폴리오 프로젝트에서 Jenkins와 Docker를 활용한 CI/CD 구축하기
이번 포스트에서는 제 포트폴리오 프로젝트에서 Jenkins와 Docker를 사용하여 어떻게 CI/CD를 구축한지, 그 과정에서 겪은 여러 문제들과 그 해결 과정에 대해 이야기해보려고 합니다.이 포스팅은 jen
velog.io
'스프링' 카테고리의 다른 글
K6를 통한 PortfoGram의 성능 개선 과정 및 결과 (0) | 2023.09.26 |
---|---|
[sqld] - 데이터 모델링의 이해(1) (0) | 2021.08.12 |
[웹] [백엔드] - SQL(2) MySQL 기본 용어 (0) | 2021.02.22 |
[웹] [ 백엔드 ] - SQL (1) 정의 및 분류, Database 생성 및 권한 (0) | 2021.02.22 |