Ubuntu18.04でGitLabCI/CDを使用して継続的デプロイパイプラインを設定する方法
序章
GitLab は、コードリポジトリのホストを超えた強力な機能を提供するオープンソースのコラボレーションプラットフォームです。 問題の追跡、パッケージとレジストリのホスト、Wikiの保守、継続的インテグレーション(CI)および継続的デプロイメント(CD)パイプラインの設定などを行うことができます。
このチュートリアルでは、GitLabを使用して継続的デプロイパイプラインを構築します。 Dockerイメージを構築し、それをGitLabコンテナーレジストリにプッシュし、SSHを使用してサーバーにデプロイするようにパイプラインを構成します。 パイプラインは、リポジトリにプッシュされたコミットごとに実行されます。
小さな静的Webページを展開しますが、このチュートリアルの焦点はCDパイプラインの構成です。 静的なWebページは、デモンストレーションのみを目的としています。 デプロイに他のDockerイメージを使用して同じパイプライン構成を適用することもできます。
このチュートリアルを終了すると、次のサイトにアクセスできます。 http://your_server_IP
自動展開の結果については、ブラウザで。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Ubuntu 18.04初期サーバーセットアップガイドに従ってセットアップされた1つのUbuntu18.04サーバー(sudo非rootユーザーとファイアウォールを含む)。 少なくとも1GBのRAMと1つのCPUが必要です。
- Ubuntu18.04ガイドにDockerをインストールして使用する方法に従ってサーバーにDockerをインストールします。
- コンテナレジストリが有効になっているGitLabインスタンスのユーザーアカウント。 公式GitLabインスタンスの無料プランは要件を満たしています。 Ubuntu 18.04ガイドにGitLabをインストールして構成する方法に従って、独自のGitLabインスタンスをホストすることもできます。
ステップ1—GitLabリポジトリを作成する
まず、GitLabプロジェクトを作成し、それにHTMLファイルを追加します。 後でHTMLファイルをNginxDockerイメージにコピーし、サーバーにデプロイします。
GitLabインスタンスにログインし、新しいプロジェクトをクリックします。
- 適切なプロジェクト名を付けてください。
- オプションで、プロジェクトの説明を追加します。
- 要件に応じて、可視性レベルをプライベートまたはパブリックに設定してください。
- 最後にプロジェクトの作成をクリックします
プロジェクトの概要ページにリダイレクトされます。
HTMLファイルを作成しましょう。 プロジェクトの概要ページで、新しいファイルをクリックします。
ファイル名を index.html
次のHTMLをファイル本体に追加します。
<html>
<body>
<h1>My Personal Website</h1>
</body>
</html>
ページ下部のコミット変更をクリックしてファイルを作成します。
このHTMLは、ブラウザで開いたときに個人のWebサイトを示す1つの見出しのある空白のページを生成します。
Dockerfileは、DockerがDockerイメージを構築するために使用するレシピです。 を作成しましょう Dockerfile
HTMLファイルをNginxイメージにコピーします。
プロジェクトの概要ページに戻り、 + ボタンをクリックして、新しいファイルオプションを選択します。
ファイル名を Dockerfile
次の手順をファイル本体に追加します。
FROM nginx:1.18
COPY index.html /usr/share/nginx/html
The FROM
命令は、継承する画像を指定します。この場合、 nginx:1.18
画像。 1.18
Nginxバージョンを表す画像タグです。 The nginx:latest
タグは最新のNginxリリースを参照しますが、将来的にアプリケーションが破損する可能性があるため、修正バージョンをお勧めします。
The COPY
命令はコピーします index.html
にファイルする /usr/share/nginx/html
Dockerイメージ内。 これは、Nginxが静的HTMLコンテンツを保存するディレクトリです。
ページ下部のコミット変更をクリックしてファイルを作成します。
次のステップでは、GitLabランナーを構成して、デプロイジョブを実行できるユーザーを制御します。
ステップ2—GitLabランナーの登録
SSH秘密鍵と接触する環境を追跡するために、サーバーをGitLabランナーとして登録します。
デプロイメントパイプラインで、SSHを使用してサーバーにログインする必要があります。 これを実現するには、SSH秘密鍵をGitLab CI / CD変数に保存します(ステップ5)。 SSH秘密鍵は、サーバーへのエントリチケットであるため、非常に機密性の高いデータです。 通常、秘密鍵は、それが生成されたシステムを離れることはありません。 通常の場合、手動でログインして展開ルーチンを実行するために、ホストマシンでSSHキーを生成してから、サーバーでSSHキーを承認します(つまり、公開キーをサーバーにコピーします)。
ここで状況が少し変わります。サーバーへの自律権限(GitLab CI / CD)アクセスを許可して、展開ルーチンを自動化する必要があります。 したがって、秘密鍵は、それが生成されたシステムを離れ、GitLabやその他の関係者に信頼を与える必要があります。 自分の秘密鍵が、自分で制御または信頼されていない環境に入ることは絶対に避けてください。
GitLabに加えて、GitLabランナーは、秘密鍵が入力されるもう1つのシステムです。 パイプラインごとに、GitLabはランナーを使用して重い作業を実行します。つまり、CI/CD構成で指定したジョブを実行します。 つまり、デプロイジョブは最終的にGitLabランナーで実行されるため、SSHを使用してサーバーにログインできるように秘密鍵がランナーにコピーされます。
不明なGitLabランナー(たとえば、共有ランナー)を使用して展開ジョブを実行する場合、システムが秘密鍵に接触していることに気付かないでしょう。 GitLabランナーはジョブの実行後にすべてのデータをクリーンアップしますが、独自のサーバーをGitLabランナーとして登録することで、不明なシステムに秘密鍵を送信することを回避できます。 秘密鍵は、あなたが管理するサーバーにコピーされます。
サーバーにログインすることから始めます。
- ssh sammy@your_server_IP
インストールするために gitlab-runner
サービスでは、公式のGitLabリポジトリを追加します。 インストールスクリプトをダウンロードして検査します。
- curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh > script.deb.sh
- less script.deb.sh
スクリプトの安全性に満足したら、インストーラーを実行します。
- sudo bash script.deb.sh
わかりにくいかもしれませんが、続行するには非rootユーザーのパスワードを入力する必要があります。 前のコマンドを実行すると、出力は次のようになります。
Output[sudo] password for sammy: % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5945 100 5945 0 0 8742 0 --:--:-- --:--:-- --:--:-- 8729
いつ curl
コマンドが終了すると、次のメッセージが表示されます。
OutputThe repository is setup! You can now install packages.
次に、 gitlab-runner
サービス:
- sudo apt install gitlab-runner
サービスステータスを確認して、インストールを確認します。
- systemctl status gitlab-runner
あなたが持っているでしょう active (running)
出力:
Output● gitlab-runner.service - GitLab Runner
Loaded: loaded (/etc/systemd/system/gitlab-runner.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-06-01 09:01:49 UTC; 4s ago
Main PID: 16653 (gitlab-runner)
Tasks: 6 (limit: 1152)
CGroup: /system.slice/gitlab-runner.service
└─16653 /usr/lib/gitlab-runner/gitlab-runner run --working-directory /home/gitlab-runner --config /etc/gitla
ランナーを登録するには、プロジェクトトークンとGitLabURLを取得する必要があります。
- GitLabプロジェクトで、設定> CI / CD>ランナーに移動します。
- 特定のランナーを手動でセットアップするセクションには、登録トークンとGitLabURLがあります。 両方をテキストエディタにコピーします。 次のコマンドで必要になります。 それらはと呼ばれます
https://your_gitlab.com
とproject_token
.
ターミナルに戻り、プロジェクトのランナーを登録します。
- sudo gitlab-runner register -n --url https://your_gitlab.com --registration-token project_token --executor docker --description "Deployment Runner" --docker-image "docker:stable" --tag-list deployment --docker-privileged
コマンドオプションは次のように解釈できます。
-n
を実行しますregister
非対話的にコマンドを実行します(すべてのパラメーターをコマンドオプションとして指定します)。--url
GitLabのランナーページからコピーしたGitLabURLです。--registration-token
GitLabのランナーページからコピーしたトークンです。--executor
エグゼキュータタイプです。docker
Dockerコンテナ内の各CI/CDジョブを実行します( GitLabのエグゼキュータに関するドキュメントを参照)。--description
はランナーの説明であり、GitLabに表示されます。--docker-image
明示的に指定されていない場合、CI/CDジョブで使用するデフォルトのDockerイメージです。--tag-list
ランナーに割り当てられたタグのリストです。 タグをパイプライン構成で使用して、CI/CDジョブの特定のランナーを選択できます。 Thedeployment
タグを使用すると、この特定のランナーを参照してデプロイメントジョブを実行できます。--docker-privileged
CI/CDジョブごとに作成されたDockerコンテナを特権モードで実行します。 特権コンテナーは、ホストマシン上のすべてのデバイスにアクセスでき、コンテナーの外部で実行されているプロセスとほぼ同じようにホストにアクセスできます(ランタイム特権とLinux機能に関するDockerのドキュメントを参照)。 特権モードで実行する理由は、Docker-in-Docker( did )を使用してCI/CDパイプラインにDockerイメージを構築できるようにするためです。 コンテナに必要な最小要件を与えることをお勧めします。 Docker-in-Dockerを使用するには、特権モードで実行する必要があります。 この特定のプロジェクトにのみランナーを登録したことに注意してください。このプロジェクトでは、特権コンテナーで実行されるコマンドを制御できます。
実行後 gitlab-runner register
コマンドを実行すると、次の出力が表示されます。
OutputRunner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
GitLabの設定>CI / CD > ランナーに移動して、登録プロセスを確認します。ここに、登録済みのランナーが表示されます。
次のステップでは、デプロイメントユーザーを作成します。
ステップ3—デプロイメントユーザーの作成
展開タスク専用のユーザーを作成します。 後で、そのユーザーでサーバーにログインするようにCI/CDパイプラインを構成します。
サーバーで、新しいユーザーを作成します。
- sudo adduser deployer
ユーザー作成プロセスをガイドします。 強力なパスワードと、オプションで指定する追加のユーザー情報を入力します。 最後に、ユーザーの作成を確認します Y
.
ユーザーをDockerグループに追加します。
- sudo usermod -aG docker deployer
これにより、deployerは docker
コマンド。これは、展開を実行するために必要です。
警告: Dockerグループにユーザーを追加すると、rootユーザーと同等の権限が付与されます。 これがシステムのセキュリティにどのように影響するかについての詳細は、 Docker Daemon AttackSurfaceを参照してください。
次のステップでは、SSHキーを作成して、deployerとしてサーバーにログインできるようにします。
ステップ4—SSHキーを設定する
デプロイメントユーザー用のSSHキーを作成します。 GitLab CI / CDは後でキーを使用してサーバーにログインし、展開ルーチンを実行します。
SSHキーを生成する新しく作成されたdeployerユーザーに切り替えることから始めましょう。
- su deployer
ユーザーの切り替えを完了するために、deployerパスワードの入力を求められます。
次に、4096ビットのSSHキーを生成します。 の質問に答えることが重要です ssh-keygen
正しくコマンド:
- 最初の質問:で答える
ENTER
、これはキーをデフォルトの場所に保存します(このチュートリアルの残りの部分では、キーがデフォルトの場所に保存されていることを前提としています)。 - 2番目の質問:SSH秘密鍵(認証に使用される鍵)を保護するためのパスワードを構成します。 パスフレーズを指定すると、秘密鍵を使用するたびにパスフレーズを入力する必要があります。 一般に、パスフレーズはSSHキーに別のセキュリティレイヤーを追加します。これは良い習慣です。 秘密鍵を所持している人は、鍵を使用するためにパスフレーズも必要になります。 このチュートリアルでは、CI / CDパイプラインが非対話的に実行されるため、パスフレーズを入力できないため、パスフレーズが空であることが重要です。
要約すると、次のコマンドを実行し、両方の質問を次のように確認します。 ENTER
4096ビットのSSHキーを作成し、空のパスフレーズを使用してデフォルトの場所に保存するには、次のようにします。
- ssh-keygen -b 4096
deployer ユーザーのSSHキーを承認するには、公開キーをに追加する必要があります authorized_keys
ファイル:
- cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
~
Linuxのユーザーホームの略です。 The cat
プログラムはファイルの内容を出力します。 ここでは、 >>
の出力をリダイレクトする演算子 cat
に追加します authorized_keys
ファイル。
このステップでは、CI/CDパイプラインがログインしてアプリケーションをデプロイするためのSSHキーペアを作成しました。 次に、秘密鍵をGitLabに保存して、パイプラインプロセス中にアクセスできるようにします。
ステップ5—秘密鍵をGitLab CI/CD変数に保存する
SSH秘密鍵をGitLabCI/ CDファイル変数に保存して、パイプラインが鍵を使用してサーバーにログインできるようにします。
GitLabがCI/CDパイプラインを作成すると、すべての変数が対応するランナーに送信され、ジョブの期間中、変数は環境変数として設定されます。 特に、 file 変数の値はファイルに保存され、環境変数にはこのファイルへのパスが含まれます。
変数セクションにいる間に、サーバーIPとサーバーユーザーの変数も追加します。これにより、ログイン先のサーバーとユーザーについてパイプラインに通知されます。
SSH秘密鍵を表示することから始めます。
- cat ~/.ssh/id_rsa
出力をクリップボードにコピーします。 後に必ず改行を追加してください -----END RSA PRIVATE KEY-----
:
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
次に、GitLabプロジェクトの設定> CI / CD > 変数に移動し、変数の追加をクリックします。 次のようにフォームに記入します。
- 鍵:
ID_RSA
- 値:クリップボードからSSH秘密鍵を貼り付けます(最後の改行を含む)。
- タイプ:ファイル
- 環境範囲:すべて(デフォルト)
- 保護変数:チェック済み
- マスク変数:チェックなし
注:正規表現の要件を満たしていないため、変数をマスクできません(マスクされた変数に関するGitLabのドキュメントを参照)。 ただし、秘密鍵はコンソールログに表示されないため、マスキングは廃止されます。
秘密鍵を含むファイルが各CI/CDジョブのランナーに作成され、そのパスがに保存されます。 $ID_RSA
環境変数。
サーバーIPを使用して別の変数を作成します。 変数の追加をクリックし、次のようにフォームに入力します。
- 鍵:
SERVER_IP
- 価値:
your_server_IP
- タイプ:変数
- 環境範囲:すべて(デフォルト)
- 保護変数:チェック済み
- マスク変数:チェック済み
最後に、ログインユーザーで変数を作成します。 変数の追加をクリックし、次のようにフォームに入力します。
- 鍵:
SERVER_USER
- 価値:
deployer
- タイプ:変数
- 環境範囲:すべて(デフォルト)
- 保護変数:チェック済み
- マスク変数:チェック済み
これで、秘密鍵がGitLab CI / CD変数に保存されました。これにより、パイプラインの実行中に鍵を使用できるようになります。 次のステップでは、CI/CDパイプラインの構成に進みます。
ステップ6—設定 .gitlab-ci.yml
ファイル
GitLab CI/CDパイプラインを構成します。 パイプラインはDockerイメージを構築し、それをコンテナーレジストリにプッシュします。 GitLabは、プロジェクトごとにコンテナレジストリを提供します。 次の場所に移動すると、コンテナレジストリを調べることができます。 パッケージとレジストリ >> コンテナレジストリ GitLabプロジェクトで(詳細は GitLabのコンテナレジストリドキュメント 。)パイプラインの最後のステップは、サーバーにログインし、最新のDockerイメージをプルし、古いコンテナーを削除して、新しいコンテナーを開始することです。
次に、を作成します .gitlab-ci.yml
パイプライン構成を含むファイル。 GitLabで、プロジェクトの概要ページに移動し、 + ボタンをクリックして、新しいファイルを選択します。 次に、ファイル名をに設定します .gitlab-ci.yml
.
(または、リポジトリのクローンを作成して、以下のすべての変更を行うことができます。 .gitlab-ci.yml
ローカルマシンで、コミットしてリモートリポジトリにプッシュします。)
開始するには、以下を追加します。
stages:
- publish
- deploy
各ジョブはステージに割り当てられます。 同じステージに割り当てられたジョブは並行して実行されます(十分な数のランナーが利用可能な場合)。 ステージは指定された順序で実行されます。 ここでは、 publish
ステージが最初になり、 deploy
ステージセカンド。 後続のステージは、前のステージが正常に終了したとき(つまり、すべてのジョブが合格したとき)にのみ開始されます。 芸名は任意に選ぶことができます。
このCD構成を、アプリをテストおよびビルドする既存のCIパイプラインと組み合わせる場合は、 publish
と deploy
テストに合格した場合にのみ展開が行われるように、既存のステージの次のステージ。
これに続いて、これをあなたの .gitlab-ci.yml
ファイル:
. . .
variables:
TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest
TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA
変数セクションは、ジョブのコンテキストで使用できる環境変数を定義します script
セクション。 これらの変数は、通常のLinux環境変数として使用できます。 つまり、次のようなドル記号を前に付けることで、スクリプトでそれらを参照できます。 $TAG_LATEST
. GitLabは、ジョブごとにいくつかの定義済み変数を作成し、ブランチ名やジョブが処理しているコミットハッシュなどのコンテキスト固有の情報を提供します(事前定義変数の詳細をご覧ください)。 ここでは、事前定義された変数から2つの環境変数を作成します。 それらは以下を表します:
CI_REGISTRY_IMAGE
:特定のプロジェクトに関連付けられているコンテナレジストリのURLを表します。 このURLはGitLabインスタンスによって異なります。 たとえば、 gitlab.com プロジェクトのレジストリURLは、次のパターンに従います。registry.gitlab.com/your_user/your_project
. ただし、GitLabがこの変数を提供するため、正確なURLを知る必要はありません。CI_COMMIT_REF_NAME
:プロジェクトがビルドされるブランチまたはタグの名前。CI_COMMIT_SHORT_SHA
:プロジェクトがビルドされるコミットリビジョンの最初の8文字。
両方の変数は事前定義された変数で構成されており、Dockerイメージにタグを付けるために使用されます。
TAG_LATEST
追加します latest
画像にタグを付けます。 これは、常に最新のリリースを表すタグを提供するための一般的な戦略です。 展開ごとに、 latest
イメージは、新しくビルドされたDockerイメージを使用してコンテナレジストリでオーバーライドされます。
TAG_COMMIT
一方、デプロイされているコミットSHAの最初の8文字をイメージタグとして使用することで、コミットごとに一意のDockerイメージを作成します。 Dockerイメージの履歴をGitコミットの粒度まで追跡できるようになります。 これは、展開に欠陥がある場合に古いバージョンのコードをすばやく展開できるため、継続的な展開を行う場合の一般的な手法です。
次の手順で説明するように、デプロイメントを古いGitリビジョンにロールバックするプロセスは、GitLabで直接実行できます。
$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME
Dockerイメージのベース名を指定します。 GitLabのドキュメントによると、Dockerイメージ名は次のスキームに従う必要があります。
image name scheme<registry URL>/<namespace>/<project>/<image>
$CI_REGISTRY_IMAGE
を表します <registry URL>/<namespace>/<project>
これはプロジェクトのレジストリルートであるため、一部であり必須です。 $CI_COMMIT_REF_NAME
オプションですが、さまざまなブランチのDockerイメージをホストするのに役立ちます。 このチュートリアルでは、1つのブランチのみを操作しますが、拡張可能な構造を構築することをお勧めします。 一般に、GitLabでサポートされているイメージリポジトリ名には次の3つのレベルがあります。
repository name levelsregistry.example.com/group/project:some-tag
registry.example.com/group/project/image:latest
registry.example.com/group/project/my/image:rc1
あなたのための TAG_COMMIT
2番目のオプションを使用した変数 image
ブランチ名に置き換えられます。
次に、以下を追加します .gitlab-ci.yml
ファイル:
. . .
publish:
image: docker:latest
stage: publish
services:
- docker:dind
script:
- docker build -t $TAG_COMMIT -t $TAG_LATEST .
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
- docker push $TAG_COMMIT
- docker push $TAG_LATEST
The publish
セクションは、CI/CD構成の最初のジョブです。 それを分解しましょう:
image
このジョブに使用するDockerイメージです。 GitLabランナーは、ジョブごとにDockerコンテナーを作成し、このコンテナー内でスクリプトを実行します。docker:latest
画像は、docker
コマンドが利用可能になります。stage
ジョブをに割り当てますpublish
ステージ。services
Docker-in-Dockerを指定します—dind
サービス。 これが、GitLabランナーを特権モードで登録した理由です。
のスクリプトセクション publish
jobは、このジョブに対して実行するシェルコマンドを指定します。 これらのコマンドが実行されると、作業ディレクトリはリポジトリルートに設定されます。
docker build ...
:に基づいてDockerイメージを構築しますDockerfile
変数セクションで定義された最新のコミットタグでタグ付けします。docker login ...
:Dockerをプロジェクトのコンテナレジストリにログインします。 事前定義された変数を使用します$CI_BUILD_TOKEN
認証トークンとして。 GitLabはトークンを生成し、ジョブの存続期間中有効なままになります。docker push ...
:両方のイメージタグをコンテナレジストリにプッシュします。
これに続いて、 deploy
あなたへの仕事 .gitlab-ci.yml
:
. . .
deploy:
image: alpine:latest
stage: deploy
tags:
- deployment
script:
- chmod og= $ID_RSA
- apk update && apk add openssh-client
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker pull $TAG_COMMIT"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker container rm -f my-app || true"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker run -d -p 80:80 --name my-app $TAG_COMMIT"
Alpineは軽量Linuxディストリビューションであり、ここではDockerイメージとして十分です。 あなたは仕事をに割り当てます deploy
ステージ。 デプロイメントタグは、タグ付けされたランナーでジョブが実行されることを保証します deployment
、ステップ2で構成したランナーなど。
The script
のセクション deploy
ジョブは2つの構成コマンドで始まります。
chmod og= $ID_RSA
:groupおよびothersのすべてのアクセス許可を秘密鍵から取り消して、所有者のみが使用できるようにします。 これは要件です。そうでない場合、SSHは秘密鍵の操作を拒否します。apk update && apk add openssh-client
:Alpineのパッケージマネージャー(apk)を更新し、openssh-client
、を提供しますssh
指図。
4連続 ssh
コマンドが続きます。 それぞれのパターンは次のとおりです。
ssh connect pattern for all deployment commandsssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "command"
それぞれに ssh
実行しているステートメント command
リモートサーバー上。 そのためには、秘密鍵を使用して認証します。
オプションは次のとおりです。
-i
IDファイルの略で、$ID_RSA
秘密鍵ファイルへのパスを含むGitLab変数です。-o StrictHostKeyChecking=no
リモートホストを信頼するかどうかにかかわらず、質問をバイパスするようにしてください。 この質問は、パイプラインなどの非対話型のコンテキストでは回答できません。$SERVER_USER
と$SERVER_IP
手順5で作成したGitLab変数です。 SSH接続のリモートホストとログインユーザーを指定します。command
リモートホストで実行されます。
展開は、最終的にサーバーで次の4つのコマンドを実行することによって行われます。
docker login ...
:Dockerをコンテナレジストリにログインします。docker pull ...
:コンテナレジストリから最新のイメージを取得します。docker container rm ...
:既存のコンテナが存在する場合は削除します。|| true
名前で実行されているコンテナがなかった場合でも、終了コードが常に成功することを確認しますmy-app
. これにより、コンテナーが存在しない場合(たとえば、最初のデプロイメントの場合)にパイプラインを中断することなく、 deleteifexistsルーチンが保証されます。docker run ...
:レジストリからの最新のイメージを使用して、新しいコンテナを開始します。 コンテナには名前が付けられますmy-app
. ポート80
ホスト上のポートにバインドされます80
コンテナの(順序は-p host:container
).-d
コンテナをデタッチモードで開始します。そうしないと、コマンドが終了するのを待ってパイプラインがスタックします。
注:コマンドを実行するGitLabランナーがまったく同じサーバーであることを考えると、SSHを使用してサーバー上でこれらのコマンドを実行するのは奇妙に思えるかもしれません。 ただし、ランナーはDockerコンテナーでコマンドを実行するため、SSHを使用せずにコマンドを実行する場合は、サーバーではなくコンテナー内にデプロイする必要があるため、必須です。 Dockerをランナーエグゼキューターとして使用する代わりに、シェルエグゼキューターを使用してホスト自体でコマンドを実行できると主張する人もいるかもしれません。 ただし、これによりパイプラインに制約が生じます。つまり、ランナーはデプロイ先のサーバーと同じサーバーである必要があります。 ある日、アプリケーションを別のサーバーに移行したり、別のランナーサーバーを使用したりする可能性があるため、これは持続可能で拡張可能なソリューションではありません。 いずれにせよ、SSHを使用して展開コマンドを実行することは理にかなっていますが、それは技術的または移行関連の理由による場合があります。
これをあなたのデプロイメントジョブに追加して先に進みましょう .gitlab-ci.yml
:
. . .
deploy:
. . .
environment:
name: production
url: http://your_server_IP
only:
- master
GitLab環境を使用すると、GitLab内のデプロイを制御できます。 操作>環境に移動すると、GitLabプロジェクトの環境を調べることができます。 パイプラインがまだ終了していない場合、これまでのところ展開が行われていないため、利用可能な環境はありません。
パイプラインジョブが environment
セクションでは、GitLabは特定の環境のデプロイメントを作成します(ここでは production
)ジョブが正常に終了するたび。 これにより、GitLab CI/CDによって作成されたすべてのデプロイメントをトレースできます。 デプロイメントごとに、関連するコミットとそれが作成されたブランチを確認できます。
古いバージョンのソフトウェアにロールバックできる再展開に使用できるボタンもあります。 で指定されたURL environment
展開の表示ボタンをクリックすると、セクションが開きます。
唯一のセクションは、ジョブが実行されるブランチとタグの名前を定義します。 デフォルトでは、GitLabはリポジトリへのプッシュごとにパイプラインを開始し、すべてのジョブを実行します( .gitlab-ci.yml
ファイルが存在しています)。 The only
セクションは、ジョブの実行を特定のブランチ/タグに制限する1つのオプションです。 ここでは、の展開ジョブを実行します master
ブランチのみ。 ジョブを実行するかどうかに関するより複雑なルールを定義するには、rules構文を参照してください。
注: 2020年10月、GitHubはデフォルトブランチの命名規則をmaster
に main
. GitLabや一般的な開発者コミュニティなどの他のプロバイダーは、このアプローチに従い始めています。 用語 master
このチュートリアルでは、ブランチは、別の名前を持つ可能性のあるデフォルトのブランチを示すために使用されます。
あなたの完全な .gitlab-ci.yml
ファイルは次のようになります。
stages:
- publish
- deploy
variables:
TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest
TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA
publish:
image: docker:latest
stage: publish
services:
- docker:dind
script:
- docker build -t $TAG_COMMIT -t $TAG_LATEST .
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY
- docker push $TAG_COMMIT
- docker push $TAG_LATEST
deploy:
image: alpine:latest
stage: deploy
tags:
- deployment
script:
- chmod og= $ID_RSA
- apk update && apk add openssh-client
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker pull $TAG_COMMIT"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker container rm -f my-app || true"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker run -d -p 80:80 --name my-app $TAG_COMMIT"
environment:
name: production
url: http://your_server_IP
only:
- master
最後に、GitLabのページの下部にあるコミット変更をクリックして、 .gitlab-ci.yml
ファイル。 または、Gitリポジトリのクローンをローカルに作成したら、ファイルをコミットしてリモートにプッシュします。
Dockerイメージを構築してサーバーにデプロイするためのGitLabCI/CD構成を作成しました。 次のステップでは、展開を検証します。
ステップ7—展開の検証
次に、GitLabのさまざまな場所、サーバー、ブラウザーでのデプロイを検証します。
いつ .gitlab-ci.yml
ファイルがリポジトリにプッシュされると、GitLabはそれを自動的に検出し、CI/CDパイプラインを開始します。 作成した時点で .gitlab-ci.yml
ファイル、GitLabは最初のパイプラインを開始しました。
GitLabプロジェクトのCI/ CD > Pipelines に移動して、パイプラインのステータスを確認します。 ジョブがまだ実行中/保留中の場合は、完了するまで待ちます。 合格パイプラインに2つの緑色のチェックマークが表示され、公開およびデプロイジョブが正常に実行されたことを示します。
パイプラインを調べてみましょう。 ステータス列の合格ボタンをクリックして、パイプラインの概要ページを開きます。 次のような一般的な情報の概要が表示されます。
- パイプライン全体の実行期間。
- パイプラインが実行されたコミットとブランチ。
- 関連するマージリクエスト。 担当支店のオープンマージリクエストがある場合は、ここに表示されます。
- このパイプラインで実行されたすべてのジョブとそのステータス。
次に、 deploy ボタンをクリックして、デプロイジョブの結果ページを開きます。
ジョブの結果ページで、ジョブのスクリプトのシェル出力を確認できます。 これは、失敗したパイプラインをデバッグするときに探す場所です。 右側のサイドバーには、このジョブに追加したデプロイメントタグがあり、 DeploymentRunnerで実行されたことがわかります。
ページの一番上までスクロールすると、このジョブは本番環境にデプロイされていますメッセージが表示されます。 GitLabは、ジョブの環境セクションが原因でデプロイが行われたことを認識しています。 本番リンクをクリックして、本番環境に移動します。
すべての本番環境の展開の概要がわかります。 これまでのところ、展開は1つだけでした。 展開ごとに、右端に再展開ボタンがあります。 再デプロイは、その特定のパイプラインのデプロイジョブを繰り返します。
再デプロイメントが意図したとおりに機能するかどうかは、パイプラインの構成によって異なります。これは、同じ状況でデプロイジョブを繰り返す以上のことは行わないためです。 コミットSHAをタグとして使用してDockerイメージをデプロイするように構成したため、パイプラインで再デプロイが機能します。
注:GitLabコンテナーレジストリに有効期限ポリシーがある場合があります。 有効期限ポリシーは、コンテナレジストリから古いイメージとタグを定期的に削除します。 結果として、有効期限ポリシーより古いデプロイメントは再デプロイに失敗します。これは、このコミットのDockerイメージがレジストリから削除されるためです。 有効期限ポリシーは、設定> CI/CD>コンテナレジストリタグの有効期限ポリシーで管理できます。 有効期限は通常、90日などの高い値に設定されます。 ただし、有効期限ポリシーのためにレジストリから削除されたイメージをデプロイしようとした場合は、その特定のパイプラインのpublishジョブを再実行することで問題を解決できます。 、指定されたコミットのイメージを再作成してレジストリにプッシュします。
次に、展開の表示ボタンをクリックします。これにより、 http://your_server_IP
ブラウザで個人用ウェブサイトの見出しが表示されます。
最後に、サーバーにデプロイされたコンテナーを確認します。 すでに切断している場合は、ターミナルにアクセスして再度ログインしてください(sammyとdeployerの両方のユーザーで機能します)。
- ssh sammy@your_server_IP
次に、実行中のコンテナを一覧表示します。
- docker container ls
どれがリストされます my-app
容器:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5b64df4b37f8 registry.your_gitlab.com/your_gitlab_user/your_project/master:your_commit_sha "nginx -g 'daemon of…" 4 hours ago Up 4 hours 0.0.0.0:80->80/tcp my-app
Dockerコンテナーの管理の詳細については、 Ubuntu18.04にDockerをインストールして使用する方法ガイドをお読みください。
これで、展開が検証されました。 次のステップでは、デプロイメントをロールバックするプロセスを実行します。
ステップ8—展開のロールバック
次に、Webページを更新します。これにより、新しいデプロイメントが作成され、GitLab環境を使用して以前のデプロイメントが再デプロイされます。 これは、デプロイメントに欠陥がある場合のデプロイメントロールバックのユースケースをカバーしています。
に少し変更を加えることから始めます index.html
ファイル:
- GitLabで、プロジェクトの概要に移動し、
index.html
ファイル。 - 編集ボタンをクリックしてオンラインエディタを開きます。
- ファイルの内容を次のように変更します。
<html>
<body>
<h1>My Enhanced Personal Website</h1>
</body>
</html>
ページの下部にある[変更をコミット]をクリックして、変更を保存します。
変更を展開するために、新しいパイプラインが作成されます。 GitLabで、 CI / CD>Pipelinesに移動します。 パイプラインが完了したら、開くことができます http://your_server_IP
更新されたWebページのブラウザで、 My PersonalWebsiteの代わりにMyEnhanced PersonalWebsiteが表示されるようになりました。
操作>環境>本番に移動すると、新しく作成されたデプロイメントが表示されます。 次に、最初の古いデプロイメントのre-deployボタンをクリックします。
ロールバックボタンをクリックしてポップアップを確認します。
その古いパイプラインのデプロイジョブが再開され、ジョブの概要ページにリダイレクトされます。 ジョブが終了するのを待ってから開きます http://your_server_IP
ブラウザで、最初の見出し個人用Webサイトが再び表示されます。
このチュートリアルを通じて達成したことを要約してみましょう。
結論
このチュートリアルでは、GitLab CI/CDを使用して継続的デプロイパイプラインを構成しました。 HTMLファイルとDockerfileで構成される小さなWebプロジェクトを作成しました。 次に、 .gitlab-ci.yml
パイプライン構成:
- Dockerイメージをビルドします。
- Dockerイメージをコンテナーレジストリにプッシュします。
- サーバーにログインし、最新のイメージをプルして、現在のコンテナーを停止し、新しいコンテナーを開始します。
これで、GitLabは、リポジトリにプッシュするたびにWebページをサーバーにデプロイします。
さらに、GitLabとサーバーでのデプロイを確認しました。 また、2番目のデプロイメントを作成し、GitLab環境を使用して最初のデプロイメントにロールバックしました。これは、欠陥のあるデプロイメントに対処する方法を示しています。
この時点で、展開チェーン全体が自動化されています。 コードの変更を世界中や顧客とより頻繁に共有できるようになりました。 その結果、フィードバックの収集とコード変更の公開に必要な時間が短縮されるため、開発サイクルが短くなる可能性があります。
次のステップとして、ドメイン名でサービスにアクセスできるようにし、HTTPSとの通信を保護することができます。DockerコンテナのリバースプロキシとしてTraefikを使用する方法は適切なフォローアップです。