Ubuntu 16に最新版のJenkinsをインストール

このチュートリアルでは、**Alibaba Cloud ECS Ubuntu 16**に**Jenkins**自動化サーバの最新版のインストールについて述べています。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/cicd-with-jenkins---part-1-install-jenkins-on-ubuntu_593717)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

[Alibaba Cloud Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.789b4a54a4WRLd)著者Liptan Biswas, [Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.789b4a54a4WRLd)は、クラウドコミュニティ内で技術的な知識やベストプラクティスを共有することを奨励するAlibaba Cloudのインセンティブプログラムです。

Jenkinsはオープンソースのセルフホスト型自動化サーバーです。ソフトウェア開発ライフサイクルにおける継続的インテグレーションや継続的デリバリーを実装するために、DevOpsエンジニアの間で非常に人気があります。JenkinsはJavaで書かれており、Apache Ant、Maven、sbtプロジェクトを構築するためのアウトオブボックスのサポートを提供しています。また、LinuxシェルやWindowsのバッチスクリプトを実行することもできます。Git, Mercurial, Subversion, CVSなどの複数のバージョン管理システムがJenkinsによって完全にサポートされています。少なくとも1000種類以上のプラグインが用意されており、アプリケーションの機能性を高めることができます。

Jenkinsでのビルドは、バージョン管理システムのソースコードの変更を検出した後、特定の時間にビルドをスケジューリングしたり、ビルドURLを呼び出すなど、いくつかの方法でトリガーすることができます。ビルドがトリガーされると、Jenkinsはリポジトリからソースコードを取得し、ビルドを開始します。提供された設定に従って、自動テストが実行され、出力が保存されます。また、Jenkinsはビルド成功後に生成されたパッケージを配信することも可能です。

この3部構成のチュートリアルでは、Jenkinsのインストール方法を説明し、継続的なインテグレーションとデプロイメントにJenkinsを使用する方法を説明します。

このチュートリアルの第１部では、Ubuntu 16.04 64ビットのAlibaba Cloud [Elastic Computer Service](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.789b4a54a4WRLd) (ECS)インスタンスに最新バージョンのJenkins自動化サーバーをインストールします。また、JenkinsインスタンスにアクセスするためのセキュアなNginxリバースプロキシを設定します。第2部では、MavenプロジェクトとしてサンプルのJava Webアプリケーションを作成します。また、Jenkinsでビルドジョブを作成するプロセスも進めていきます。最後に、チュートリアルの第3部では、ビルドプロセスを自動化します。また、Jenkinsを使用して継続的に配信する方法についても学びます。

