Jenkinsを使用してUbuntuで自動的にビルドする方法

[ Jenkins](https://jenkins.io/)は、アプリケーションの構築、テスト、および展開のプロセスを自動化するパイプラインを構築できるようにするオープンソースの自動化サーバーです。このガイドでは、継続的な統合と継続的な配信(CI / CD)プロセスを高速化するための基本的なワークフローを実装します。

準備完了##

sudo apt-get update && sudo apt-get upgrade

このチュートリアルは、root以外のユーザーを対象としています。昇格された特権を必要とするコマンドの前には sudoが付いています。

初期の仮定##

このガイドはDevOpsの専門家を対象としているため、次のことを前提としています。

  1. ローカルワークステーションは、開発とテストに使用されます。
  2. LinodeはリモートJenkinsサーバーに使用されます。
  3. どちらもUbuntu16.04を使用します。
  4. Jenkinsは、主に新しい[Blue Ocean](https://jenkins.io/projects/blueocean/)Webインターフェイスを介して使用されます。
  5. ワークステーションとリモートLinodeの両方で、事前にDockerをインストールする必要があります。詳細な手順については、[ドッカーイメージのインストール方法](https://www.linode.com/docs/applications/containers/how-to-install-docker-and-pull-images-for-container-deployment/)ガイドを参照してください。
  6. このガイドでは、Jenkinsマスターサーバーのみを使用します。
  7. 作成済みのGitHubアカウント、またはBitbucketとGitLabで利用できる同様のプログラムが必要になります。
  8. DockerHubまたは同様の登録済みアカウントも必要です。

ジェンキンスがどのように機能するかを理解する##

ワークフローを自動化する前に、基本的なCI / CDプロセスを理解する必要があります。次の図はこれを示しています。

最も基本的なプロセスは、ビルド、テスト、およびデプロイの3つの段階で構成されます。分散バージョン制御システムで変更が行われるたびに、Jenkinsサーバーで自動化ループがトリガーされます。プロセス Jenkinsfileを実行するための完全な手順は、ソースリポジトリのルートディレクトリにあります。この単一のファイルは、サーバーにこれらのタスクを実行するタイミングと方法を指示します。

Node.jsアプリケーションの例を書く##

前のセクションで述べたように、自動化されたプロセスは最初にバージョン制御システムに送信されます。

GitHubに新しいリポジトリを作成します。このガイドでは、単純なNode.jsアプリケーションを使用して、Jenkinsパイプラインがどのように機能するかを示します。対応する .gitignoreを選択し、次のコンテンツ READMEで初期化することを忘れないでください。

新しいリポジトリをローカルワークステーションにクローンします。

 git clone [email protected]:<GITHUB_USERNAME>/jenkins-guide.git

お気に入りのテキストエディタを開き、リポジトリのルートディレクトリにファイル app.jsを作成します。次のコンテンツを追加します。

~ /jenkins-guide/app.js

1 2 3 4 5 6 7 8 9101112131415161718192021 ' use strict';const express = require('express');const app = express();// Server connectionconst PORT = 9000;const HOST = '0.0.0.0';// Application contentconst os = ['Windows','macOS','Linux']// Web Serverapp.get('/',function(req,res) { res.json(os);});// Console outputapp.listen(PORT, HOST);console.log(Running on http://${HOST}:${PORT});

このアプリケーションは、[Express](https://expressjs.com/)Webサーバーを使用して、ポート9000でブラウザーに単一のJSON出力を提供します。次に、 test.jsをリポジトリのルートの同じ場所に保存します。

~ /jenkins-guide/ test.js

1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829 var supertest = require("supertest");var should = require("should");var server = supertest.agent("http://nodeapp-dev:9000");// Unit Testdescribe("Webapp Status",function(){ // Test 1 - HTTP status it("Expect HTTP status 200",function(done){ server .get("/") .expect("Content-type",/text/) .expect(200) .end(function(err,res){ res.status.should.equal(200); done(); }); }); // Test 2 - Control Tests it("Mocha Control Test",function(done){ (1).should.be.exactly(1).and.be.a.Number(); done(); });});

これは、 supertest shouldを使用した簡略化されたテストスイートです。テストは2つだけです。最初のテストはHTTPステータスをチェックします。これは200と予想されます。2番目のテストは実際のテストではなく、常に合格するコントロールです。

この例では、2つのDockerコンテナを使用します。1つはExpressを使用する app.js用で、もう1つはMochaを使用するテストスイート用です。各画像には、対応する Dockerfile package.jsonを含む独自のフォルダーがあります。

FROM node:6-alpine

# Create a server directory
RUN mkdir -p /home/node/app
WORKDIR /home/node/app

# Install server dependencies
COPY /express-image/package.json /home/node/app
RUN npm install

# Copy node Application
COPY app.js /home/node/app

# Open port
EXPOSE 9000

CMD ["npm","start"]

App.jsは、起動時にデフォルトでこのイメージを実行します。これは、Webアプリケーションの「ドッカー化」バージョンと考えることができます。

{" name":"express-image","version":"1.0.0","description":"Example Node Application","author":"Your name","repository":{"type":"git","url":"git+https://github.com/<YOUR_USERNAME>/<REPOSITORY_NAME>.git"},"license":"ISC","scripts":{"start":"node app.js"},"dependencies":{"express":"^4.13.3"}}
FROM node:6-alpine

# Create feports directory
RUN mkdir -p /JUnit

# Create a server directory
RUN mkdir -p /home/node/tests
WORKDIR /home/node/tests

# Install app dependencies
COPY /test-image/package.json /home/node/tests
RUN npm install

# Copy test source
COPY test.js /home/node/tests

EXPOSE 9000

CMD ["npm","test"]

このイメージは* reports *フォルダーを作成し、そこから依存関係 package.jsonをインストールします。最初は、モカテストを実行します。

このJSONファイルには、 mocha-junit-reporterを含むすべての必要な依存関係が含まれています。Jenkinsは、ストレージに必要な依存関係をテストするために使用されます。テストスクリプトは、 mochaFileが画像で指定された画像レポートフォルダを使用するオプション Dockerfileで構成されていることに注意してください。最終的なプロジェクトの配布は次のようになります。

**注:**フォルダー構造の方法と2つのDockerコンテナーの実装は珍しいですが、教育上の理由から、Jenkinsパイプラインの機能を示すために使用されています。

アプリケーションを手動で実行する###

実際の自動化プロセスを開始する前に、まず自動化するコンテンツを理解する必要があります。

これで、この架空のWebアプリケーションのビルド、テスト、および展開プロセス全体が完了しました。今度は自動化する時です。

JenkinsとBlueOceanをインストールします##

Jenkinsには、多くのインストールオプションがあります。

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

Jenkinsプロジェクトによって維持されているパッケージを使用すると、配布パッケージマネージャーに含まれているバージョンよりも新しいバージョンを使用できます。

  1. Jenkinsの現在の安定バージョンのリポジトリキーをダウンロードして追加します。wget-q-O-https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add-
  2. 新しいリポジトリを sources.listに追加します:sudo sh -c'echo deb http://pkg.jenkins.io/debian-stable binary />/etc/apt/sources.list.d/jenkins。リスト'
  3. システムを更新してJenkinsをインストールします。sudoaptupdatesudo apt install jenkins
  4. Jenkinsをインストールしたので、Dockerコマンドを実行する権限をユーザーに付与する必要があります。sudousermod-aG docker jenkins
  5. デーモンの使用を制御するのは非常に簡単です。sudoservicejenkinsを選択し、 start stoprestart、または statusを選択します。サービスを開始してインストールを確認します。sudoservicejenkinsstart
  6. 問題がなければ、起動時にサービスを有効にしてください。 sudo systemctl enable jenkins
  7. Linode Managerを使用してサーバーを再起動し、これらの変更を適用します。 警告: Jenkinsリモートインストールのセキュリティパラメータを確立することは、このガイドの範囲を超えています。ただし、実稼働環境で対処する必要がある次の重要なポイントに注意してください。

ジェンキンスのセットアップ##

スクリプトと宣言パイプライン構文##

Jenkinsは、 Jenkinsfile構文に2つの異なるオプションを提供します。

どちらも継続配信とJenkinsプラグインをサポートしています。スクリプト構文はGroovyプログラミング環境に基づいているため、より完全です。一方、宣言的文法は「ジェンキンスのパイプラインを作成するためのより単純で洞察に満ちた文法を提供するために作成された」ため、日常の自動構築に適しています。構文の比較について詳しくは、[Jenkinsのドキュメント](https://jenkins.io/doc/book/pipeline/syntax/#compare)をご覧ください。

このガイドでは、宣言構文を使用してJenkinsプロセスを説明します。これは、その設計が実装と理解が容易だからです。

Jenkinsfile構造##

宣言的なパイプライン構文は非常に直感的です。最も基本的なレイアウトは、以下に示すレイアウトに似ています。

コードブロックは中括弧( {および })で区切られ、セミコロンを使用しません。各ステートメントは独自の行にある必要があり、 Jenkinsfileは実行するステップの中核です。一般的な手順は次のとおりです。

これらの操作はすべて、内部で実行できます。エージェント、またはSSHを介してリモートで操作を実行するようにJenkinsに指示できます。ご覧のとおり、自動化には無限の可能性があります。単純なシナリオでは、ステージを順番に実行する1つのパイプラインだけで、目的の最終状態を実現できますが、必要に応じて並列で実行するようにパイプラインを定義できます。 Jenkinsの宣言パイプライン構文の詳細については、[公式ドキュメント](https://jenkins.io/doc/book/pipeline/syntax/)を参照してください。

パイプラインの使用を開始します##

ここから、次の貴重な情報を取得できます。1)ビルド番号、2)各ステップのコンソール出力、3)さらに分析するステージの選択、4)変更の送信、テストに関する情報を含むタブの参照結果と保存されたアーティファクトに関する情報、5)ビルドの再生、6)パイプラインの視覚的な編集、7)パイプライン設定に移動します。

