Azure DevOps Pipelines で Nuxt.js アプリを Firebase に継続的にデプロイする

kheiakiyama.hateblo.jp

Nuxt.js で書いたアプリですが、デプロイが煩わしい状態でしたので、最近話題の Azure DevOps を使って継続的デプロイを設定しました。

Azure DevOps Pipelines について

まずは公式リンク。

azure.microsoft.com

なぜ Azure DevOps(Pipelines) を使うかというと、プライベートリポジトリを使う場合の CI/CD サービスで Travis CI や CircleCI を使うとそこそこの費用が発生するためです。
(私は GitHub はプライベートリポジトリを使っています)
ギョーム開発であれば有償サービスを使うべきかとは思いますが、Azure DevOps Pipelines は月1,800分の無償枠があります。(2018/9/14 現在)
個人開発で何かを作るにはこの枠を有効に使えるのではないでしょうか。

実装方法

Azure DevOps Pipelines

DevOps Pipelines では GUI で設定する方法とYAMLファイルで設定する方法がある。
GUI で作ったものは後からYAMLを確認できるので、まずは GUI から入るとよい。
ここでは結果のみ書く。

以下の yamlリポジトリ直下に置き、Agent-pool は Hosted Ubuntu 1604 を使う。

azure-pipelines.yml

pool:
  vmImage: 'Ubuntu 16.04'
  
variables:
  firebaseToken: '********'

steps:
- script: |
   #!/bin/bash
   npm install firebase-tools firebase-functions firebase-admin
  displayName: 'Install firebase-cli'

- task: Npm@1
  displayName: 'npm install'
  inputs:
    verbose: false

- script: |
   #!/bin/bash
   npm run build
   npm run copyassets
   node_modules/.bin/firebase deploy --token $(firebaseToken)
  displayName: 'Run npm deploy'

パイプライン内では npm のグローバル環境下に Firebase CLI をインストールする権限がないため、firebase はローカルにインストールしています。
そのため firebase deploy はパス指定して動かす苦肉の策で実行しています。

このYAML についてのドキュメントはまだまだ充実してません。
サンプルコードが以下に紹介されており、GitHub を漁ると iOSAndroid のサンプルも見つかるので参考になれば。

Create your first pipeline | Microsoft Docs

Node 部分

package.json

  "scripts": {
    "dev": "nuxt",
    "build": "npm run clean && nuxt build",
    "clean": "rm -rf dist && rm -rf functions/nuxt",
    "deploy": "npm run build && npm run copyassets && firebase deploy", // for local only
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "precommit": "npm run lint",
    "copyassets": "mkdir -p dist/assets && npm run copydist && npm run copystatic",
    "copydist": "cp -R functions/nuxt/dist/ dist/assets",
    "copystatic": "cp -R static/ dist"
  },

Nuxt.js 部分

nuxt.config.js