#前提条件
1、[Alibaba Cloud ECS](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.789b4a54a4WRLd&biz_params=%7B%22intl%22:%22%7B%5C%22referralCode%5C%22:%5C%22fmj2og%5C%22%7D%22%7D)インスタンスにUbuntu 16.04 64ビットがインストールされていること。
2、ポート「80」、「443」を許可するように構成されたファイアウォールまたはセキュリティグループのルール。
3、[ECSインスタンス向けの](https://www.alibabacloud.com/help/doc-detail/58077.htm?spm=a2c65.11461447.0.0.789b4a54a4WRLd)必要な[ドメイン名](https://www.alibabacloud.com/domain?spm=a2c65.11461447.0.0.789b4a54a4WRLd&biz_params=%7B%22intl%22:%22%7B%22referralCode%22:%22fmj2og%22%7D%22%7D)。

インスタンスを作成し、インスタンスに接続するための手順は、「[クイックスタートガイド](https://www.alibabacloud.com/help/doc-detail/25422.htm?spm=a2c65.11461447.0.0.789b4a54a4WRLd)」に従ってください。このチュートリアルでは、すでにAlibabaインスタンスを作成し、Ubuntuインスタンスを指すように「[jenkins.example.com](http://jenkins.example.com/?spm=a2c65.11461447.0.0.789b4a54a4WRLd)」を設定していることを前提としています。SSH経由でインスタンスに接続したら、以下のコマンドを実行してリポジトリキャッシュとベースシステムを更新します。

`apt update && apt -y upgrade & apt -y autoremove`

すべてのコマンドをrootユーザーで実行するのではなく、sudoユーザーを作成してすべてのコマンドを実行するのがベストです。ではsudoユーザーを作成します。ユーザー名はお好みに応じて自由です。

`adduser aliyun`

ユーザーを作成したら、sudoグループに追加します。

`usermod -aG sudo aliyun`

では、新しく作成したユーザーに切り替えます。

`su - aliyun`

#ホスト名の設定
サーバのホスト名としてFQDNまたはFully Qualified Domain Nameを設定します。ホスト名の設定は必須ではありませんが、ホスト名が正しく設定されていない場合、Jenkinsは警告メッセージを表示します。

`sudo hostnamectl set-hostname jenkins.example.com`

同様に、/etc/hostsファイルにドメイン名を追加します。

`echo "127.0.0.0.1 jenkins.example.com" | sudo tee -a /etc/hosts`

#Javaのインストール
JenkinsはJavaで書かれており、将来的にJavaアプリケーションを構築する必要があるかもしれないので、Java Development KitやJDKのインストールを進めていきましょう。JenkinsはOracle Java 8とOpenJDK 8の両方をサポートしています。このチュートリアルでは、Oracle Javaバージョン8をインストールします。Oracle JavaにはJava Runtime（JRE）とJDKの両方がパックされています。Oracle JavaのPPAリポジトリを追加します。

```
sudo apt install -y software-properties-common
sudo add-apt-repository --yes ppa:webupd8team/java
sudo apt update
```

Oracle Java 8をインストールします。

`sudo apt -y install oracle-java8-installer`

Javaが正常にインストールされているかどうかは、java -versionコマンドを実行することで確認できます。

```
aliyun@jenkins:~$ java -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
```

以下のパッケージをインストールしてjava_homeのデフォルトパスを設定します。

`sudo apt -y install oracle-java8-set-default`

これで、 echo $JAVA_HOME を実行することで JAVA_HOME 変数が設定されているかどうかを確認することができます。また、目的の出力を得るためにログアウトしてログインし直す必要があるかもしれません。

```
aliyun@jenkins:~$ echo $JAVA_HOME
/usr/lib/jvm/java-8-oracle
```

#Jenkinsのインストール
Jenkinsは、プロジェクト自体が積極的にメンテナンスしているリポジトリを通じて簡単にインストールすることができます。リポジトリ経由でインストールすることで、将来的には apt upgrade コマンドを直接使用して簡単にアップグレードすることも可能です。Jenkinsのリポジトリにあるパッケージの署名に使われているキーをインポートします。これにより、正しいパッケージがインストールされていることを確認できます。

`wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -.`

Jenkins用の新しいリポジトリリストファイルを作成します。

`echo "deb https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list`

Jenkinsをインストールします。

```
sudo apt update
sudo apt -y install jenkins git
```

プロジェクトが管理しているリポジトリからJenkinsをインストールしているので、最新の利用可能なバージョンのアプリケーションをインストールする必要があります。JenkinsでGitプラグインを実行するにはGitが必要です。Jenkinsを起動し、起動時に自動的に起動するようにするには、実行します。

```
sudo systemctl start jenkins
sudo systemctl enable jenkins
```

サービスの状態は、systemctl status jenkinsというコマンドで確認できます。

```
aliyun@jenkins:~$ sudo systemctl status jenkins
● jenkins.service - LSB: Start Jenkins at boot time
   Loaded: loaded (/etc/init.d/jenkins; bad; vendor preset: enabled)
   Active: active (exited) since Fri 2018-05-04 12:37:03 UTC; 35s ago
     Docs: man:systemd-sysv-generator(8)

May 04 12:37:02 jenkins.liptan.tk systemd[1]: Starting LSB: Start Jenkins at boot time...
May 04 12:37:02 jenkins.liptan.tk jenkins[4787]:  * Starting Jenkins Automation Server jenkins
```

Jenkinsサーバ自体に関連するログを確認するには、以下のコマンドを実行します。

`tail -f /var/log/jenkins/jenkins.log`

Jenkinsの初回起動には数分かかります。出力に以下の行があれば、アプリケーションの準備ができていることになります。

```
aliyun@jenkins:~$ tail -f /var/log/jenkins/jenkins.log
May 02, 2018 2:14:29 PM hudson.WebAppMain$3 run
INFO: Jenkins is fully up and running
```

これで、あなたのサーバー上で Jenkins が稼働しています。ドメイン名を使って簡単にJenkinsインスタンスにアクセスできるように、Nginxのインストールを進めてください。

注: Alibaba Cloud ECSインスタンスを指すようにドメイン名が設定されていない場合は、ECSインスタンスのセキュリティグループを介してポート「808080」を開き、[http://172.16.0.1:8080](http://172.16.0.1:8080/?spm=a2c65.11461447.0.0.789b4a54a4WRLd)、172.16.0.1がECSインスタンスのパブリックIPアドレスであるJenkinsインスタンスにアクセスできます。Nginx のインストールセクションをスキップして、Final Setup からチュートリアルに従ってください。

#Nginxをインストールする
Jenkinsにはアプリケーションを「808080」番ポートで提供するためのウェブサーバが組み込まれていますが、本番環境ではこのようなウェブサーバをインターネット上に公開することは推奨されていません。このチュートリアルでは、クライアントからのリクエストを Jenkins サーバに転送するリバースプロキシとして Nginx を使用します。ドメイン名でリバースプロキシを設定することで、インスタンスのアクセス性も向上しますので、インスタンスのIPアドレスを覚えておく必要はありません。

NginxのWebサーバをインストールします。

`sudo apt -y install nginx`

Nginxを起動し、起動時にサーバーが自動的に起動するようにします。

```
sudo systemctl start nginx
sudo systemctl enable nginx
```

また、ログインやその他の重要なデータはクライアントからウェブサーバーに、またその逆も同様に送信されるため、SSL/TLS暗号化でウェブサーバーを保護することも重要です。交換されるデータが暗号化されていない場合、ネットワーク内のデータを盗まれてしまう可能性があります。このチュートリアルでは、Let's Encrypt CAの無料SSL証明書を使用します。より本番に適した信頼性の高いSSLを使用したい場合は、[アリババクラウドからSSL証明書を購入](https://www.alibabacloud.com/product/certificates?spm=a2c65.11461447.0.0.789b4a54a4WRLd)することができます。

Let's Encryptでは、証明書のリクエストや生成を簡単に行えるツール「Certbot」を提供しています。Certbotのリポジトリをシステムに追加し、Certbotをインストールします。

```
sudo add-apt-repository --yes ppa:certbot/certbot
sudo apt update
sudo apt -y install certbot
```

Certbotがドメインの所有権を確認するためには、ドメインがECSインスタンスに向けられていることが重要です。そうでない場合、ドメインの証明書は生成されず、エラーが表示されます。Certbotを使用して証明書を要求します。

`sudo certbot certonly --webroot -w /var/www/html -d jenkins.example.com`

証明書が生成されると、以下のような出力が表示されます。

```
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for jenkins.example.com
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/jenkins.example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/jenkins.example.com/privkey.pem
   ...
```

証明書の有効期限が切れる前に自動更新するためのcronジョブを作成します。

`{ sudo crontab -l; echo '36 2 * * * * /usr/bin/certbot renew --post-hook "systemctl reload nginx"; } } | sudo crontab -l.`

sudo crontab -lコマンドを実行することで、cronジョブが作成されているかどうかを確認することができます。

```
aliyun@jenkins:~$ sudo crontab -l
36 2 * * * /usr/bin/certbot renew --post-hook "systemctl reload nginx"
```

Jenkinsリバースプロキシ用のNginxサーバーブロックを新規作成します。

`sudo nano /etc/nginx/sites-available/jenkins`

エディタで以下の設定を入力します。例のドメインのすべての出現を実際のドメインに置き換えることを確認してください。

```
upstream jenkins {
  keepalive 32;
  server 127.0.0.1:8080;
}
server {
    listen 80;
    server_name jenkins.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443;
    server_name jenkins.example.com;

    root            /var/cache/jenkins/war/;
    ssl_certificate           /etc/letsencrypt/live/jenkins.example.com/fullchain.pem;
    ssl_certificate_key       /etc/letsencrypt/live/jenkins.example.com/privkey.pem;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    gzip  on;
    gzip_http_version 1.1;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml;
    gzip_buffers 16 8k;
    gzip_disable "MSIE [1-6].(?!.*SV1)";
    
    access_log            /var/log/nginx/jenkins.access.log;
    error_log            /var/log/nginx/jenkins.error.log;
    ignore_invalid_headers off;

location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
    rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
    }

location /userContent {
    root /var/lib/jenkins/;
    if (!-f $request_filename){
    rewrite (.*) /$1 last;
    break;
    }
    sendfile on;
    }
    
location @jenkins {
    sendfile off;
    proxy_pass         http://jenkins;
    proxy_redirect     default;
    proxy_http_version 1.1;

    proxy_set_header   Host              $host;
    proxy_set_header   X-Real-IP         $remote_addr;
    proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_max_temp_file_size 0;
    client_max_body_size       10m;
    client_body_buffer_size    128k;

    proxy_connect_timeout      90;
    proxy_send_timeout         90;
    proxy_read_timeout         90;
    proxy_request_buffering    off;
    proxy_set_header Connection "";
    }

location / {
    if ($http_user_agent ~* '(iPhone|iPod)') {
    rewrite ^/$ /view/iphone/ redirect;
    }
try_files $uri @jenkins;
    }
}
```

設定ファイルを有効化します。

`sudo ln -s /etc/nginx/sites-available/jenkins /etc/nginx/sites-enabled/jenkins`

sudo nginx -tを実行することで、設定ファイルにエラーがないかどうかを確認できます。

```
aliyun@jenkins:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

設定の変更が反映されるように、NginxのWebサーバーを再起動します。

`sudo systemctl restart nginx`

JenkinsにアクセスするためにNginxリバースプロキシを使用しているため、ポート "8080 "へのアクセスは不要になっています。ファイアウォールやECSインスタンスのセキュリティグループでポート「808080」へのアクセスを有効にしていれば、安全に削除することができます。ローカルホストからの接続のみをリッスンするようにJenkinsビルトインサーバを設定するには、Jenkinsのデフォルト設定ファイルで設定を変更します。設定ファイルを開きます。

`sudo nano /etc/default/jenkins`

ファイルの最後に以下の行を見つけます。

`JENKINS_ARGS="--webroot=/var/cache/$NAME/war --httpPort=$HTTP_PORT”`

設定を以下のように変更します。

```
HTTP_HOST=127.0.0.1

JENKINS_ARGS="--webroot=/var/cache/$NAME/war --httpPort=$HTTP_PORT --httpListenAddress=$HTTP_HOST"
```

ファイルを保存してエディタを終了します。実行してJenkinsインスタンスを再起動します。

`sudo systemctl restart jenkins`

これでJenkinsのビルトインサーバはローカルホストからの接続のみを受け付けるようになりました。Nginxプロキシのみで安全にアクセスできます。

Jenkinsのインスタンスには、URLhttps://jenkins.example.comにアクセスすることで、お気に入りのブラウザからアクセスできます。

#最終設定
インストール中、Jenkinsは初期パスワードを生成します。この初期パスワードは、ブラウザからJenkinsのセットアップを完了するために必要です。ブラウザからJenkinsインスタンスにアクセスすると、管理者パスワードを求めていることがわかります。端末に初期管理者パスワードを印刷します。

`sudo cat /var/lib/jenkins/secrets/initialAdminPassword`

同じような出力が表示されるはずです。

```
aliyun@jenkins:~$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
84ae7775fec245e69305c6db08389d69
```

端末からパスワードをコピーしてブラウザに貼り付けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/1e809d1f-cd6e-28e4-e148-558ec192efc1.png)

初期パスワードの確認に成功すると、セットアップはインストールするプラグインを尋ねてきます。プラグインはJenkinsのインターフェースから簡単に管理できるので、ここではInstall suggested pluginsオプションを選択します。これにより、Jenkinsの機能を拡張するために最も人気のある便利なプラグインがインストールされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/6951041d-e4d4-46bf-41ce-7e9aff617824.png)

この段階で、SETUPが推奨プラグインをインストールします。数分で完了します。各プラグインのインストール状況が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/4a5e78e0-8a2b-d82a-b892-f1ade9c06dac.png)

