好奇心の赴くままに

好奇心の赴くままに

やりたいことを書いています。

JenkinsとGithubの連携(SpringBoot)

目次

開発環境

Java1.8
Maven
Spring Boot 2.1.4

Jenkins環境

CentOS 7

今回のゴール

GithubへのpushをトリガーにしてJenkins上でSpringBootアプリの自動ビルド、自動デプロイを走らせる

手順

Spring bootプロジェクト作成

Eciipse上でプロジェクトを作成する。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>TestApp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>TestApp</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

簡単なHello Worldアプリを作成する

package com.example.demo.tryJenkinsTest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {
    @GetMapping("/hello")
    public String getHello() {
        return "hello";
    }
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
    <h1>Hello World</h1>
</body>
</html>

SpringBootとJenkinsのポートが競合するのでapplication.propertiesファイルでSpringBootのポートを8080番以外に設定する

server.port=8082

結果

f:id:kamada-math:20191209085044p:plain

Jenkinsサーバ構築

AWSコンソール上でCentOSのAMIからCentOSサーバを構築する f:id:kamada-math:20191209000010p:plain

サーバに接続後、サーバにJenkinsをインストールする

$ sudo yum -y install java-1.8.0-openjdk    # 前提環境のインストール

$ sudo curl -o /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo   # Jenkins公式yumレポジトリの追加 
$ sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key # Jenkinsインストール時に使用する公開鍵を追加
$ sudo yum install jenkins # Jenkinsのインストール
$ sudo systemctl enable jenkins # 自動起動設定
$ sudo systemctl start jenkins # Jenkinsの起動
$ sudo systemctl status jenkins # 起動及び自動起動確認

※firewalldが有効になっている場合は、別途8080番へのアクセスを許可する必要があるので注意
※EC2ではセキュリティグループでアクセス制限を行う為、firewalldは標準ではインストールされていない

http://(公開IP):8080/」に接続して画面に沿って初期設定を進める

f:id:kamada-math:20191209005536p:plain

f:id:kamada-math:20191209010248p:plain

Github上で新規リポジトリ作成後,先ほど作成したHello WorldアプリをGithubにpush

> cd (Hello Worldアプリのworkspaceパス)
> git init
> git add .
> git commit -m "first commit"
> git remote add origin (gitリポジトリのHTTPパス)
> git fetch
> git merge --allow-unrelated-histories origin/master
> git push -u origin master

Webhookの設定(Jenkins側)

左側の「新規ジョブ作成」からジョブ名入力後、「フリースタイル・プロジェクトのビルド」を選択

f:id:kamada-math:20191209015527p:plain

ビルドトリガの「リモートからビルド」で認証トークン名を設定し、ジョブを作成 f:id:kamada-math:20191209015734p:plain

認証トークン名は後で利用するため、メモ帳等にメモしておく

作成後、Webhook時に使用するRESTAPIの認証情報を取得する為、「Jenkinsの管理]→「ユーザーの管理」よりログインユーザ名の歯車マークを選択 f:id:kamada-math:20191209021453p:plain

設定画面の「APIトークン」より「Add new Token」を押下後、 「Generate」で認証トークンを生成 f:id:kamada-math:20191209021822p:plain

生成時に表示される認証トークンは後で利用するため、メモ帳等にメモしておく

Webhookの設定(Github側)

対象のリポジトリの「Settings」→「Add webhook」より webhookの作成画面を開く f:id:kamada-math:20191209022226p:plain

PayloalURLを以下のように設定し、Add webhookをクリック   [PayloadURL]
http://(ユーザー名):(生成した認証トークン)@(jenkinsホスト)/job/(ジョブ名)/build?token=(認証トークン名)

f:id:kamada-math:20191209022418p:plain

トリガー時のスクリプト実行のための準備

再度サーバに接続後、以下を実行する

# デプロイするディレクトリ作成
$ mkdir /var/webapp/spring/
# javacインストール
$ sudo yum -y install java-1.8.0-openjdk-devel     
# sudoを実行するためにsudoersに設定追加
$ sudo visudo

$ Defaults !visiblepw
Defaults visiblepw

jenkins ALL=(ALL) NOPASSWD:ALL

トリガー時に実行させるスクリプトを設定する

作成したジョブを選択し、設定より設定画面を開く 「ビルド」→「シェルの実行」より以下のスクリプトを設定する

#前に残っているspringプロセスを削除してspringアプリケーションを止める。
ps aux | grep java | grep (作成したSpringBootプロジェクト名)-0.0.1-SNAPSHOT.jar | grep -v sudo | awk '{print "kill -9 " $2}' | sudo  sh

#springアプリケーションをデプロイするディレクトリに移動する。
cd /var/webapp/spring/

# 前にgit cloneしたアプリケーションの削除
sudo rm -rf (作成したSpringBootプロジェクト名)

#git cloneする。
sudo git clone (gitリポジトリのHTTPパス)

#cloneされたリポジトリのルートディレクトリに移動
cd (作成したSpringBootプロジェクト名)

#実行権限を追加 
sudo chmod 700 mvnw

# Mavenでビルドする。ビルドするとプロジェクトのルートディレクトリにtargetディレクトリにspringの実行可能jarファイルができる。
sudo ./mvnw clean package

#jarファイルのフォルダに移動
cd target

#jarファイルの実行&でバックグラウンドで実行している。--server.portで好きなポートで実行できる。
sudo java -jar (作成したSpringBootプロジェクト名)-0.0.1-SNAPSHOT.jar --server.port=(設定したポート) &

設定後、保存

テスト

ローカルで以下のように変更後、githubにpush

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
    <h1>Hello Jenkins</h1>
</body>
</html>
> cd (Hello Worldアプリのworkspaceパス)
> git add .
> git commit -m "first cicdtest"
> git push 

すると、以下のようにJenkins上でビルドが走り、 f:id:kamada-math:20191209092314p:plain

ローカル上での変更が反映された(自動デプロイされる)ことが確認できる

f:id:kamada-math:20191209092455p:plain

参考

JenkinsをCentOS 7にyumインストールする手順 | WEB ARCH LABO

CentOS7.0にJenkinsをインストールする - Qiita

Installing Jenkins on Red Hat distributions - Jenkins - Jenkins Wiki

GithubとJenkinsを連携させてアプリケーションを自動デプロイさせる。 - Qiita

Jenkinsでsudo実行時のエラー - Qiita

一般ユーザーを sudo できるようにする - maruko2 Note.