Flutter WebをAmazon Linux2023でホスト Jenkinsでデプロイ
以下の記事でFlutter WebアプリをEC2に手動アップロードしてデプロイしました。
今回はEC2にJenkinsをインストール、ソースコードをGitHubにおいて、 半自動でデプロイできるようにしました。
- ソースコードをコミット
- jenkinsでボタンを押すと最新のソースコードでデプロイ
インフラ環境
手動でデプロイしたときと同じ構成ですが、テンプレートには変更点があります。
- apache.yaml
- インスタンスサイズをt2.micro(無料利用枠あり)からt2.mediumに変更しています。理由はflutterアプリのビルドが1時間経っても終わらなかったので。。。
- UserDataにJenkinsをインストール/起動するスクリプトを追加しています。
- UserDataにgitをインストールするスクリプトを追加しています。JnekinsのGitプラグインをインストールしても、Git本体はインストールされないです。
- UserDataにflutterをインストールするスクリプトを追加しています。
- security_group_apache.yaml
- インバウンドルールにJenkinsにhttpsアクセスするときのポート8443を許可します。
テンプレートを使っていただければ、必要なソフトがインストールされたサーバが起動します。
Jenkins 初期設定
httpsを有効化
httpのままではJenkinsとの通信が暗号化なしでインターネットを通るため、httpsを有効にして通信を暗号化します。 パスワードや秘密鍵を入力しますので。
以下の記事を参考にさせていただきました。
自己証明書を作成
自己証明書をkeytoolコマンドで作成し、権限を変更してjenkinsが読み取れるようにします。
# jenkinsのホームディレクトリに移動
cd /var/lib/jenkins
# keytoolを実行
sudo keytool -genkey -alias jenkins-ssl-cert -keyalg RSA -keystore keystore -validity 3650
sudo chown ec2-user:ec2-user keystore
以下はkeytoolを実行したときの画面です。 パスワードだけ入力して、他は空です。
Jenkins HTTPSの設定
Jenkinsのシステム設定を変更して、HTTPSを有効化します。
Linuxに慣れてないので、ここで1日くらい時間を取られました。
いろいろな記事を渡りましたが、最終的に以下の公式ページが参考になりました。
system edit jenkins
設定変更は以下のコマンドから行います。
# systemdのオーバライドでHTTPS設定を行う
sudo systemctl edit jenkins
実行すると、”nano”というエディタの編集画面が表示されます。
以下の設定をコピペします。 PASSWORDはkeystoreで入力したパスワードです。
[Service]
Environment="JENKINS_PORT=-1"
Environment="JENKINS_HTTPS_PORT=8443"
Environment="JENKINS_HTTPS_KEYSTORE=/var/lib/jenkins/keystore"
Environment="JENKINS_HTTPS_KEYSTORE_PASSWORD=XXXXXX"
以下の画像のように、赤線の間にコピペします。 英文で書かれているように、間以外に記入された内容は保存されません。
コピペしたら、以下のキー入力で保存して閉じます。
^O(Ctrl + o) ⇒ Enter ⇒ ^X(Ctrl + x)
設定内容は以下のファイルに保存されます。
/etc/systemd/system/jenkins.service.d/override.conf
Jenkisnを再起動
再起動して設定を反映させます。
sudo systemctl restart jenkins
補足ですが、override.confを直接編集したり、あらかじめ用意したファイルを置くことも可能です。 その場合はdaemon-reloadで明示的に読み込む必要があります。
sudo systemctl daemon-reload
sudo systemctl restart jenkins
これで、httpsの設定は以上です。
アクセス
ブラウザで以下のURLにアクセスします。
XXX.XXX.XXX.XXXはJenkinsをインストールしたEC2イスタンスのPublic IpまたはDNSです。
自己証明書が信頼されていないので以下のような画面になりますが、”~に進む(安全ではありません)”をクリックしてください。
今後、AWSのロードバランサを使ってhttpsでアクセスさせてみようと思ってます。
Unlock Jenkins
初めてJenkinsにアクセスすると、以下ののページが表示されます。
記載に従って、Jenkinsのロックを解除します。
EC2のLinuxにログインして、以下のコマンドを入力すると、初期パスワードが取得できます。
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
プラグインの設定
以下のように二つのプラグイン設定する画面が表示されます。
Jenkinsに詳しくないので、左のおすすめ設定を選びます。
プラグインのインストールに移り、インストールが始まります。
ユーザ設定
ユーザ情報(名前、パスワード、メールアドレス)を入力します。
表示に従って入力するだけです。
Instance Configuration
JenkinsのRoot URLを設定します。
httpsになっていると思いますので、そのままでOKです。
Jenkins is ready
設定完了です。
Startボタンをクリックします。
Githubで使うSSHの設定
githubからcloneするためにSSHの設定をします。
Git Host Key Verification Configuration
GitHubの公開鍵をJenkinsに登録します。
SSHの接続で接続先がGitHubの本当のサーバであるかを確認するためであり、設定しないと接続できません。
まずはダッシュボードのJenkinsの管理からセキュリティ画面に移動します。
セキュリティ画面のスクロースしていくと、”Git Host Key Verification Configuration”があります。
今回はAccept first connectionを選択します。
Accept first connection
自動でGithubが公開する公開鍵を設定してくれますので、他に作業はありません。
ただし、これは初回アクセス時だけです。
Githubの公開鍵が変わるとKnown hosts fileを削除する必要があります。または他の設定項目による設定が必要です。 これはJenkinsではなく、OpenSSHの動作によるものです。
また、Amazon Linux2でAccept first connectionを設定すると後述のジョブ作成画面で以下のようなエラーが表示されます。
Amazon Linux2にインストールされているOpenSSHのバージョンでは初回アクセスを許可するオプションがないため、エラーになるようです。
OpenSSH 7.6以降なら使用できます。Amazon Linux2023なら問題ありません。
# Amazon Linux2のSSHバージョン確認
[ec2-user@ip-10-0-0-186 jenkins]$ sshd -v
unknown option -- v
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
SSHのバージョンアップで解決できますが、失敗するとSSHでログインできなくなるので、難易度は高いと思います。
他のHost Key Verification Strategyについて
Known hosts file
デフォルトはこれになっています。
jenkinsユーザでbashを起動し、以下の方法で.ssh/known_hostsにGitHubの公開鍵を設定する必要があります。
- 手動で”/var/lib/jenkins/.ssh/known_hosts”を作成
- sshコマンドで初めてGitHubにアクセスすると、known_hostsファイルが作成される。
以下はGithubにアクセスして、known_hostsファイルを作成するコマンドを記載しています。
# rootユーザとなる。ec2ユーザからjenkinsユーザでbashを起動できないため。
sudo su -
# jenkinsユーザとなり、bashを起動
su jenkins --shell=/bin/bash
# sshでGitHubサーバにアクセス。
# 初回アクセス時はGitHubサーバから受け取った公開鍵を受け入れるか聞かれるので、
# yesを選択するとknown_hostsファイルに登録される。
ssh -T git@github.com
# 作成されたかを確認
cat /var/lib/jenkins/.ssh/known_hosts
Manually provided keys
Jenkinsの画面上から手動で設定します。
Approved Host KeysにはGitHub公開鍵をコピペします。
Credentials 認証情報の登録
SSHで使用する秘密鍵を登録します。
Jenkinsの管理からCredentials画面を表示します。
DomainsのGlobalを選択します。
Add Credentialsを選択します。
種類”SSH ユーザ名と秘密鍵”を選択し、IDに好きな値を入力します。 他は空でOKです。ユーザ名は作成が完了すると”jenkins”が自動で設定されます。
秘密鍵は直接入力のみで、開発PCで使用している秘密鍵を入力します。 パスフレーズは空でOKです。
秘密鍵の詳細は以下の記事を参照してください。開発PCでGitHubにPushできているなら、秘密鍵が”~/ssh”に作成済みだと思います。 “~”はユーザフォルダです。Windowsだと”C:\Users\XXX”です。隠しフォルダなので、表示する設定が必要です。
Jenkins用に新しく秘密鍵を作成する場合
鍵を分けたい場合は、以下の記事が参考になります。
Jenkins ジョブ作成
ここからビルドに向けての作業になります。
新規ジョブ作成
ダッシュボードから新規ジョブ作成を選択してください。
フリースタイル・プロジェクトのビルド
ジョブ名を入力して、フリースタイル・プロジェクトのビルドを選択してOKを選択してください。
Configure
General
設定が必須な項目はないです。
ソースコード管理
Gitを選択して以下のように設定してください。
- リポジトリURL
- ビルドしたいリポジトリを入力してください。
- 画像は私が作成したflutterの初期プロジェクトをコミットしたリポジトリです。
- 認証情報
- Credentialsで作成した認証情報を選択してください。
- jenkinsという名前になっていますが、作成したCredentialのユーザ名が空だとこの名前になるようです。
- ブランチ指定
- ビルドしたいブランチを入力してください。
- デフォルトは”*/master”になっていますが、最近githubはmainがデフォルトの名前になっています。私が作成したリポジトリはmainだけなので、mainを入力しています。
ビルド・トリガ
設定必須な項目はありません。
Jenkins上でビルド開始ボタンを押してビルドします。後で説明します。
自動化においては重要なところで、また使ってみたいと思います。
ビルド環境
設定必須な項目はありません。
Build Steps
シェルの実行を選択します。
スクリプトを入力できるので、お好きなスクリプトを入力してください。 スクリプトがエラーなく実行されると成功になります。 何かのビルドが必須というわけではありません。
例えば、以下のスクリプトを入力してビルドを実行すると、gitからブランチをcloneしてhellow worldを出力して成功となります。 gitからコードを取ってくる処理はスクリプトに書く必要はありません。
#!/bin/bash
echo hellow world
flutterアプリをビルドしてApacheのルートディレクトリに出力するスクリプトは以下のようになります。
#!/bin/bash
echo "add path to flutter"
export PATH="$PATH:/usr/bin/flutter/bin"
echo "delete html directory on apache"
rm -rf /var/www/html
echo "flutter version"
flutter --version
echo "build flutter web app and output apache hosted directory"
flutter build web -o /var/www/html
ビルド後の処理
設定必須な項目はありません。
ジョブ作成完了
完成なので保存します。ジョブの作成は以上です。
ビルド
実行
ビルド実行をクリックすると、ビルドが開始されます。
成功
成功すると2回目のように緑のマークがつきます。
1回目はスクリプトの間違いに気づいたので中断しました。
失敗したら赤のマークがつきます。試してみてください。
ビルド出力の確認
各ビルドをクリックすると、スクリプトのコンソール出力を確認できます。
ワークスペース
ビルドするときの作業ディレクトリです。
以下のようにgitから取ってきたファイルが置かれます。
Linuxの中の場所は以下になります。
$ ls /var/lib/jenkins/workspace
'flutter web' 'flutter web@tmp'
ビルド完了
ビルドとデプロイが完了しました。
Webアプリにアクセス
ロードバランサのDNS名からブラウザでアクセスして、flutterのアプリが表示されたら完了です。
メモ
Jenkinsのパスワードを忘れた場合
いったん認証を無効化します。
sudo sed -i 's/<useSecurity>true/<useSecurity>false/' /var/lib/jenkins/config.xml
systemctl restart jenkins