module.exports = {
  buildDir: "functions/nuxt",
  build: {
    publicPath: "/assets/",
  }

感想

Microsoft-Hosted Agent の Docker Image に Firebase CLI を入れる PullRequest 書いたら通るのでしょうか。
後で気が向いたら試してみようと思います。
GitHub - Microsoft/vsts-agent-docker: Visual Studio Team Services (VSTS) Agent Docker Images

Self-Hosted Agent を作るのは結構敷居が高い印象あるので、Travis CI のように Agent に使う Docker Image を指定できると 一番理想的です。

Nuxt.jsビギナーズガイド―Vue.js ベースのフレームワークによるシングルページアプリケーション開発

Nuxt.jsビギナーズガイド―Vue.js ベースのフレームワークによるシングルページアプリケーション開発

Nuxt.js を Firebase Hosting, Function で SSR する

コストかけずに始めていざとなったらスケールするインフラとして Firebase が気になっている。
そしてWebのフロントエンドで疲弊しないための選択肢として Vue.js が同じく気になりだした。
SPA(SinglePageApplication)やるとSSR(ServerSideRendering)がサービスの性質によっては必要になるので、そこをどう実現するのかを試してた。

参考資料

Nuxt.js は公式ガイドが非常に充実していて、日本語もある。

はじめに - Nuxt.js

公式が一番の近道。
あとは参考にすべき実装は Qiita やブログではなく、以下のリポジトリが一番わかりやすかった。

github.com

解説

まず通常の静的サイトホスティングであれば Nuxt.js の公式に Firebase へのデプロイ方法が書いてあるので、SSRが不要であれば以下のドキュメント通りに実現するのがよい。

ルーティング - Nuxt.js

SSRをやる場合、フロントのURLは Firebase Hosting から払い出される xxx.firebaseapp.com になるが、Hosting するのはアセットのみで、各ページのルーティングURLへのアクセスは裏側の Functions にリライトする形となる。
上にあげたリポジトリのコードを読んでいて、この点に気づくまでに時間がかかった。。

以下の Firebase ドキュメントにリライトの適用ルールについて記載されている。

Customize Hosting Behavior  |  Firebase

他にやること

SSR は検索サービスにページをインデックスしてもらうのが目的の一つだと思う(クライアントの負荷軽減など他にもあるが)が、サイトマップの生成などやることは他にもありそうだ。

感想

Vue.js ならびに Nuxt.js は全部入りって感が強く、比較すべきではないが React やWebPackなどでどう組み合わせるか考えるのが億劫な人にはちょうどいいソリューションだと感じている。
自分にとってはフロントエンドの裏側に API サーバーを Go で書きたいとかやりたいことがそっち方面に広がっているので、学習コストがそこそこに済むものを使っていきたい。
とはいえやっていくうちに悪いところも見えてくるに違いない。

Nuxt.jsビギナーズガイド―Vue.js ベースのフレームワークによるシングルページアプリケーション開発

Nuxt.jsビギナーズガイド―Vue.js ベースのフレームワークによるシングルページアプリケーション開発

Firebase をざっくり理解するためにサンプルアプリ書いた

Firebase を使う機会があり、どんなものか理解するためにやったことを書いておく。

把握する

Firebase の公式サンプル を見ると、ほぼすべての機能を網羅している FriendlyPix というアプリがあったので、これのコード・ドキュメントを読み込むことにした。

Friendly Pix

iOS, Android をほぼ書いたことがないため、Web に対応されていたのが大きい。

github.com

使って理解する

コード読むとわかった気になるが、書けるようにならないと理解したとは言えない。
なので上であげた fiendlypix-web をベースに fork したアプリを書いた。

ちょうと GitHub のコントリビュートの度合いが可視化できると面白いかなと思ったので、それらしいもの。

Repos Presense

ドメイン取るほどでもないので雑に作って雑に公開。

主な変更点は

  • GitHub 認証に変更
  • 写真のファイル保存機能を削除
  • GitHub のコントリビュート数を取得、自分のコントリビュートが何番目かを表示するように変更
  • アプリ名称変更に伴うドキュメント類の書き換え

これらによって、database の具体的な設計方法や Authentication の手軽さなどがわかった。

はてなブログにリンク貼って気づいたけど、meta データ変更してなかった。

余談

最近は Qiita ややってみた記事を読むことが減ってきて、公式ドキュメントを重視するようになってきた。
はてブのテクノロジー記事追っても PodCast 聴いても技術は身につかないし、手を動かしていきたい。

WEB+DB PRESS Vol.105

WEB+DB PRESS Vol.105

  • 作者: 小笠原みつき,西村公宏,柳佳音,志甫侑紀,池田友洋,木村涼平,?橋優介,大塚雅和,飯塚直,吉川竜太,末永恭正,久保田祐史,浜田真成,穴井宏幸,大島一将,桑原仁雄,牧大輔,池田拓司,はまちや2,竹原,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/06/23
  • メディア: 単行本
  • この商品を含むブログを見る

CentOS で Microsoft SQL Server Command Line Client を使いたいときの Docker Image

公式で用意された Docker ImageUbuntu 16.04 ベースになっており、CentOS で使いたかったので書いた。

Docker Hub

Docker Hub - kheiakiyama/centos7-mssql-tools

GitHub

GitHub - kheiakiyama/centos7-mssql-tools: Unofficial images for Microsoft SQL Server Command Line Tools (sqlcmd/bcp) on CentOS7

つくりかた

Linux 環境での利用方法は以下のドキュメントにあるので、それを Dockerfile におこすだけ。

docs.microsoft.com

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

Go 言語を始めるためにやったこと

覚えているうちに書いておきます。

ソースコード置き場の検討

現時点では Mac でのみ開発しています。
(Home)/go/src/github.com/kheiakiyama/(project) に並べるようになりました。

$GOPATH は (home)/go です。

言語の仕組みをざっと理解

Go についての連載記事があったので一通りざっと読みました。

ascii.jp

Go = 使い勝手のよい C++ というのがネット上の評価だと思っていたので、特にメモリ周りがどうなっているのかが気になった次第。
GC が面倒見てくれる C++ があったら便利ですね。

小さいプロダクトで試す

以前 Ruby, Rails を勉強したときもそうだったが、小さいサービスを書くのがモチベーションを維持しつつやりやすい。
Rails のときの記事はこちら。

kheiakiyama.hateblo.jp


ついでに最近 terraform と仲良くなってきたのでそこも練習したのが以下。

kheiakiyama.hateblo.jp

github.com

ちょっと小さすぎだし、コードの最適化といった発想が全然できてないのでもう少しサイズの大きいサービスで試したい。
ホントは Rails で書いたやつを Go に移植してみようと書き始めたが、Go では View が面倒ということが判明し、では静的サイトジェネレータで・・・とどんどん Go から離れていったので手軽な Lambda で書いたのが今ココというところ。

Goならわかるシステムプログラミング

Goならわかるシステムプログラミング

1年以上前からやるやると言ってたけど、さっさとやればよかった。

「ただいま」と「いってらっしゃい」を学習リモコン sRemo-R で Alexa に最適化する

kheiakiyama.hateblo.jp

今や旧機種の sRemo-R を1ヶ月前に購入しましたが、ようやく Alexa 連携を設定しました。

sRemo-R を接続可能にするための設定

新機種の sRemo-R2 もそうですが、sRemo-R に Alexa や ifttt と連携するためには設置場所(僕の場合は自宅) に外部からアクセスできる必要があります。
他の学習リモコンと違う点として、ルータのポート開放を行う必要があります。

sremosup.socinno.com

デフォルトでは 777 ポートを開放します。

ポート開放のときは sRemo-R が使用する IP アドレスを開放する必要がありますが、初期設定を雑に行っている場合は自動割当になっているかもしれません。
その場合はIPアドレス設定をやり直します。

sremosup.socinno.com

無事完了したらそのIPアドレスをポート開放しましょう。

Alexa の設定

Alexa の設定は検索すると腐るほどガジェット記事がヒットしますが、公式の手順を見るのが早いです。

Amazon.co.jp ヘルプ: スマートホーム製品の定型アクションを作成する

できたこと

kheiakiyama.hateblo.jp

上記事で書きましたが、FireTV のオンオフを Alexa から切り替えできるようにしていました。
これに加え、 sRemo-R がエアコンと連携しました。

「ただいま」で FireTV をオン、エアコンをオン
「いってきます」で FireTV をオフ、エアコンをオフ
できるようになりました。
就寝中はエアコンつけっぱなしにしているため、
「おはよう」で FireTV をオン
「おやすみ」で FireTV をオフ
という状態です。

ときどき朝の発話が寝ぼけているために「おはよ」と認識され、デフォルトの朝の挨拶に返答される場合があります。
ここがコンテキストで設定できるようになると嬉しいなというところです。

AWS IoT Button を買ったのでトイレ IoT に使えそうなバックエンド書いた

まえがき

気になっていた AWS IoT エンタープライズボタンを購入しました。

届くまでの間、何に使えそうか考えてましたが勤め先のトイレ IoT で使ってみたいと思いバックエンドのプログラムを書きました。

できたもの

github.com

S3 上に以下のような CSV のメトリックスが保存されるのが iot-button-metrics の最終成果物です。

"2018/07/28 12:12:30",0
"2018/07/28 12:13:29",0
"2018/07/28 12:14:30",1
"2018/07/28 12:15:30",1
"2018/07/28 12:16:30",1
"2018/07/28 12:17:29",1
"2018/07/28 12:18:30",1
"2018/07/28 12:19:30",0
"2018/07/28 12:20:30",0
...

iot-button-metrics ではAWS IoT エンタープライズボタンをトイレに設置し、個室入室者が入室時にボタンを押すことを想定しています。
ボタンを押してから5分間は入室している想定でメトリックを保存します。
(この300秒という時間は適切な時間がわからないので調整の余地があります)

複数ボタンはまだ対応してませんが、そのうち対応するでしょう。
(2018/07/29 01:44 追記: 対応しました)

アーキテクチャ

f:id:khei-fuji:20180728221939p:plain

AWS IoT エンタープライズボタンを押したときに Lambda を呼び出すことができます。
ボタンからトリガーされる Lambda Function では単にボタンを押された日時が保存されるのみです。
毎分トリガーされる Lambda Function ではさきの日時を加味してメトリックを保存します。

メトリックを保存するまでが役割で、これをどう可視化するかまではカバーしていません。

あとがき

Amazon - AWS IoT エンタープライズボタン
説明に "約2,000 回クリックできます" とあるため、1日40回利用されるとすれば50日程度、週末を考慮しても2ヶ月程度しか保たないということになります。
地味にコストがかかりますね。。

このコストがクリアされる前提ですが、勤め先で無事導入できた場合は Power BI が得意な同僚がいるため、可視化の部分を託したいところです。


なぜかボタンの Amazon アフィリエイト貼れないのでトイレっぽいもの置いておきます。