こんにちは、n0bisukeです。IoTLTというライトニングトークイベントを毎月実施していますがスプレッドシートに書いてもらった登壇者情報をconnpassのイベントページに自動反映するというスクリプトをHerokuで動かしています。
昔の登壇スライド: https://speakerdeck.com/n0bisuke/iotltwozhi-erurpaji-shu-falsehua-false-bu-shao-jie-number-yururpa
Herokuの無料枠が2022年11月28日に終わってしまうという話題が有名でしたが、AzureのWebAppsに移行してみました。
動かしているconnpassの自動制御
登壇者からのLT登壇情報をスプレッドシートに記載してもらい、Connpassページに自動反映する といったことをやっています。
connpassにはPOSTのAPIがないのでPuppeteerを使って自動操作を行なって更新処理などを行なっています。
実際のページがこちらです。
スプレッドシートに記載してもらい、Puppeteerでスクリーンショットを撮影し、画像編集などを行います。
Puppeteerでconnpassにログインや編集などをさせます。
また、常に変更ではなくシートに変更があった際にだけ動かすようにしていて、HerokuでWebサーバーとして置いておき、スプレッドシートに変更にあったらHTTPリクエストをさせるような処理をしてました。
移行の流れとハマったところ
移行に際して
- Puppeteerがインストールできるか
- 日本語フォントを使えるか
ってところが障壁になりました。
この辺は別記事にメモしてあります。
0. まずは手元で動くか確認
まずは放置してたので手元にコードがないのでHerokuから手元に持ってきます。
$ heroku git:clone -a connpassupdater2
$ cd connpassupdater2
開いてみるとProcfile
というものがありますね。Herokuならでは感。
{
"name": "iotltupdate_v2",
"version": "1.2.2",
"description": "Program last debug 2021/9/14 => Node.js v16.9.1",
"main": "app.js",
"scripts": {
"start": "node app.js",
"deploy": "git add . && git commit -m 'deloy' && git push heroku master",
"test": "echo \"Error: no test specified\" && exit 1"
},
"engines": {
"node": "16.x"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.21.4",
"express": "^4.17.1",
"gyazo-api": "^0.3.1",
"jimp": "^0.16.1",
"moment": "^2.29.1",
"moment-timezone": "^0.5.33",
"puppeteer": "^10.2.0"
}
}
このボットはpuppeteer
が色々な機能の中心となります。
最終更新をしていたタイミングだとv10系みたいですが、今調べるとv19らしいです。
そのままアップデートは結構怖いですね。
Node.jsもv16系で動かしていたみたいです。
ローカルで動かしてみます。
$ yarn install
yarn install v1.22.19
[1/5] 🔍 Validating package.json...
error iotltupdate_v2@1.2.2: The engine "node" is incompatible with this module. Expected version "16.x". Got "19.0.0"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
早速こけましたね。
Node.js v19で動かそうとしたので怒られています。
取り急ぎpackage.jsonの記載を更新...というか削除します。
"engines": {
"node": "16.x"
},
package.jsonからここを削除すればOKです。うろ覚えですがHerokuだと指定してほしいといった形だったのだと思います。
$ npm i
無事にパッケージのインストールができました。
$ npm start
起動方法忘れちゃうのでpackage.json
にスクリプト書いておくの大事ですね。
取り急ぎ無事に起動しました。
Puppeteerとは関係ないですが、現時点での移行先のWebAppsの最新ランタイムがv18系が使えるとのことで、axiosを使ってる箇所はFetch APIに切り替えてみました。
1. WebAppsでPuppeteerを動かす準備
WebAppsのリソース作成から進みます。
無料で動かしたいのでF1にしたいところですが、パワー不足なのかタイムアウトしてしまう事象が多かったので結果B1にして動かしてみてます。Puppetterを動かすだけならF1でもたぶん大丈夫です。
ただ現状F1にすると、Japan East
は選べなく、Central US
を選ぶ必要があります。
- 公開(デプロイ):
コード
- ランタイム:
Node 18 LTS
- OS:
Linux
- 地域:
Japan East
GitHub Actions経由のデプロイ設定
Herokuで動いていたコードをGitHubにコードをあげておき、GitHub Actions経由でのデプロイ設定をします。
ちなみにプランがF1だとGitHub Actions経由のデプロイは選択出来ないので注意です。直接ローカルGitを選択することになりそうです。
ここまでの設定でWebAppsのインスタンス作成します。
2. GitHub Actionsの設定
GitHubを見ると、.github/workflows/main_アプリ名.yml
という形でymlファイルがGitHubリポジトリ上に作成されていると思います。
# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# More GitHub Actions for Azure: https://github.com/Azure/actions
name: Build and deploy Node.js app to Azure Web App - connpastest
on:
push:
branches:
- main
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Node.js version
uses: actions/setup-node@v1
with:
node-version: '18.x'
- name: npm install, build, and test
run: |
npm install
npm run build --if-present
npm run test --if-present
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v2
with:
name: node-app
path: .
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: 'Production'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v2
with:
name: node-app
- name: 'Deploy to Azure Web App'
id: deploy-to-webapp
uses: azure/webapps-deploy@v2
with:
app-name: 'connpastest'
slot-name: 'Production'
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_123456789 }}
package: .
下から2行目のsecrets.AZUREAPPSERVICE_PUBLISHPROFILE_123456789
の箇所は作成した環境によって異なるのでコピーしておきましょう。
@horihiroさんのブログでAzureでPuppeteerを動かす記事を書いてくれているのですが、
@horihiroさんのGitHub Actionsのサンプルをまるっと差し替えた上で
-
secrets.AZUREAPPSERVICE_PUBLISHPROFILE_
の箇所で先ほどコピーした内容に差し替え - 57行目のappnameの指定で自信のアプリ名に差し替え
を行います。
などが大枠の変更箇所な気がします。
まずは試したいのでnpm initした時のpackage.jsonのテスト部分は削除しておくとよさそう。
GitHub Actions側でここでコケてうまく動かないと思います。ymlからtest部分を削除しておくでもよさそうですね。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
},
3. スタートアップスクリプトを記載する
プロジェクトのルートにappservice
フォルダを作成し、start.sh
というファイルを作成します。
#!/bin/sh
apt update \
&& apt install -y \
libasound2 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcairo2 \
libcups2 \
libdrm2 \
libgbm1 \
libglib2.0-0 \
libnss3 \
libpango-1.0-0 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxkbcommon0 \
libxrandr2 \
&& mkdir /noto && cd /noto \
&& wget https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip \
&& unzip NotoSansCJKjp-hinted.zip \
&& mkdir -p /usr/share/fonts/noto \
&& cp *.otf /usr/share/fonts/noto \
&& chmod 644 -R /usr/share/fonts/noto/ \
&& fc-cache -fv \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /noto
cd /home/site/wwwroot
PUPPETEER_CACHE_DIR=$(pwd)/node_modules/puppeteer node app.js
参考のものでそのままやると日本語がうまく表示されなかったので後半(mkdir /noto && cd /noto
あたり)でフォントのインストールをしています。
参考: https://github.com/horihiro/20221129-puppeteer-on-webapp/blob/main/appservice/start.sh
ちなみに、@horihiroさんリポジトリに.devcontainer
フォルダがありますが、これはスルーして大丈夫です。
スタートアップコマンドを設定する
Azureのポータルの構成 > 全般設定 > スタートアップコマンド
に以下を指定します。
sh /home/site/wwwroot/appservice/start.sh
これでデプロイしてアプリ名.azurewebsite.net
にアクセスすると無事に動いてくれてます。
発生したトラブルその他
GitHub Actionsからデプロイ時の認証エラー
Error: Deployment Failed with Error: Error: Publish profile is invalid for app-name and slot-name provided. Provide correct publish profile credentials for app.
前述した、シークレットとappnameの指定をミスるとここでこけてしまします。
ここも地味にハマりました。
WebAppsにデプロイするとcannot find module 'statuses'と怒られる問題
他の人も上げてましたがイマイチ原因が分からず、npm installがうまくいってなさそうな雰囲気でした。 別のインスタンスを作り直したら消えてしまった事情です。なぞ。。
GitHub Actionsの容量
GitHub Actions側でCreate Artifact Container failed: Artifact storage quota has been hit. Unable to upload any new artifacts.
というエラーが出てデプロイが止まっていたタイミングがありました。
どうやら使いすぎてしまって容量オーバーの模様です。一度Publicにして試したら回避されました。
この辺は別途調べて容量がオーバーしないようにキャッシュクリアしながらやれば問題なさそう。
Herokuとお別れする
移行がうまくできたのでHeroku側のアプリケーションを削除しておきます。
消さなくても勝手に消される模様です。学生や非営利団体向けのプログラムが出る方針らしいのでその辺の動きを待ってから消す消さない判断をしても良いかもしれないですね。
・学生と非営利団体のサポートプログラムを開始
Salesforceは、学生が自分の可能性を実現するために必要なリソースと経験を学生に提供することに、積極的に取り組む姿勢を示しています。学生プログラムの詳細については、2022年9月に開催されるSalesforceのDreamforceカンファレンスで発表される予定とのこと。また、Salesforceは非営利コミュニティとも密接に協力しており、学生及び非営利団体をサポートする今後のプログラムについて順次発表していくそうです。
ログインすると色々とアラート出てますね。
herokuコマンドもアンインストールしておきます。
$ brew uninstall heroku
先人に感謝
今回、色々試してたらめちゃ助けてもらいました。
ほりひろさんありがとうございました!! 情報を色々と教えていただきました。
だいぶ変わってそう (@n0bisuke さんが奮闘中) なので、 2022 年版をまとめるか。。。 https://t.co/jNHd8xP9DT
— ほりひろ loves <⚡> (@hori__hiro) November 29, 2022
Azureのデフォルトymlが少し古い
Azureが自動生成したGitHub Actionsの記述だと少し古いみたいでNode.js 12 actions are deprecated.
と警告がでるのでこの辺りは少し修正したいですね。
もうちょいやりたいところだけど一旦動いたのでここまでで一旦締めておきます。