https://backtony.github.io/spring/aws/2021-08-08-spring-cicd-1/
참고 : https://docs.docker.com/engine/install/ubuntu/
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world
sudo usermod -aG docker $USER
Docker in Docker(DiD) 로 구축하여 컨테이너로 실행해도 되지만, jenkins 컨테이너 안에 Docker를 설치하는 과정에서 컨테이너를 낭비하는 것이 아닌가 하는 생각에 Bare-metal에 설치했다.
sudo apt-get update
sudo apt-get install openjdk-11-jdk
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins
sudo systemctl start jenkins
sudo systemctl enable jenkins
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
참고 : https://nginx.org/en/linux_packages.html#Ubuntu
sudo systemctl start nginx
sudo systemctl status nginx
dockerhub에서 이미지를 push/pull 하기 위해 로그인을 해둔다.
docker login
Username:
password:
sudo vi /usr/lib/systemd/system/jenkins.service
JENKINS_PORT={포트번호}
sudo systemctl start jenkins
1. Jenkins 관리 > Global Tool Configuration > JDK
update-alternatives --list java
명령어를 통해 위치 확인git --version
mvn --version
gradle --version
@RestController
public class TestController {
@GetMapping("/")
public String connectTest() {
return "success!!!!!";
}
}
테스트 완료 후 github repository에 puash해준다.
git clone {repossitory}
./gradlew clean build -Dfile.encoding=UTF-8
docker build -t {dockerhub username}/{repository name}:{tag} .
-f
옵션을 통해 원하는 경로를 지정할 수도 있다. docker push {dockerhub username}/{repository name}:{tag}
spring1, spring2라는 이름으로 컨테이너를 2개 띄우고, 각각 9001, 9002 포트를 사용하고 프로젝트 설정에 포트를 9000으로 설정해뒀기 때문에 알맞게 publish하여 실행한다.
docker run -d -p 9001:9000 --name spring1 {image name}
docker run -d -p 9002:9000 --name spring2 {image name}
sudo vi /etc/nginx/nginx.conf
위 그림처럼 http에 upstream 블록을 추가해준다.
http {
upstream backend1 {
server 7001;
server 7002;
}
upstream backend2 {
server 9001;
server 9002;
}
server {
listen 80;
location / {
proxy_pass http://backend1;
}
}
server {
listen 9000;
location / {
proxy_pass http://backend2;
}
}
}
sudo systemctl start nginx
postman으로 아래 항목을 모두 테스트 해준다.
dockerhub에서 유료 계정을 사용하면 image를 만드는 것까지 자동화 할 수 있지만,
지금은 무료로 사용중이기 때문에 jenkins를 이용해서 image도 자동 build한다.
위에서 jenkins 플러그인들을 여러가지 다운받긴 했지만, jenkinsfile을 사용해보고 싶어졌기 때문에 Pipeline을 골라 생성해준다.
GitHub project
오래된 빌드 삭제 추가
pipeline {
agent any
environment {
dockerRepo = "jihoonydev/cicdtest"
dockerTag = "0.0.1"
githubRepo = "https://github.com/Jihoon-An/total.study.git"
path = "test-project/"
}
stages {
stage("Build stage") {
steps {
dir("${path}"){
echo "-------------Git pull------------"
sh "git pull origin main"
echo "----------build gradle------------"
sh "chmod 555 ./gradlew"
sh "./gradlew clean build -Dfile.encoding=UTF-8"
echo "----------delete image------------"
sh "docker rmi ${dockerRepo}:${dockerTag}"
echo "-----------build image------------"
sh "docker build -t ${dockerRepo}:${dockerTag} ."
echo "-----------push image-------------"
sh "docker push ${dockerRepo}:${dockerTag}"
}
}
}
stage("Update spring1 stage") {
steps{
echo "-----------stop spring1--------------"
sh "docker stop spring1"
echo "-----------rm spring1--------------"
sh "docker rm spring1"
echo "-----------run spring1--------------"
sh "docker run -d -p 9001:9000 --name spring1 ${dockerRepo}:${dockerTag}"
}
}
stage("Update spring2 stage"){
steps{
echo "-----------check spring1 status--------------"
script {
def retryCount = 0
def responseCode = sh(script: "curl -s -o /dev/null -w '%{http_code}' http://localhost:9001/actuator/health", returnStdout: true).trim()
while (responseCode != "200" && retryCount < 30) {
sleep 10
responseCode = sh(script: "curl -s -o /dev/null -w '%{http_code}' http://localhost:9001/actuator/health", returnStdout: true).trim()
retryCount++
}
}
echo "-----------stop spring2--------------"
sh "docker stop spring2"
echo "-----------rm spring2--------------"
sh "docker rm spring2"
echo "-----------run spring2--------------"
sh "docker run -d -p 9002:9000 --name spring2 ${dockerRepo}:${dockerTag}"
}
}
}
}
Github Integration
플러그인을 설치한다.
먼저 server에서 사용하는 github token이 아래 권한이 있는지 확인하자.
"githun" -> ""github
Jenkins script에 pull만 넣어놨기 때문에 clone을 미리 해둘 필요가 있다.
어차피 지울 EC2라 하지 않았지만 계속 사용할 거라면 기존의 프로젝트 파일은 지우는게 좋다.
최초의 배포는 수동으로 눌러줘야 한다길래 한번 눌러주었다.
빌드를 하니 권한이 없다고 해서 workspace에 권한을 다시 설정하고 실행한다.
chmod -R 777 /var/lib/jenkins/workspace
하지만 계속 권한에 의한 명령어 실행 불가능으로 오류가 발생하였다.
이 전에 Jenkins container에서 DID(Docker in Docker)를 사용하여 배포하려고 하였는데,
Jenkins container 안에 docker를 설치하는 것에 실패하여 이 방법으로 했던 것이다.
2부에서는 다시 Docker in Docker를 사용하여,Jenkins container에서 spring container를 두 개 run하여 사용하는 방법으로 배포해보자.