プラグインのインストールに成功すると、setupは管理者アカウントの作成を求めてきます。Jenkinsが尋ねる基本的なアカウントの詳細を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/e7a7e1c4-9747-28d4-af70-caa5eda4e8cc.png)

最後に、Jenkinsの準備ができましたというメッセージが表示されます。ログインに進み、先ほど作成した管理者アカウントでログインします。Jenkinsのダッシュボードが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/15b2c042-bd78-6221-0418-50684d67b200.png)


#結論
これで終了です。[Alibaba Cloud ECS](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.789b4a54a4WRLd) Ubuntu 16.04上にJenkins自動化サーバを導入することに成功しました。また、Nginxリバースプロキシを設定し、Let's Encrypt SSLでセキュリティを確保しました。これでJenkinsインスタンスの準備ができたので、最初のビルドジョブの作成に進むことができます。

[チュートリアルの後半](https://community.alibabacloud.com/blog/ci%2Fcd-with-jenkins---part-2%3A-use-jenkins-for-continuous-integration_593720?spm=a2c65.11461447.0.0.789b4a54a4WRLd)では、MavenプロジェクトとしてWebベースのJavaアプリケーションのサンプルを作成します。また、JDK、Git、Mavenで動作するようにJenkinsを設定します。最後に、サンプルアプリケーションのJenkinベースのビルドプロジェクトを設定し、最初のビルドを実行します。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*