Jeinkins/Docker 명령어로 FreeStyle publish-over-ssh 배포하기 ver 0.2

devdo·2022년 2월 16일
0

Jenkins

목록 보기
4/8
post-thumbnail

Jenkins/Docker를 이용하여 AWS EC2 서버에 Gradle로 빌드한 jar 파일을 배포할 것이다.

이는 Spring Boot로 작성한 프로젝트를 Jenkins와 Docker를 활용하여 이미지를 생성하고 그 이미지를 기반으로 ssh로 연결된 EC2에 자동 배포하는 것이다.

jenkins를 이용한 시스템 구성도는 아래와 같다.

# 사용할 AMI 버전
Springbot 2.6.3
gradle 7.4
AWS EC2 이미지 : Ubuntu 20.04

먼저 만든 SpringBoot 프로젝트를 Docker image로 생성해야 한다.

@RestController
public class TestController {

    @GetMapping("/test")
    public String test() {
        return "jenkins_test";
    }
}

앞서 그 이미지를 사용하기 위한 Dockerfile을 먼저 생성한다.


Dockerfile (위치: 프로젝트 루트)

FROM openjdk:11-jdk

LABEL maintainer="mooh2jj@naver.com"

ARG JAR_FILE=build/libs/*.jar

COPY ${JAR_FILE} app.jar

ENTRYPOINT ["java","-jar","/app.jar"] 

💥주의
gradle jar 파일 생성이 springboot 2.5버전부터는 java 명령어를 통해 jar 파일이 2개가 생성된다고 한다. 그래서 별도의 설정을 해야JAR_FILE=build/libs/*.jar에 error가 안나온다!

build.gradle의 별도 설정(plain jar 파일 제거)

jar {
    enabled = false
}

이제, 로컬에서 별도로 잘되는지 확인하고 Dockerfile을 이용해서 이미지를 만든다.

sudo docker build -t mooh2jj/docker-jenkins-github-test .

그 다음 도커 이미지가 제대로 되있는 확인한다.

sudo docker images

이제 빌드한 네임대로 docker image를 dockerhub 레포지토리에 등록할 것이다.
이 허브에 image를 등록해서 배포할 때 pull을 하기 위함이다.

dockerhub 레포지토리는 이렇게 만들어주자.

그다음 로컬에서 docker 이미지를 저 만든 레포지토리에 push한다.

sudo docker push mooh2jj/docker-jenkins-github-test

이제부터 배포할 서버(worker-instacne)는 이 레포지터리에 등록된 이미지를 pull 받아서 사용할 것입니다.


AWS EC2 서버 jenkins, docker 설치

서버설치는 전에 만든 걸 적은 블로그를 참조해두었다.

서버의 종류는 jenkins 인스턴스, 그리고 배포할 서버인 worker 인스턴스 2개이다.

EC2 서버에는 docker> jenkins 를 설치한다.

설치하는 방법은 이 블로그 참조.
jenkins 설치 : https://velog.io/@mooh2jj/Jenkins-AWS-EC2-설치

그리고 worker 인스턴스에는 docker 를 설치해주자.

docker 설치 : https://velog.io/@mooh2jj/AWS-EC2-Docker-설치


Jenkins 페이지에 배포할 SSH 서버(worker 인스턴스) 등록

Jenkins SSH 서버 등록
: https://velog.io/@mooh2jj/젠킨스-자동배포하기

1) Jenkins 인스턴스 개인키&공개키 생성
2) 공개키 - SSH서버(worker 인스턴스)에 등록
3) 개인키 - Jenkins publish-over-ssh 페이지에 Key에 등록

이 순서로 하면 된다.

밑에 Test Configuraion이 Success가 뜨면 젠킨스가 배포할 서버인 SSH 인스턴스 접속이 성공한 것이다.


Free Style 프로젝트 생성 및 배포 명령어 등록

Item > Free Style 등록

먼저 이름은 아무렇게 지어도 좋다.

그 다음 프로젝트에 들어가서 구성으로 들어간다.

  • 소스 코드 관리 > Git

Repository URL 에 본인이 만든 프로젝트 Git주소를 적어준다.
프로젝트가 public 으로 되어 있다면 Credentials는 따로 처리할 필요가 없다.

만약 private라면 이 블로그를 참조해주기를 바란다.

https://velog.io/@mooh2jj/Jenkins-Git-webhook-설정

  • Build > Invoke Grade script > Use Gradle Wrapper

Invoke Gradle을 선택할 경우 Jenkins에 Global Toll Configuration에서 Gradle 패키지를 설치해야 사용할 수 있다.

여기서는 Use Gradle Wrapper을 사용하자.
그리고 Make gradlew executable 까지 체크해준다.
이는 jar 파일 자체를 빌드를 해주는 것으로 gradlew 권한(chmod) 문제로 실행이 안 되는 상황을 막아 주는 것이다.

그리고 Tasks 안에 clean build를 넣어준다.

그리고

  • Build > Execute shell
docker login -u [도커허브ID] -p [도커허브Password]

docker build -t [도커허브ID]/[도커허브 레포지토리 이름] .
docker push [도커허브ID]/[도커허브 레포지토리 이름]

를 적어준다.

그러면 Jenkins 내부 /var/jenkins_home/workspace/ 안에 git 레포지토리로 등록한 프로젝트가 jenkins-docker-test 가 들어가고 그 프로젝트 안에 /gradlew clean build 가 실행되는 것이다.

# jenkins 내부 확인
docker exec -it [jenkins 컨테이너 ID] /bin/bash

root~ > cd /var/jenkins_home/workspace/ 

💥[도커허브Password] 같은 경우 보안 기밀 상 유출 위험이 있어 DockerHub 내에서 Token을 생성해 기입할 수 있다.


DockerHub > Account Setting > Security > New Access Token

그다음 생성한 암호화된 Token을 [도커허브Password] 자리에 대체하면 된다.


💥 docker push가 정상적으로 동작되지 않을 때

=> docker login 이 안되서 !

denied: requested access to the resource is denied
Build step 'Execute shell' marked build as failure
SSH: Current build result is [FAILURE], not going to run.
Finished: FAILUREdocker-compose 

💢 참고로, Invoke Gradle script > Execute shell 이 순서로 진행해주어야 한다. docker 이미지에서 빌드하고 처리하기 때문에 docker push 전에 해야되기 때문이다.


  • 빌드 후 조치 > Send build artifacts over SSH

jenkins 인스턴스 Freestyle Project 내 구성 에 다시들어가서, 빌드 후 조치로 SSH 인스턴스가 해주어야 명령어를 적어주어야 한다.
다음 2가지를 적어주면 된다.

1) Name
2) Exec command

Name은 알아서 Publish Over를 통해 등록했으면 리스트로 나온 걸 선택해주면 된다.

SSH 원격 서버(worker instance)에 보낼 명령어를 적어주자.
Transfer Set에 Excute shell 만 적어주면 된다.

# 처음 컨테이너 돌시에 
# sudo docker rm -f $(docker ps -aq)
# sudo docker rmi -f mooh2jj/docker-jenkins-github-test
sudo nohup docker run -p 8080:8080 mooh2jj/docker-jenkins-github-test > /dev/null 2>&1 &


결과

웹 브라우저에서 잘 확인이 된다.

웹 URL : [등록한 SSH 서버 퍼블릭IP주소]:8080/test

이젠 Jenkins를 통해 Github에 push한 내용이 바로 빌드/배포 하는 과정이 자동화되어진 것이다.
Git + Jenkins + Docker 를 활용해 CI/CD 시스템을 만들면 개발하는 데 정말 편하다는 것을 알 수 있다.


Schedule - Build periodically

Jenkins에서는 Schedule를 짜서 자동으로 배포하는 시스템이 마련되어 있다. 그중 하나가 build periodically 기능이다.

말그대로 주기성을 가지고 빌드/배포한다는 것이다.

# Build every 5 minutes:
H/5 ****

출처 : https://www.baeldung.com/ops/jenkins-job-schedule


MySQL 인스턴스 만들기(추가)

Mysql 도커로 설치및 실행
: 이 블로그 - Mysql 만들기 참조

https://velog.io/@mooh2jj/도커Docker-이미지로-Apache-및-PHP-개발환경-구축하기

추가로 해야할 일

  • jpa, Entity, Controller 만들기
  • mysql post 데이타베이스 만들기

application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://{mysql-instacne IP}:9876/post
    username: root
    password: 1234
  jpa:
    open-in-view: true
    hibernate:
      ddl-auto: update
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
      use-new-id-generator-mappings: false
    show-sql: true
    properties:
      hibernate.format_sql: true
      dialect: org.hibernate.dialect.MySQL5InnoDBDialect

logging:
  level:
    root: info
    com.example: debug
    org.hibernate.SQL: debug

@RequiredArgsConstructor
@RestController
public class PostController {

    public final PostRepositroy postRepositroy;

    @PostMapping
    public Post createPost(@RequestBody Post post) {
        return postRepositroy.save(post);
    }

    @GetMapping("/posts")
    public List<Post> getPostList() {
        return postRepositroy.findAll();
    }
}
@Getter
@Setter
@ToString
@Entity
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String content;
}
public interface PostRepositroy extends JpaRepository<Post, Long> {
}


참고

profile
배운 것을 기록합니다.

0개의 댓글