Docker, Jenkins가 이미 설치되어 있다는 가정하에 작성하였습니다.
Jenkins 설정완료 화면
도입배경
간단하게 설명하자면 젠킨스는 빌드 및 배포를 자동화해주는 툴이다.
AWS에서도 비슷한 역할을 하는 서비스를 제공하고 있지만, 모든 것은 유료로 제공된다.
개인적으로 사이드 프로젝트를 위해 AWS를 유지하고 사용하기가 어렵다고 판단이 되어서 모든 운용중인 서버를 로컬 서버로 옮기게 되었다.
이러한 과정에서 기존의 GitHub와 AWS 연동을 통해 CI/CD를 구성해두었던 부분은 전부 들어내고 젠킨스를 도입하게 되었다.
목적
CI/CD 자동화를 통해 배포와 빌드를 자동화하는 것은 좋지만
모든 것을 자동화하는 것은 적지않은 공부가 필요하다.
사이드프로젝트 수준에서만 자동화 할 목적이고, 처음 세팅은 간결하기 위해 아래의 구성만 진행하기로 하였다.
•
Jenkins-GitHub 연동을 통해 커밋된 Repository를 불러와 시스템에 지속적인 배포 설정
•
Jenkins-Docker 연동을 통해 특정 Repository는 Docker Container로 배포되도록 설정
Jenkins-GitHub 연동
토큰생성
먼저 GitHub Repository를 Jenkins에서 받아올 수 있도록 GitHub를 연동해야한다.
GitHub에 접속하여 Token을 생성하기 위해 아래와 같이 진행 후 3가지 권한을 설정해준다.
Settings -> Developer settings -> Personal access tokens -> Tokens (classic)
•
repo
•
admin:org
•
admin:repo_hook
Credential 생성
생성이 완료되면 Jenkins Dashboard로 넘어온다
각 Repository 별로 Credentials을 설정 할 수도 있으나 별도 권한은 필요하지 않으므로 전역 Credential을 생성하기 위해 아래와 같은 절차를 거친다.
Dashboard > Jenkins 관리 > Credentials > Global Credentials > Add Credentials
•
Username : 본인의 GitHub 아이디
•
Password : 위에서 발급 받은 GitHub token
•
ID : Credentials 이름
•
Description : Optional
여기까지 설정했다면 설정 완료.
Repository 설정
이제 Jenkins에 미리 생성해둔 Repository에 GitHub를 연동한다.
Dashboard > {Respository 명} > Configuration > 소스 코드 관리> Git 로 이동
위에서 생성한 Credentials을 설정해준다.
Branch Specifier는 main 브랜치를 가져올 예정이므로 */main 로 설정해준다.
Webhook 설정
Push(GitHub) → Build(Jenkins)를 자동화 하기 위해 Trigger → GitHub hook trigger for GITScm polling 옵션을 체크
GitHub hook trigger for GITScm polling은 Jenkins와 GitHub를 연동하여 GitHub 저장소에 변경 사항이 푸시될 때마다 자동으로 Jenkins 빌드를 트리거하는 옵션입니다.
Git Repository → Setting → Webhooks에 들어간 뒤 Jenkins URL을 등록해준다.
등록하게 되면 아래와 같은 화면인데, 글쓴이의 경우 Jenkins 서버로부터 403 Error 를 반환 받았다.
확인결과 Jenkins 연동을 위한 정해진 양식이 존재한다.
http://{도메인 or IP}:{포트}/github-webhook/
와 같이 변경한 뒤 Last delivery was successful 성공 메시지를 볼 수 있었다.
Webhook 설정 후 Push 하게되면 아래와 같이 자동으로 진행되는 build를 확인 할 수 있다.
Jenkins-Docker 연동
docker-jenkins-github 구조도 https://whimsical.com/BsGeJiHtfvgWY9qvqDNWAw
Docker Image Buld부터 Container 생성까지 다루려면 내용이 너무 헤비해지므로
Web Server Container와 Jenkins Server Container 는 이미 세팅됐다고 가정한다.
컨테이너는 아래 DockerFile을 통해 이미지를 빌드하여 사용하였다.
Web Server DockerFile
FROM ubuntu:20.04
# default user
ENV USER dominic
# packages install
RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y sudo vim net-tools ssh openssh-server curl
# nvm install by curl
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
# set nvm variable
RUN export NVM_DIR="$HOME/.nvm"
RUN [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
RUN [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"b
RUN nvm install 22
RUN npm install -g pm2
# Access Option
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -i 's/UsePAM yes/#UserPAM yes/g' /etc/ssh/sshd_config
#user add & set
RUN groupadd -g 999 $USER
RUN useradd -m -r -u 999 -g $USER $USER
RUN sed -ri '20a'$USER' ALL=(ALL) NOPASSWD:ALL' /etc/sudoers
#set root & user passwd
RUN echo 'root:root' | chpasswd
RUN echo $USER':{{password}}' | chpasswd
ENTRYPOINT sudo service ssh restart && bash
USER $USER
Docker
복사
PostgreSQL DockerFile
FROM postgres:latest
ENV POSTGRES_USER postgres
ENV POSTGRES_PASSWORD {{password}}
ENV POSTGRES_DB public
ENV TZ Asia/Seoul
EXPOSE 5432
## host에 postgreSQL data를 마운트
#docker run -v /home/postgres/pgdata:/var/lib/postgresql/data postgres
Docker
복사
먼저 서버는 NestJS를 활용할 예정이므로 Jenkins 서버는 nodejs를 실행 할 수 있어야한다.