Jenkinsを使用してプロセス全体を自動化します###

Jenkinsfileテンプレートは、3つのステージしかない非常に基本的なパイプライン構造を使用します。必要に応じて、複数のステージに合わせてカスタマイズできます。最終的なパイプライン構造は、プロジェクトの複雑さと従う必要のある開発ガイドラインによって決まります。 Node.jsの例がわかったので、各ステージを自動化するパイプラインを設計する方法を理解しました。このガイドの目的上、最終的なパイプラインは次のようになります。

** Pipeline ** ###に変更を送信します

最初にJenkinsfileを編集し、次のパイプラインを貼り付けます。置換 <DockerHub Username> あなた自身の情報のために。

〜/ Jenkinsガイド/ Jenkinsfile

|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99100101| pipeline { environment { DOCKER = credentials('docker-hub') } agent any stages {// Building your Test Images stage('BUILD') { parallel { stage('Express Image') { steps { sh 'docker build -f express-image/Dockerfile \ -t nodeapp-dev:trunk .' } } stage('Test-Unit Image') { steps { sh 'docker build -f test-image/Dockerfile \ -t test-image:latest .' } } } post { failure { echo 'This build has failed. See logs for details.' } } }// Performing Software Tests stage('TEST') { parallel { stage('Mocha Tests') { steps { sh 'docker run --name nodeapp-dev --network="bridge" -d \ -p 9000:9000 nodeapp-dev:trunk' sh 'docker run --name test-image -v $PWD:/JUnit --network="bridge" \ --link=nodeapp-dev -d -p 9001:9000 \ test-image:latest' } } stage('Quality Tests') { steps { sh 'docker login --username $DOCKER_USR --password $DOCKER_PSW' sh 'docker tag nodeapp-dev:trunk /nodeapp-dev:latest' sh 'docker push /nodeapp-dev:latest' } } } post { success { echo 'Build succeeded.' } unstable { echo 'This build returned an unstable status.' } failure { echo 'This build has failed. See logs for details.' } } }// Deploying your Software stage('DEPLOY') { when { branch 'master' //only run these steps on the master branch } steps { retry(3) { timeout(time:10, unit: 'MINUTES') { sh 'docker tag nodeapp-dev:trunk /nodeapp-prod:latest' sh 'docker push /nodeapp-prod:latest' sh 'docker save /nodeapp-prod:latest | gzip > nodeapp-prod-golden.tar.gz' } } } post { failure { sh 'docker stop nodeapp-dev test-image' sh 'docker system prune -f' deleteDir() } } }// JUnit reports and artifacts saving stage('REPORTS') { steps { junit 'reports.xml' archiveArtifacts(artifacts: 'reports.xml', allowEmptyArchive: true) archiveArtifacts(artifacts: 'nodeapp-prod-golden.tar.gz', allowEmptyArchive: true) } }// Doing containers clean-up to avoid conflicts in future builds stage('CLEAN-UP') { steps { sh 'docker stop nodeapp-dev test-image' sh 'docker system prune -f' deleteDir() } } }}|
|--------|--------|

この完全なJenkinsfileは、宣言構文を使用して記述されています。注意深く読むと、前のセクションでアプリケーションの展開中に使用されたのと同じプロセスが説明されていることがわかります。このセクションでは、Jenkinsファイルをより詳細に分析します。

プロキシと環境変数###

最初のブロックは、グローバルに利用可能な環境変数 DOCKERを定義します。パイプラインブロックの内側にあるがステージブロックの外側にあるため、グローバルに適用するように指示できます。次は agentのステートメントです。これは、Jenkinsが任意の(サーバー)エージェントを使用できることを意味します。

〜/ Jenkinsガイド/ Jenkinsfile

12345 pipeline { environment { DOCKER = credentials('docker-hub') } agent any

DOCKERの定義は、* voucher *関数を介して完了します。これにより、Jenkinsファイルに含めずに機密のログイン情報を使用できます。このキーペアを構成するには:

この例のパイプラインでは、 DOCKER = authentication( &#39;docker-hub&#39;)は、dockerhubアカウントへのログインに使用できる DOCKER_USER DOCKER_PWDの2つの環境変数を作成します。

ビルドフェーズ###

parallelコードブロックについて最初に気付くのは、それが自明であるということです-それはサブフェーズを並列に実行します。これは、以前に使用したのと同じシェルコマンドを使用して2つのDockerイメージを構築する場合に非常に役立ちます。各画像は独自のステップで宣言されますが、これも独立フェーズの一部です。

~ /jenkins-guide/Jenkinsfile

1 2 3 4 5 6 7 8 910111213141516171819202122 // Building your Test Images stage('BUILD') { parallel { stage('Express Image') { steps { sh 'docker build -f express-image/Dockerfile \ -t nodeapp-dev:trunk .' } } stage('Test-Unit Image') { steps { sh 'docker build -f test-image/Dockerfile \ -t test-image:latest .' } } } post { failure { echo 'This build has failed. See logs for details.' } } }

並列フェーズを閉じた後、「post」状態が発生します。 Postは、定義が BUILDフェーズ全体に適用されることを意味します。この場合、 failure条件のみが設定されるため、 BUILDフェーズのいずれかの部分が失敗した場合にのみ実行されます。 Jenkinsが通信用に提供するさまざまなツールの構成は、このガイドの範囲を超えています。

テストフェーズ###

テストフェーズでも並列実行を使用します。

~ /jenkins-guide/Jenkinsfile

1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233 // Performing Software Tests stage('TEST') { parallel { stage('Mocha Tests') { steps { sh 'docker run --name nodeapp-dev --network="bridge" -d \ -p 9000:9000 nodeapp-dev:trunk' sh 'docker run --name test-image -v $PWD:/JUnit --network="bridge" \ --link=nodeapp-dev -d -p 9001:9000 \ test-image:latest' } } stage('Quality Tests') { steps { sh 'docker login --username $DOCKER_USR --password $DOCKER_PSW' sh 'docker tag nodeapp-dev:trunk /nodeapp-dev:latest' sh 'docker push /nodeapp-dev:latest' } } } post { success { echo 'Build succeeded.' } unstable { echo 'This build returned an unstable status.' } failure { echo 'This build has failed. See logs for details.' } } }

Mocha Testsステージは2つの画像で始まり、自動テストを実行します。結果の reports.xmlはJenkinsワークスペースファイルに保存されます。一方、この「品質テスト」ステージでは、アプリケーションの「トランク」バージョンがDockerHubに公開されます。最初に(事前定義された資格情報を使用して)Dockerログインコマンドを発行し、次にイメージタグを変更してプッシュします。

ここでも、「post」コードブロックがありますが、今回は、正常な完了、不安定性、および失敗の通知があります。ここでは、通知だけでなく、任意のコードを使用できることを忘れないでください。

展開フェーズ###

この段階では、さまざまなタイプのブロックが導入されます: when。名前が示すように、この句は特定の条件が満たされた場合にのみ実行されます。この例の場合、マスターブランチへの変更が検出された場合にのみコードが実行されます。他のブランチに送信しても、パイプラインのこのステップはトリガーされません。

このステップでは、 retryおよび timeoutパラメーターを構成することを選択できます。上記の例は、イメージ構築プロセスのタイムアウトが10分で、タイマーの期限が切れると合計3回の再試行があるネストされた使用法を示しています。

postブロックは、障害が発生した場合にクリーンアップするように設計されています。この段階では通知は設定されていません。

レポートとクリーンアップフェーズ###

パイプラインの最後の2つの段階は比較的単純です。 junitステートメントにより、JenkinsはMochaイメージによって生成された reports.xmlファイルを使用でき、 archiveArtifactsコマンドはレポートファイルとアプリケーションファイルを永続的な場所に保存します。デフォルトでは、場所は JENKINS_HOME / var / lib / jenkins / jobs /です。<REPOSITORY> / branchs / master / builds / lastStableBuild。必要に応じて、Jenkinsの一般設定でカスタムの場所を構成できます。

支店との協力###

完全なJenkinsファイルをJenkinsサーバーに送信し、新しいパイプラインの実行をトリガーします。 「when」で前述したブロックをテストするために、変更は別のブランチにプッシュされます。

自動トリガーを構成する###

リポジトリを定期的にスキャンするようにJenkinsを設定できます。これを行うには、パイプラインビューのギアアイコンをもう一度クリックしてから、構成をクリックします。多くのオプションがあります。 スキャンリポジトリトリガーを探します。実行されていない場合定期的にこのチェックボックスをオンにしてください。何度でも選択できます。この例では、1分が選択されます。

テストに失敗しました(不安定なパイプライン)###

これまでのところ、すべてがエラーなしで期待どおりに機能するはずです。しかし、エラーが発生するとどうなりますか?

~ /jenkins-guide/app.js

12345 // Web Serverapp.get('/ERROR',function(req,res) { res.json(os);});

失敗の段階###

これで、 BUILDステージでエラーが発生します。

~ /jenkins-guide/express-image/package.json "dependencies": { "express-ERROR": "^4.13.3" }

  1. 下にスクロールして、エラーを確認します。

  1. エラー express-image / package.jsonを修正します。

プルリクエストのマージ###

trunkブランチを masterにマージしました。これにより、展開フェーズを含むパイプライン全体の操作がトリガーされます。

git checkout master
git merge trunk
git push origin master

外の青い海のダッシュボード##

ブルーオーシャンインターフェースはまだ開発中です。つまり、ジェンキンスの多くの側面が新しいインターフェースによって管理されていません。最も一般的な画面のいくつかを次に示します。

  1. ギアアイコンをクリックして、リポジトリメニューに入ります。そこで、左側のサイドバーの[ステータス]をクリックします。ブランチといくつかの一般情報が表示されます。

  1. masterブランチをクリックすると、より詳細なダッシュボードが表示されます。

このビューから、ログ、アーティファクト、変更、テスト結果の傾向など、多くの有用な情報を表示できます。

未来の道##

このガイドでは、ジェンキンスとブルーオーシャンの基本的な自動ワークフローを紹介しますが、できることはたくさんあります。いくつかの可能性を挙げれば:

詳しくは##

このトピックの詳細については、次のリソースを参照してください。これらは有用であることを願って提供されていますが、外部でホストされている資料の正確性や適時性を保証することはできませんのでご注意ください。

チュートリアルの詳細については、[Tencent Cloud + Community](https://cloud.tencent.com/developer?from=10680)にアクセスして詳細をご覧ください。

参照:「[https://www.linode.com/docs/development/ci/automate-builds-with-jenkins-on-ubuntu/](https://www.linode.com/docs/development/ci/automate-builds-with-jenkins-on-ubuntu/)」

Recommended Posts

Jenkinsを使用してUbuntuで自動的にビルドする方法
Ubuntu16.04にJenkinsをインストールする方法
Ubuntu20.04にJenkinsをインストールする方法
Ubuntu18.04にJenkinsをインストールする方法
ubuntu16.04でnfsサービスを構築する方法
Ubuntu16.04でNginxのマップモジュールを使用する方法
Ubuntu20.04にDockerをインストールして使用する方法
Ubuntu18.04にCurlをインストールして使用する方法
Ubuntu18.04にComposerをインストールして使用する方法
Ubuntu18.04にWineをインストールして使用する方法
Ubuntu14.04でDockerデータボリュームを使用する方法
Ubuntu14.04でRancherを使用してJenkinsを管理する方法
Ubuntu14.04にBaasBoxをインストールして使用する方法
Ubuntu16.04にPostgreSQLをインストールして使用する方法
Ubuntu16.04にDockerをインストールして使用する方法
LVMを使用してUbuntu18.04でストレージデバイスを管理する方法
Ubuntu14.04でMongoDBバックアップを作成して使用する方法
Ubuntu18.04にMySQLWorkbenchをインストールして使用する方法
Ubuntu20.04にRubyをインストールする方法
Ubuntu20.04にMemcachedをインストールする方法
Ubuntu20.04にJavaをインストールする方法
Ubuntu20.04にMySQLをインストールする方法
ubuntuでhanlpを使用する方法
Ubuntu20.04にVirtualBoxをインストールする方法
Ubuntu20.04にElasticsearchをインストールする方法
Ubuntu20.04にNginxをインストールする方法
Ubuntu20.04にApacheをインストールする方法
Ubuntu20.04にGitをインストールする方法
Ubuntu16.04にNode.jsをインストールする方法
Ubuntu20.04にMySQLをインストールする方法
Ubuntu20.04にVagrantをインストールする方法
CentOS8にJenkinsをインストールする方法
Ubuntu16.04にPostgreSQLをインストールする方法
Ubuntu20.04にGitをインストールする方法
Ubuntu18.04にMemcachedをインストールする方法
Ubuntu14.04にMemSQLをインストールする方法
Ubuntu16.04にMongoDBをインストールする方法
Ubuntu14.04にMailpileをインストールする方法
Ubuntu14.04でPHP7にアップグレードする方法
Ubuntu20.04にSkypeをインストールする方法
Ubuntu18.04にPython3.8をインストールする方法
Ubuntu18.04にKVMをインストールする方法
Ubuntu20.04にKVMをインストールする方法
ubuntu14.04にopencv3.0.0をインストールする方法
Ubuntu20.04にAnacondaをインストールする方法
Ubuntu20.04にApacheをインストールする方法
Ubuntu20.04にRをインストールする方法
Ubuntu16.04にMoodleをインストールする方法
Ubuntu14.04にSolr5.2.1をインストールする方法
Ubuntu16.04にTeamviewerをインストールする方法
Ubuntu14.04でNginxを保護する方法
Ubuntu20.04にMariaDBをインストールする方法
Ubuntu20.04にNginxをインストールする方法
Ubuntu20.04にMonoをインストールする方法
Ubuntu20.04にGoをインストールする方法
Ubuntu20.04にZoomをインストールする方法
Ubuntuでソフトウェアをアンインストールする方法
Ubuntu16.04にNginxをインストールする方法
Ubuntu20.04にOpenCVをインストールする方法
Ubuntu20.04にSpotifyをインストールする方法
Ubuntu18.04にPostmanをインストールする方法