Quantcast
Browsing Latest Articles All 26 Live
Mark channel Not-Safe-For-Work? (0 votes)
Are you the publisher? or about this channel.
No ratings yet.
Articles:

heroku 初級編 - GitHub から deploy してみよう -

みなさま、こんにちは。たくさんの仕事に囲まれて泣きながら過ごしていますが、今月は Perfumeのライブが約4日に一度程度の頻度で訪れるために泣いてる場合ではありません、しょっさんです。

さて、Advent Calendar 2018 始まりましたね。初日からすっかり遅刻気味ですが、今年もHerokuどうもありがとうございました。そして、これからもどうぞよろしくお願い申し上げます。

GitHubからHerokuへ deployしてみよう

Heroku 初心者向けのガイダンスには、ローカルのgitリポジトリから、heroku create して git push heroku master することが一般的です。実際にこの方法を使うのは、ちょろっと試すときがほとんどで、それ以外の場合ではGitHubと連携して、Heroku Flowを使っていただくようにおすすめしています。

おすすめしている程度には、GitHub連携は使っていただきたいと考えています。ですから、今回は初級編と題して、Heroku Flow を使わずとも GitHub から直接 Heroku へ deploy してみる手順について紹介します。Heroku の全てに通じることですが、なにをするにしても、ひじょーにカンタンです。

前提条件

大したことでもないけれども、どうしても必須な条件があります。

  • Heroku アカウントを持っている
  • GitHub アカウントを持っている

当たり前でした。ごめんなさい。でも、これだけあれば GitHubからカンタンに Herokuへ deployする手順を学習できます。

なお、これから実行・実現することはすべて「無料」で実施可能です。お財布にも優しい!!

準備1: Heroku用のソースコードを準備しよう

「Heroku で動かすためのアプリケーションを書いてください」では、敷居が高すぎるので、Heroku が準備しているデモソースコードを元にして試してみます。

Herokuでは、Githubリポジトリ にて対応している言語のサンプルソースコードが公開されています。今回は、自分がたまたま Node.jsの連載を持っているからという理由だけで、Node.js のサンプルソースコードを選択します。他の言語で試してみたい方は、もちろんそちらでも構いません。

まず https://github.com/heroku/node-js-getting-started へ移動しましょう。そしておもむろに右上の「Fork」ボタンをクリックして自分のリポジトリへコピーしましょう。

Fork_github.png

複数の組織を持っている場合は、こちらのように選択画面が出てくると思いますが、そのあたりはお任せします。

Screen Shot 2018-12-01 at 10.03.27.png

これで、deploy 用のソースコードの準備は完了です。

準備2: Heroku アプリケーションを作成しよう

Heroku 上でアプリケーションを動かすためには、Heroku アプリケーションが必要です。感覚としては、空の箱を一つ準備して、ソースコードをそこへ放り込むと、Webアプリケーションが動く、というイメージです。まず、この空の箱を準備します。

Heroku へログインして、Heroku ダッシュボード画面へ入ります。アプリケーション一覧の画面になりますので、ここで右上の「New」をクリックしてプルダウンメニューからCreate new appをクリックします。

Create_new_app_Heroku.png

Heroku アプリケーションを作成する画面になります、App name は Herokuアプリケーションへアクセスするときの URLの一部になります。ここで指定した App name が、https://<App name>.herokuapp.com としてアクセスできるようになります。ドメイン名の一分になるので、世界中で唯一の名前であることが必須となります。入力しながら、使えるかどうかお試しください。面倒な場合は空欄にしておけば、自動的にアプリケーション名が割り振られます。

リージョンは、「United States」と「Europe」が選択できます。Private Spaceでなければ、この2つからしか選択できないので、標準のままの「United States」でどうぞ。

アプリケーション名に問題がなければ、「Create app」ボタンをクリックします。

Create_app_Heroku.png

ほんの数秒で Heroku app が作成され、対象のアプリケーションのダッシュボードへ移ります。

ここまでで、準備完了です。

GitHub と連携しよう。

Heroku アプリケーションを作成した後、ダッシュボードの「Deploy」タブにいるのではないでしょうか。もし、違うタブにいるようであれば「Deploy」へクリックして移動してください。

Heroku_Deploy.png

ちょうど、この下部に Deployment method という欄があり、現在は Heroku Git になっているように見えますね。Heroku app作成直後は、Heroku app一つに割り当てられる Gitリポジトリへソースコードをpushすることでアプリケーションを deployできる状態となっています。いわゆる、git push heroku master で deployする時の状態です。

ここでおもむろに、愛嬌あるGitHubアイコンの「GitHub」をクリックしてみましょう。しばらくすると、次の画面のようなConnect to GitHub欄が出てきます。

Connecto_to_GitHub.png

次にやることはわかりますね、そうです「Connect to GitHub」ボタンをクリックするのです。GitHubでの認可画面が出てきますので、「Authorize heroku」をしてみましょう。

Authorize_GitHub.png

ただしく認可されれば、検索画面へと切り替わります。さきほど自分のリポジトリへForkした「node-js-getting-started」をrepo-nameへ入力し「Search」してみましょう。次の通り、検索欄の下に「node-js-getting-started」のリポジトリが表示されるでしょう。

search_repo.png

「Connect」ボタンをクリックするのです! どうなりますか? 次のように Automatic deploysManual deploy の欄ができあがれば成功です。

connected_github.png

手動 deployを実行しよう!!

Automatic deploys が気になりところですが、一旦忘れて、先程Forkしてきたプログラムをdeployしてみましょう。手動でもdeployができるんです。「今の状況でdeployしたーい」という甘い誘惑に応えます。

deployしたい元となるgitのブランチはどれかわかりますね?今回は迷わずmasterブランチで構いません。Manual deploy欄の「Choose a branch to deploy」の項目がmasterになっていることを確認しつつ、「Deploy Branch」ボタンをクリックしましょう。このように、Buildプロセスが開始されます。

building.png

ほんの数秒程度で Build&deploy は完了します。異常なくDeployできれば、次のように「Your app was successfully deployed.」と表示され、「これを押せ」と言わんばかりに「View」ボタンが現れます。そうです、押してやりましょうとも「View」ボタンを。

deployed.png

次のような画面が表示されれば Deploy成功です。先程 Forkしてきたばかりのアプリケーションが、このように全世界へ公開されました!!

Node_on_Heroku.png

自動Deployって?

スルーしたAutomatic deploys欄内の「Enable Automatic Deploys」をオンにするとどうなるのでしょうか?

ここも、手動deploy同様、ブランチを選択できます。GitHubの対象のブランチにソースコードが変更され、コミットされたら、自動的にHerokuへDeployする、という機能です。また、もう一つ気になるチェックがあることに気がついたでしょうか?そうです Wait for CI to pass before deploy です。これをチェックすると、Deployの前に Heroku CIが動き、自動的にソースコード内で設定されたユニットテストが実行されます。そのテストコードがすべてパスしたら、Deployするフローとなります。

Enabled_automatic_deploys.png

このように、自動的にテストとも連携して、Deployを実行できる。それもこんなカンタンに。

まとめ

GitHubと連携して HerokuへプログラムをDeployすることはカンタにできちゃいます。次のたったの4手順です。

  1. ソースコードを準備する
  2. Heroku app を作成する
  3. GitHubと連携する
  4. Deploy!

また、GitHubのブランチと連動して、自動的にテストコードを実行して、うまくいったら自動的にDeployすることもできます。他の PaaS でここまでカンタンにできます?

そう、Heroku ならできます。みなさんもカンタンに楽をしてプログラムを公開していきましょう!

Herokuにほしい機能のはなし

External article

BitBucketのパイプラインを使ってHerokuにJavaをPushした話

初投稿です。文章が読みづらいかもしれませんが宜しくお願い致します。

モチベーション

せっかくだからGitにpushしたら自動でHerokuにデプロイするようにしたい。
でもGitHubはマイクロソフトに買収された課金しないとpublicだから見られたくないもんも見られちゃう。
BitBucketはprivateだからその辺うまくいきそう。

前提

  • STS使ってSpringBootでプロジェクト作ります(当方eclipseにSTSプラグインを入れております)
  • bitbucketのアカウント作成を済ませておきます
  • Herokuのアカウント作成を済ませておきます
  • HerokuCLI導入済です
  • Gitが使えます(eclipseのGitプラグインでもOK)

さっそくやってみる

まずはHerokuの準備

HerokuCLIからでもWebアプリ管理画面上からでもよいので任意のプロジェクトを作成
HerokuのAPIキーを控えておく(Account Settings画面から確認できる)

続いてBitBucketのリポジトリ作成

リポジトリクリエイト→GitCloneでURLを控えておく

Javaのプロジェクト作成

右クリック→新規→新規Sprinスタータープロジェクトで作成
以後作ったプロジェクト名はSampleProjectとして、各ファイル内の変数名もSampleProjectとしていますが、
そこは自分のプロジェクト名に読み替えてください。

SampleProject
├─src/main/java
├─src/main/resources
│ ├─application.properties
├─mvnw
├─mvnw.cmd
└─pom.xml

上記のようなパッケージ構成になっていればOK
ここからBitBucketとHeroku特有ファイル作成&修正

system.properties(新設)
java.runtime.version=1.8
Procfile(新設)
web: java -jar target/SampleProject-0.0.1jar --server.port=${PORT}
pom.xml(修正)
<artifactId>SampleProject</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>

pom.xmlのPackagingをjarに修正
pom.xmlのartifactId&version名がProcfileと同様になっていることを確認

application.properties(修正)
下記記載を追加

server.port=${PORT:5000}
bitbucket-pipelines.yml(新設)
# This is a sample build configuration for Java (Maven).
# Check our guides at https://confluence.atlassian.com/x/zd-5Mw for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: maven:3.3.9

pipelines:
  default:
    - step:
        caches:
          - maven
        script: # Modify the commands below to build your repository.
          #- mvn -B verify # -B batch mode makes Maven less verbose
          - git push https://heroku:"HerokuのAPIキー"@git.heroku.com/"Herokuのプロジェクト名".git HEAD

それぞれのファイルの説明

system.properties

Heroku側でmavenプロジェクトをビルド後実行するために必要な設定ファイル

Procfile

Heroku側でプロジェクトを実行するために必要なファイル。実行コマンドを記載
因みに、mavenプロジェクトではmvn buildを実行するとプロジェクト直下のtargetフォルダ内に、ビルド結果ファイル(今回はjar)を格納する。これを実行する指定をしている

pom.xml

mvn buildのゴールをjarに変更(デフォルトはwarだった気が)

application.properties

heroku側のサーバーポートは5000らしいのでこのように記載(公式に書いてある通り)

bitbucket-pipelines.yml

bitbucketに備わっているパイプライン機能を利用。
bitbucketのmasterブランチにプッシュされると、自動でyamlに記載の処理を実行する
ここでは、今回はjavaをmaven管理しているので、
 ①冒頭でmavenプロジェクトを宣言
 ②herokuのプロジェクトブランチにpush
している。
なおherokuにpushされると、プロジェクトの言語、設定ファイル等を自動判別し勝手にビルドしてくれる。

最終的なフォルダ構成
(この構成じゃないとbitbucketさんやherokuさんが動いてくれないので要確認)

SampleProject
├─src/main/java
├─src/main/resources
│ ├─application.properties
├─bitbucket-pipelines.yml
├─mvnw
├─mvnw.cmd
├─pom.xml
├─Procfile
├─pom.xml
└─system.properties

最後にbitbucketにpush

bitbucketにプッシュすると、
①bitbukcetパイプラインが起動
②bitbukcetからheroku側のgitリポジトリにpush
③herokuがmavenプロジェクトと自動判別しmaven buildを実行
④targetフォルダ直下のjarをjavaコマンドで起動
の流れでherokuに配備されます。
pushしたらbitbucketのパイプライン画面のログや、Herokuのlogを確認し、各種コマンドがうまくいっていることを確かめましょう。うまくいったら完了です。

一度パイプラインを作れば、これからはBitBucektにpushするたび自動でherokuに配備されます。
終わりです。

オープンソースの営業支援システム「FreeSFA」をHeroku上で動かす手順

はじめに

先日、自社用に開発した営業支援システム「FreeSFA」を、オープンソースとして公開しました。
営業支援システム(SFA : Sales Force Automation)とは営業職の生産性を上げ、効率化を目指すシステムのことです。
オープンソースのSFAやCRM(顧客管理システム)はFreeSFAのほかにもいくつか存在しますが、PythonとDjangoで書かれたものは珍しいのではないかと思います。

ランディングページ
https://free-sfa.tk/

ソースコード
https://github.com/sikkimtemi/FreeSFA

開発経緯
https://qiita.com/sikkim/items/365cb1211a3b8ca7b410

image.png

FreeSFAは外回りを行う営業メンバーのためにつくりました。弊社の営業職にヒアリングした結果をもとに、様々な営業活動の中でも特に訪問と架電を効率化することを目標にして設計しています。

この記事ではHerokuとGCPを使ってFreeSFAの動作環境を構築する手順を説明します。
手順にしたがって作業すれば、下記のデモサイトと同様のWEBアプリを自分専用に構築することができます。

デモサイト
https://free-sfa-demo.herokuapp.com/

HerokuとGCPには無料枠があるので、規模によっては無料で営業支援システムを運用することも可能です。

なお、この記事の内容やFreeSFAの使用により問題が起こったとしても、保証はいたしませんので、予めご了承ください。

前提

FreeSFAはPython3とDjango2.0で開発されています。
これらの知識がなくてもFreeSFAを動かすことは可能ですが、カスタマイズをしたい場合はプログラミングする必要があります。
今のところ弊社ではFreeSFAのカスタマイズやサポートは行っておりません。

準備するもの

  • Herokuアカウント
  • Googleアカウント
  • 適当なメールアカウント
  • Gitを実行できる環境
  • Heroku CLI
  • Google Cloud Platformアカウント(要クレジットカード)

上から3つまでは必須です。
Googleアカウントとメールアカウントの取得方法は省略します。
メールはGmailでも問題ありません。

FreeSFAを動かすだけならGitの実行環境とHeroku CLIは不要です。
カスタマイズをしたい場合やプログラミングの勉強をしたい場合は準備してください。

Google Cloud Platform(GCP)のアカウントはソーシャルログインと地図の表示、および住所から緯度経度を取得するのに利用します。GCPのアカウントがなくても一応FreeSFAを動かすことは可能ですが、「近くの顧客を探す」という目玉機能が利用できなくなるので、ぜひGCPのアカウントもご用意ください。

Herokuアカウントの準備

HerokuはPaaS(Platform as a Service)の一種で、様々なWebアプリケーションを比較的簡単にクラウド上で動かすことができます。
無料枠が充実しているので、小規模なアプリケーションなら無料で運用することも可能です。
アカウントがない場合は以下のURLにアクセスして新規登録してください。

https://jp.heroku.com/

以前はクレジットカードの登録が必要でしたが、現在はクレジットカードなしでもアカウントを作れるようです。

アカウントを作成してログインすると下図のような画面になるはずです。

image.png

ここまでできたら、以下の選択肢の中からご自分にあったものを選んでください。

  • カスタマイズしなくていいので、とにかくFreeSFAを急いで動かしたい。
  • 時間をかけてソースコードのカスタマイズやプログラミングの勉強をしたい。

急いで動かしたい場合は途中をスキップして「Herokuボタンによるデプロイ」まで進んでください。
カスタマイズや勉強をしたい場合は、このまま「Gitを実行できる環境の準備」へ進んでください。

Gitを実行できる環境の準備

Windowsの場合は下記のリンクから「Git for Windows」か「Sourcetree」をダウンロードしてインストールしてください。
gitコマンドが使えれば別の方法でも構いません。

Macの場合はHomebrewで入れるのがおすすめです。
下記の記事を参考にしてみてください。
Mac版のSourcetreeでもOKです。

https://qiita.com/furusin_oriver/items/974a7b7fb8c56ad88d6e

Linuxは最初からgitコマンドが使えるはずです。
もし入っていなかったらapt-getyumでインストールしてください。

コマンドラインやターミナルで下記のように入力し、バージョンが表示されていればOKです。
バージョンが少々違っても問題ありません。

$ git --version
git version 2.17.2 (Apple Git-113)

Heroku CLIの準備

下記のURLを参考にしてHeroku CLIをインストールしてください。

https://devcenter.heroku.com/articles/heroku-cli

コマンドプロンプトやターミナルから下記のように入力して、バージョンが表示されていればOKです。
バージョンが少々違っても問題ありません。

$ heroku --version
heroku/7.18.3 darwin-x64 node-v10.12.0

FreeSFAをHerokuへデプロイする

GitHubからソースコードを取得

作業用のフォルダを準備して、コマンドプロンプトやターミナルを開き、cdコマンドで作業用のフォルダへ移動してください。
作業用フォルダに入ったら、以下のコマンドを入力してください。

$ git clone https://github.com/sikkimtemi/FreeSFA.git
$ cd FreeSFA

中身はこんな構造になっています。
とりあえず動かすだけならあまり気にする必要はありません。

FreeSFA
├── IISE
├── register
│   ├── migrations
│   ├── static
│   │   └── register
│   │       ├── css
│   │       ├── img
│   │       ├── js
│   │       └── vendors
│   │           ├── @coreui
│   │           │   ├── coreui
│   │           │   │   └── js
│   │           │   ├── coreui-plugin-chartjs-custom-tooltips
│   │           │   │   └── js
│   │           │   └── icons
│   │           │       ├── css
│   │           │       └── fonts
│   │           ├── bootstrap
│   │           │   └── js
│   │           ├── chart.js
│   │           │   └── js
│   │           ├── flag-icon-css
│   │           │   ├── css
│   │           │   └── flags
│   │           │       ├── 1x1
│   │           │       └── 4x3
│   │           ├── font-awesome
│   │           │   ├── css
│   │           │   └── fonts
│   │           ├── jquery
│   │           │   └── js
│   │           ├── pace-progress
│   │           │   ├── css
│   │           │   └── js
│   │           ├── perfect-scrollbar
│   │           │   └── js
│   │           ├── popper.js
│   │           │   └── js
│   │           └── simple-line-icons
│   │               ├── css
│   │               └── fonts
│   └── templates
│       └── register
│           └── mail_template
│               ├── create
│               ├── invite
│               ├── join_workspace
│               └── reset
├── sfa
│   ├── migrations
│   ├── static
│   │   └── sfa
│   │       ├── css
│   │       ├── csv
│   │       ├── img
│   │       └── js
│   ├── templates
│   │   └── sfa
│   ├── templatetags
│   └── tests
└── socials
    └── migrations

Heroku CLIでHerokuにログイン

以下のコマンドを入力し、Herokuのアカウント(メールアドレス)とパスワードを用いてログインしてください。

$ heroku login

Herokuアプリの作成

アプリケーション名を適当に決めてから、以下のコマンドを入力してください。
このコマンドはFreeSFAフォルダの中で実行する必要があるので注意してください。

$ heroku create アプリケーション名

Herokuのダッシュボードを開くとHerokuアプリができていることを確認できます。
アプリケーション名はheroku createコマンドで入力した名前になっているはずです。

image.png

環境変数の設定

作ったばかりのアプリケーションはまだ空っぽの状態です。
ここにFreeSFAのソースをアップロードして、動くようにする必要があります。
ただし事前にいくつかの値を環境変数に設定しておく必要があります。

環境変数 説明
SECRET_KEY Django内部で使用する秘密鍵です。十分長い値を設定しましょう。WEB上でキーを生成してくれるサービスもあります。 https://djecrety.ir/
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY Googleのソーシャル認証で用います。取得方法は後述します。
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET Googleのソーシャル認証で用います。取得方法は後述します。
GOOGLE_RECAPTCHA_SITE_KEY 「私はロボットではありません」を表示して、アカウント追加を制限するためのキーです。取得方法は後述します。
GOOGLE_RECAPTCHA_SECRET_KEY 「私はロボットではありません」を表示して、アカウント追加を制限するための秘密鍵です。取得方法は後述します。
EMAIL_HOST メール(SMTP)サーバーのホスト名を設定します。 Gmailを使う場合はsmtp.gmail.comを設定してください。
EMAIL_PORT メールサーバーのポート番号を設定します。通常は25か465です。Gmailを使う場合は465を設定してください。
EMAIL_HOST_USER メールサーバーのユーザーIDを設定します。
EMAIL_HOST_PASSWORD メールサーバーのパスワードを設定します。
EMAIL_USE_SSL メールサーバーでSSLを使用するかどうかを設定します。TrueもしくはFalseを入力してください。Gmailを使う場合はTrueを設定してください。

メールサーバーにGmailを利用する場合は、下記URLを参考に「安全性の低いアプリからのアカウントへのアクセスを許可」も実施しておいてください。

https://support.google.com/accounts/answer/6010255

環境変数はheroku config:addコマンドで設定することができます。
例えばSECRET_KEY94*dg1^h)qdl$h#dyd4&-4v5x6()5(4c(#bi+7$p=cnry2)ul+という値を設定したい場合は次のように入力します。

$ heroku config:add SECRET_KEY="94*dg1^h)qdl$h#dyd4&-4v5x6()5(4c(#bi+7$p=cnry2)ul+"

SECRET_KEYは文字通り秘密にする必要があるので、この例をそのままコピペで実行しないようご注意ください。
下記のように秘密鍵をWEB上で生成してくれるサービスも存在します。

https://djecrety.ir/

上の表にある環境変数はすべて設定してください。
Google関連の値の取得方法は後述しますので、とりあえず空文字「""」を設定しておいてください。

環境変数はHerokuのページからでも設定することができます。
image.png

Reveal Config Varsをクリックすると画面が下図のように変わり、環境変数の追加・編集・削除ができるようになります。
image.png

Herokuへデプロイする

環境変数を設定したらいったんデプロイしてみましょう。
デプロイは以下のコマンドで行います。

$ git push heroku master

いろいろとログが出力されますが、最後が以下のような感じで終わっていればOKです。
通常は1分以内に終わるはずです。

remote: -----> Compressing...
remote:        Done: 73.6M
remote: -----> Launching...
remote:        Released v18
remote:        https://free-sfa-demo.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/free-sfa-demo.git
 * [new branch]      master -> master

マイグレート

デプロイは終わりましたが、まだデータベースの準備ができていません。
データベースを使えるようにする作業をマイグレートといいます。
以下のコマンドを実行してください。

$ heroku run python manage.py migrate

エラーが出ていなければOKです。

Herokuボタンによるデプロイ

実はここまでの作業は下のHerokuボタンを押すだけでできます。

Deploy

ボタンを押すと下図のような画面が表示されます。
アプリ名を入力して「Deploy app」をクリックすると自動でマイグレートまで実施されます。完了するまで数分かかります。
環境変数も自動で作られますが、SECRET_KEY以外の値はすべてダミーの値になっているので、正しい値に設定し直す必要があります。
「環境変数の設定」に示した表と、後述する取得方法を参考にして、ダミーの値を置き換えてください。

image.png

管理用アカウントの登録

FreeSFAはDjangoというフレームワークを使って作られていますが、Djangoには標準で管理機能が用意されています。
この管理機能を使うためのアカウントをまず登録します。
Heroku CLIをインストールしている場合は以下のコマンドを実行し、画面の指示に従ってメールアドレスとパスワードを登録してください。

$ heroku run python manage.py createsuperuser

Heroku CLIをインストールしていない場合はHerokuのダッシュボードで右上の「more」をクリックし「Run console」を選択してください。

image.png

下図のようなコンソールが開くので、python manage.py createsuperuserと入力して「Run」をクリックしてください。

image.png

動作確認

ここまでできたら以下のコマンドを実行してみてください。
Heroku CLIをインストールしていない場合はHerokuダッシュボード右上の「Open app」ボタンを押してください。

$ heroku open

問題なく実行できていれば自動的にブラウザが起動し、下図のような画面が表示されるはずです。
もしエラーになったらここまでの手順でどこか間違えているはずですので、再度確認してみましょう。

image.png

先ほど登録した管理用アカウントでログインしてみてください。

image.png

「管理サイト」をクリックするとDjangoの管理サイトが表示されます。

image.png

FreeSFAの運用で管理サイトを使うことはあまりありませんが、間違って消してしまった顧客情報を復活させたい場合やレコードの物理削除をしたい場合などは役に立つかもしれません。

Google Cloud Platformアカウントの準備

Google Cloud Platform(GCP)はGoogleが提供するクラウドコンピューティングのサービス群の総称です。
GCPは有料サービスのため、アカウントを取得するにはクレジットカードの登録が必要です。
GCPのアカウントを取得するには下記のURLにアクセスし、Googleアカウントでログインします。

https://console.cloud.google.com/?hl=ja

下図のような画面が表示されたら利用規約に同意して「承諾」をクリックします。

image.png

次の画面の上部に以下のように表示されたら「ACTIVATE」をクリックしてください。

image.png

すると次のような画面になるので、必要事項を入力して進んでください。

image.png

ステップ2で住所とクレジットカードを登録すればGCPアカウントの準備は完了です。

環境変数に設定する値の取得方法

reCAPTCHA

「私はロボットではありません」をチェックさせるアレです。最近バージョン3が出てチェックすら不要になりましたが、FreeSFAはまだ対応していないのでバージョン2のAPIキーを取得してください。

reCAPTCHAはGoogleアカウントがあれば無料で取得することができます。
以下のURLにアクセスし、右上の「My reCAPTCHA」ボタンをクリックしてください。

https://www.google.com/recaptcha

下図のような登録画面が表示されたら必要事項を入力して登録してください。
Domainsには自分のHerokuアプリのドメインを入力しましょう。
image.png

登録すると次の画面でSite keyとSecret keyが表示されます。それぞれコピーしてHerokuの環境変数に設定してください。

image.png

正常に設定できるとFreeSFAのユーザー登録画面にreCAPTCHAが表示され、新規登録できるようになります。

image.png

Googleアカウントでログインを可能にする

下記URLからGoogle Cloud Platformにアクセスし、「プロジェクトの選択」から新規プロジェクトを作成してください。
すでにプロジェクトがある方はそちらを利用してもOKです。

https://console.cloud.google.com/?hl=ja

image.png

プロジェクトを作成もしくは選択したら、APIとサービスのダッシュボードをクリックしてください。

image.png

APIとサービスのダッシュボードを開いたら、「APIとサービスの有効化」をクリックしてください。

image.png

検索欄に「google+」と入力して「Google+ API」を選択してください。
GoogleのソーシャルログインはGoogle+で行います。(もうすぐ廃止されるサービスなのに大丈夫なんでしょうか?)
image.png

Google+ APIを選択したら「有効にする」をクリックしてください。
image.png

続いて「認証情報の作成」をクリックしてください。
image.png

「プロジェクトへの認証情報の追加」で下記のように入力し、「必要な認証情報」をクリックしてください。
image.png

適当な名前を入力したら「OAuthクライアントIDを作成」をクリックしてください。
image.png

「次へ」をクリックしてください。
image.png

「完了」をクリックしてください。
image.png

認証情報の名前をクリックしてください。
image.png

クライアントIDとクライアントシークレットが表示されます。それぞれコピーして、Herokuの環境変数SOCIAL_AUTH_GOOGLE_OAUTH2_KEYSOCIAL_AUTH_GOOGLE_OAUTH2_SECRETに設定してください。
image.png

[OAuth同意画面」を選択してください。
image.png

下の方に承認済みドメインを登録する欄があるので、Herokuアプリのドメインを設定してください。
image.png

認証情報に戻って、下図を参考にして「承認済みのリダイレクトURI」にHerokuアプリのURL + /social/complete/google-oauth2を入力し、保存をクリックしてください。

image.png

ここまで正しく設定できていれば、FreeSFAのログイン画面で「Googleアカウントで登録」と「Googleアカウントでログイン」ができるようになるはずです。

image.png

住所から緯度経度を取得できるようにする

APIとサービスのダッシュボードで「ライブラリ」をクリックしてください。
image.png

検索欄に「geocode」と入力し、「Geocoding API」を選択してください。

image.png

APIを有効にしてください。
image.png

APIとサービスの認証情報で「認証情報を作成」をクリックし「APIキー」を選択してください。

image.png

キーの制限は下図を参考にしてください。
「アプリケーションの制限」はなし、APIの制限は「Geocoding API」のみです。

image.png

Geocoding APIは「HTTPリファラー」で制限することができません。
IPアドレスで制限することは可能ですが、HerokuはIPアドレスを固定できないため、やむを得ず制限なしで運用しています。良い方法をご存知の方がいらっしゃいましたらコメント欄で教えてください。

image.png

GeocodingのAPIキーはHerokuの環境変数ではなく、ワークスペースごとに作られるDB上に格納されます。
ワークスペースのオーナー権限でログインして、右上のアカウント名をクリックし、「環境設定」をクリックしてください。
APIキーの設定・確認はワークスペースのオーナーしかできないようにしています。

環境設定の該当箇所にAPIキーを設定して保存すると、住所から緯度経度を取得できるようになります。

顧客情報を新規作成し、緯度経度を入力せずに住所と必須項目を入力して保存してみてください。
緯度経度が自動的に入力されていればAPIは正しく設定されています。

地図を動的に表示できるようにする

APIとサービスのダッシュボードで「ライブラリ」をクリックしてください。
image.png

検索欄に「maps」と入力し、「Maps Embed API」と「Maps Javascript API」をそれぞれ有効にしてください。
image.png

「認証情報を作成」からAPIキーを新規作成し、キーの制限でAPIの制限とアプリケーションの制限を行ってください。
APIの制限は「Maps Embed API」と「Maps JavaScript API」を設定してください。
FreeSFAの設定画面では「Google Maps JavaScript API用のキー」と表現していますが、実際にはひとつのキーに2つのAPIが含まれているのでご注意ください。
image.png

アプリケーションの制限にはHTTPリファラーを選択し、自分のHerokuアプリのURLを設定してください。
これでこのAPIキーは自分のHerokuアプリから呼び出された場合しか使えなくなります。
image.png

「Maps Embed API」は顧客情報詳細画面で使用しています。
image.png

「Maps Javascript API」は「訪問予定と実績」画面など、複数の顧客を地図上にプロットする画面で使用しています。
image.png

Google Maps APIの料金について

Google Maps APIの利用料は従量課金制ですが、月に200ドル分までは無料で利用できます。

詳しくは下記URLを参照してください。
https://cloud.google.com/maps-platform/pricing/sheet/?hl=ja

弊社では今のところ無料で運用できています。

デモサイト

上でも書きましたが、以上の手順をすべて実施したデモサイトを作成しました。

https://free-sfa-demo.herokuapp.com/

デモサイトを試す場合は新規ユーザー登録からお願いします。
デモサイトのデータは毎朝4時にリセットされます。

おまけ

Herokuの自動スリープ回避

FreeプランのHerokuは30分間アクセスがないと自動でスリープしてしまいます。
いったんスリープすると、次にアクセスしたときはインスタンスの起動から始めるのでとても時間がかかってしまいます。
そこで自動スリープを回避する方法がいろいろ考案されています。
弊社の本番環境とデモサイトは下記の記事を参考にして自動スリープを回避しています。

https://qiita.com/uma0317/items/59af206f45b3a698d911

データベースのバックアップとリストア

Herokuのデータベースはherokuコマンドでバックアップとリストアすることができます。
弊社では下記の記事を参考にして運用しています。

https://qiita.com/kimunny/items/c841bed5df73f0f93067

TypeScriptをHerokuにデプロイした時にハマったことをシェアします

External article

Herokuアプリのデータベースのカラム名を変えたくなったら

Webアプリが成長していくと、あー、このカラムの名前やっぱり別のにしておけばよかった。Railsのマイグレーションファイルで書くとrename_column(:articles, :text, :body)しなくちゃ、と思うこと、ありますよね。あ、そういえばカラム名が変わるとコードから参照してるところも編集しなくちゃ。article.textだったところをarticle.bodyに。

さて、カラム名はdb:migrateすれば変わるんだけど、コードの方は?そうそう、デプロイしてdynoが再起動したら変わる。その間にアプリにアクセスがあった場合はどうなるんだろう?

試してみました。例えば、こうなります:

ActionView::Template::Error (undefined method `body' for #<Article>)

コードはbodyカラムを参照してるんだけどデータベースにはtextカラムしかない。

この記事では、カラムの名前は変えなきゃいけないとして、このエラーをどうやれば避けられるか考えます。

この記事は、Heroku Advent Calendar 2018の12月6日の記事としてお送りします。昨日は tsukakei さんが TypeScriptをHerokuにデプロイした時にハマっていました。そうそう。アプリのビルドはコードのpush時に。トップディレクトリにpackage.jsonがあればgit push heroku masterされたコードをみてプラットフォームがよしなにビルドしてくれるはず!

Dynoのコードの更新とデータベースのマイグレーションは同期してくれない

Herokuでは、デプロイの時のコードの更新とマイグレーションは別の時に起こります。その間にもリクエストは届き、コードはデータベースへのアクセスを続けます。アプリケーションをメンテナンスモードにしてもいいんだけど、できれば避けたいですよね。

デプロイをしてからOne-off dynoでマイグレーションを走らせる場合には、しばらくの間、新しいバージョンのコードが古いスキーマのデータベースとやりとりをします。コードがpushされ、ビルドが終わるとdynoが再起動され新しいコードが走り始めます。One-off dynoからデータベースのマイグレーションが起きるのはそのあとです。

いっぽう、Release Phaseコマンドを利用する場合は、逆に、しばらくの間古いバージョンのコードが新しいスキーマのデータベースとやりとりをします。コードがpushされ、ビルドが終わると、Release Phaseコマンドが走りデータベースのマイグレーションが起き、そのあとdynoが再起動され新しいコードが走り始めます。

デプロイ前後のコードとデータベースは互換に保つ

このように、コードのバージョンとデータベースのスキーマの更新は同期せず前後します。このような状況でも、データベースのスキーマを、変更前後どちらのコードとも互換なようにして進めることで、アプリケーションを稼働させつつデプロイを済ませることができます。

例えばarticlesテーブルのtextカラムをbodyカラムに変更する場合は、下記のように、まずbodyカラムを追加し、その後コードがbodyカラムを参照するようにしてから、最後にtextカラムを消去します。3段階のデプロイをすることになります。

(1) 新しいカラムをつくり既存のカラムと同期する

例えば下記のようなマイグレーションを作成してコードの変更なしにHerokuにデプロイし、マイグレーションのみ走らせます。bodyカラムを追加し、textカラムの内容をコピーします。textカラムを更新する旧版のコードはまだ走っている可能性があるので、textカラムに更新があった場合にはそれをbodyカラムにも反映するようにトリガを設定します。

このマイグレーションを追加しデプロイし、マイグレーションを走らせると、textカラムを参照しているコードからも、bodyカラムを参照しているコードからも、このデータベースとやりとりをできるようになります。

class AddBodyToArticles < ActiveRecord::Migration[5.2]
  def up
    add_column :articles, :body, :text
    execute <<_ADD_TRIGGER
UPDATE articles SET body = text;
CREATE OR REPLACE FUNCTION sync_to_body()
  RETURNS TRIGGER AS $$
  BEGIN
    IF ( TG_OP = 'UPDATE' AND NEW.text != OLD.text OR NEW.body IS NULL ) THEN
      NEW.body := NEW.text;
    END IF;
    RETURN NEW;
  END;
  $$ LANGUAGE plpgsql;

CREATE TRIGGER sync_to_body_trigger
  BEFORE INSERT OR UPDATE OF text ON articles
  FOR EACH ROW EXECUTE PROCEDURE sync_to_body();
_ADD_TRIGGER
  end

  def down
    execute <<_REMOVE_TRIGGER
DROP TRIGGER sync_to_body_trigger ON articles;
DROP FUNCTION sync_to_body();
UPDATE articles SET text = body;
_REMOVE_TRIGGER
    remove_column :articles, :body
  end
end

(2) コードが新しいカラムを参照するようにする

コード中でtextカラムを参照している部分を編集して、bodyカラムを参照するようにします。この変更をデプロイしdynoが再起動すると、textカラムへの参照はなくなります。

(3) 既存のカラムを削除する

下記のようなマイグレーションを作成してコードの変更なしにHerokuにデプロイし、マイグレーションのみ走らせます。これでtextカラムが削除されます。念のためrollbackもできるようにしてあります。

class DropTextFromArticles < ActiveRecord::Migration[5.2]
  def up
    execute <<_REMOVE_TRIGGER
DROP TRIGGER sync_to_body_trigger ON articles;
DROP FUNCTION sync_to_body();
_REMOVE_TRIGGER
    remove_column :articles, :text
  end

  def down
    add_column :articles, :text, :text
    execute <<_ADD_TRIGGER
CREATE OR REPLACE FUNCTION sync_to_body()
  RETURNS TRIGGER AS $$
  BEGIN
    IF ( TG_OP = 'UPDATE' AND NEW.text != OLD.text OR NEW.body IS NULL ) THEN
      NEW.body := NEW.text;
    END IF;
    RETURN NEW;
  END;
  $$ LANGUAGE plpgsql;

CREATE TRIGGER sync_to_body_trigger
  BEFORE INSERT OR UPDATE OF text ON articles
  FOR EACH ROW EXECUTE PROCEDURE sync_to_body();
_ADD_TRIGGER
  end
end

これでダウンタイムなしでカラム名を変更できました。

もっと詳しく!

Thoughts on Javaの記事「Update your Database Schema Without Downtime」などに、カラム名の変更以外の場合についても、詳しい解説があります。

この記事の内容の確認はzunda/rails-dbmigrate-testでおこないました。

落ち穂拾い

  • 筆者はRuby on RailsやPostgreSQLについては詳しくないです。ごめんなさい。上記のマイグレーションのコードなど、より良い書き方があればお知らせいただけるとうれしいです。
  • Gitでの多段リリースの表現方法を考えてたい。上記のようにコミットが複数になる場合、Tagを書きつつブランチでマイグレーションのテストを終えて、プロダクション用のブランチにtagをmergeしていくのが良いだろうか?
  • Private Spacesではコードの変更時に複数のweb dynoが新旧両方のバージョンで稼働する可能性があり、新しいバージョンのweb dynoからレスポンスをもらったクライアントが古いバージョンのweb dynoにアセットをもらいに行くと、404 Not Foundが返ってしまいます。新しいバージョンのアセットを先にリリースしておけば回避できるのですが、いい方法ないかな。

Pythonの可視化ライブラリDashで作ったグラフをherokuにあげて共有する

External article

開発環境としてのheroku

この記事は heroku Advent Calendar 2018 8日目の記事です。

開発環境としてのheroku

githubなどを使っているときに、実際の動作をレビューしようとするとローカルの開発環境にpullしたりして面倒ですよね

というわけでherokuで簡単にレビューできる環境を整えましょう

Heroku Review Apps

https://devcenter.heroku.com/articles/github-integration-review-apps

githubのプルリクエストの内容で自動的にアプリを立ち上げてくれる機能です

この機能を使用することでプルリクエストを送るだけでコードと動きのレビューができるようになります

環境変数なども開発環境のものに設定できるのでとても便利です

Heroku CI

https://devcenter.heroku.com/articles/heroku-ci

CIにおいてもherokuで完結できます
設定方法もapp.jsonに記述するだけなのでわかりやすく簡単です

{
  "environments": {
    "test": {
      "scripts": {
        "test": "phpunit"
      }
    }
  }
}

Docker

https://devcenter.heroku.com/articles/container-registry-and-runtime

Dockerイメージのデプロイも可能です
ローカル開発環境をそのままデプロイできるのも便利ですね

まとめ

レビューをするためだけでもherokuを利用することでとても便利になります
ぜひこれらの機能を利用して楽で管理しやすい環境を整えてください

heroku 中級編 - 1分で実現するCI/CDをHeroku Pipelinesで

Heroku Advent Calendar 2018 9日目。1年ぶりにTOEICを受験してきました。TOEICの所為にして、投稿が地味にちょっと遅れたことをなかったコトにしようとする、悪い大人の見本、しょっさんです。未だに、Google IMEが「しょっさん」を覚えてくれず「ショッさん」って変換するの、ほんとに憎いです。そろそろ覚えてください。

「できる」ということ

長いこと「エンジニア」人生を送ってくると、いろんなエンジニアがいます。技術力の高すぎる風光明媚なエンジニアや、志だけが高いだけのエンジニアの中に、お客様の要求に対して技術で猛攻撃する傾向のある人を見かけて、悲しい思いをすることがあります。技術は人や世界を助けることは多いのですが、技術だけで全ては片が付かないことや、どんなに論理が優れていても受け入れがたい倫理や感情論はどうしても存在します。そういったものも考慮できることが、優れたエンジニアリングスキルを持っている人と信じています。

さて、そんな中、ずっと昔からどうしても受け入れられない言葉があります。エンジニアの発する「できる」という言葉。01志向の中にあって、Yes/Noの答えを求められたときに、判断基準としてわかりやすいあの「できる」です。RFP(Request for Proposal)や仕様書などで定義される、要求機能・非機能に対して答える「できる」というあれです。この「できる」について、みなさまどのようにお考えでしょうか。わたしは、この「できる」という言葉を信用しないことにしています。崇高なエンジニアの場合は、「できます」と答えたあと「しかしながら( ^ω^)・・・」という自分に不利益な制約について正しく述べるか、質問をすれば正しく回答します。できる理由とできること(範囲)、実際には実現できないことや実現の困難さを正しく述べられることは、一流のエンジニアに重要な「説明責任(Accountability)」です。

なぜ、こんな話をするのかと言うと「できる/できない」は実は「Yes/No」という二軸ではなく、その間には広く深い闇が広がっている所為です。この広く深い闇をなかったコトにして「できる」というエンジニアの、いかに多いことか。自分も昔はそうであったこともありますが、お客様の要求する「できる」とひじょーーーーーーーーーーーーーに乖離した「できる」が世の中には多く存在します。わたしは、この期待値を遥かに下回った「できる」がひじょーーーーーーーーーーーーーーーーーーーに嫌いです。

少し深淵を探ってみましょう。「できる」はある程度、次の段階で示せます。

  1. すでに実装済み・実現されている技術であり、今すぐ使えるという意味の「できる」
  2. 標準で実装されているが、最初から使えるものでないが、ボタン一つで設定をオンにしたり、設定項目を1つ2つ設定すれば使えるという意味の「できる」
  3. オプション機能、またはある機能を使えるようにした上、ある程度の設定をすれば使えるという意味の「できる」
  4. 複数の機能や、複数のコンポーネント・オプション・仕組みを組み合わせることで使うことのできるという意味での「できる」
  5. 全く別の想定していなかったコンポーネント(ソフトウェアやハードウェアなど)を追加すると、実現可能性があるという意味での「できる」
  6. 開発すれば何でも「できる」

お客様の聞いてくる「できる」の期待値はだいたい1か2です。IT経験の長いお客様でも3までで、4からは「できる」の意味合いが別のことと期待しています。4からは「〜をすればできる(△)」という領域です。エンジニアの中では6まで含んで「できる」と答えるエンジニアがいるので、困ったものなのです。

これ、仕事ではなくとも、素人さんに「・・・・できる?」と云う期待値が1か2での質問に対して、4か5の状態のことを「できる」と返すエンジニアが散見されます。「できる」とはそういうことじゃないんです。「容易に実現することができる」かどうかなんです。素人は所詮素人さんなんです。「メール送りたければsendmail.cf書けばいいじゃん」って素人はもとより、最近のエンジニアに伝えても、それは「できない」なんです。今どきsendmailかよというツッコミを求めてるのではなく、これが一番伝わりやすそうな年齢層に向けて書いてるというだけです。

だからどうした。

世の中「カンタンにできます」ということを訴えているサービスはとてもたくさんあります。そして、本当にそれらが容易に実現される世の中にもなってきました。私としては、ITはそのように多くのものを容易に実現するための、良いパートナーであるべきであると心から願っています。「こうすればできる」と甘んじてその先に進まないのではなく、「よりカンタンに」「シンプルに」実現できること、そしてそれを実装していくことがエンジニアとして重要なことだと考えています。

複雑なことを組み合わせて実現できることは崇高で風光明媚なことですが、それを簡単に利用させることのできるようになることが、本来のエンジニアリングではないでしょうか。

余計な手間を使わずに、本当に必要なことに時間をかける。今後、日本は労働人口減少に従ってエンジニアの数も減少していきます。エンジニアこそ、より時間をかけずに、新しい使いやすいサービス実現のために時間を使うべきなのです。

だから、Heroku なんです(ようやくここまできた)

1分で実現するCI/CD環境

時間の重要性

前置きが多いと思われたかもしれませんが、残された人生も少ない私にとって「時間」はとても大切です。一番上の娘も成人し、そろそろ孫がという世代に近づいてきたということは、死期もそれだけ迫っているということです。というか、もういつ死んでもおかしくない年齢です。健康にいくら気を使っても、どうにもならないことが多く、どんなに鍛えても風邪をひくし、かんたんに重症化します。夜は早く寝たいし、少ない労働力で、多くの金銭を手にしたいわけです。まだまだ娘たちには金と手間がかかります。ホントお金をもっとください。

閑話休題。

さて、開発者にとって重要なコアコンピタンスはなんでしょうか。そです。開発することです。すぐれたソフトウェアを開発することです。そのソフトウェアを動かす環境については、微塵も時間を使いたくないはずです。本来は。aPaaS(Application Platform as a Services)やPaaSはそれらを改善してくれましたが、まだまだでした。ソフトウェアの動く環境はこれらが提供してくれましたが、開発していくための環境はまだまだこれからという部分があります。

カンタンに設定して使えるCI/CD

世がDevOpsNoOpsだと騒ぐより以前から、開発者のために素晴らしいプラットフォームを提供しようとがんばってきたのがHerokuプラットフォームです。元はと言えばRuby on RailsのためのPaaSでしたが、現在では8言語に対応したプラットフォームを提供しています。しかもそれのみならず、標準的な機能としてCI/CD(Continuous Integration/Continuous Deployment)をサポートするツールも提供していることがHerokuの特徴です。

DevOpsは文化・組織論をベースにしたプロセス進化論ですが、その中においてソフトウェアの開発を自動化し、生産性を向上させるCI/CDといった考え方も開発されました。背景にアジャイルの開発などもあったでしょう。迅速な開発を行うための様々な苦労から生み出されてきたことでしょう。CIは開発プロセスを自動化します。コードがコミットされれば、その時点でのソフトウェアをインテグレーション・ビルドし、テストまで行います。ソフトウェアが正しい状態で稼働することをいかにして保つかを根本理念として持っています。CDは、その状態を可視化します。実際に開発・テスト用の一時的な環境で、それらが動いていることを視認して確認することができます。

これらCI/CDは、インフラがクラウド化され、IT基盤が容易に廃棄して、新しい環境を作ることができるようになり、実現できるようになりました。様々なツールを組み合わせて実現できるようになりましたが、それでも複数のコンポーネントやサービスを組み合わせて実現せねばできないものでした。それは、コードバージョニングを司るツールと開発・テストを行う環境とそれらを管理するツール、実際に稼働するプラットフォームなどが分離していたことから、それらを組み合わせることが必要不可欠でした。

Herokuは、コードバージョニングこそGitHubにまかせていますが、それ以外のすべてをHerokuプロットフォームですべて実現することで、CI/CDを実装できる環境を「カンタンに」実現できることに成功しました

開発者の方々へHerokuを進める理由の大半が「カンタンに」多くのことを実現できるからです。覚えることが少なければ、トレーニングの時間も少なく、すぐにプロジェクトを立ち上げられます。実際の作業時間が少なければ、それだけプロジェクトの期間を削減できます。ソフトウェアの開発に多くの時間を割くことができます。

1分で実現するCI/CD

では実際に1分で環境を準備しましょう。慣れてないと、もう少し時間がかかるかもしれませんが、5分も必要としないでしょう。

前提条件

  1. Herokuアカウントを持っている
  2. GitHubアカウントを持っている
  3. GitHub上にCI/CDするためのソースコードツリーがある・またはこれから準備する

また、無料アカウントやクレジットカードで登録されているユーザの場合、Heroku CI(自動テスト)を利用すると月に$10かかります。Heroku Enterprise契約されているユーザの場合は、Heroku CIは追加の課金なくご利用いただけます。

設定する前に

有償だと幅が広がりますが、無料でも十分、それらの機能の恩恵を受けられます。作業内容は次の3つです。

  1. Heroku Pipelines を作成する
  2. 必要な環境を割り当てる
  3. 各機能をオンにする

今回設定するCI/CDシナリオは、次のとおりです。

  1. GitHub上でPR(Pull Request)されたら、そのPR環境をデプロイして利用可能にする
  2. GitHub上のソースコードが変更されたら自動的にテストを行う
  3. GitHub上のmasterブランチにソースコードがマージされたら、ステージング環境へ自動的にデプロイする

1. Heroku Pipelines を作成する

Heroku/GitHubにはすでにログインしている状態からスタートします。

まずは、Herokuパイプラインを作成しましょう。

Herokuダッシュボードのアプリケーション一覧の画面からはじめます。右上のNewボタンをクリックして、プルダウンメニューからCreate new pipeineをクリックします。

Screen Shot 2018-12-09 at 16.52.28.png

「Create New Pipeline」では、(1)パイプラインの名前を入れる (2)GitHubリポジトリと連携する、の2つの作業が必要です。パイプラインの名前は、自分の管理するパイプラインの中に同じ名前がなければ、好きな名前を割り当てられます。好きな名前を入れましょう。次にConnect to GitHubボタンをクリックします。

Screen Shot 2018-12-09 at 16.55.26.png

GitHubの認可画面が出てきますので、すでにログインしていれば次の画面になります。未ログインの場合はログイン画面になるでしょうから、ログインします。対象のユーザのみならず、他のOrganizationも利用する場合は、それらも「Grant」します。そして、対象のユーザ/組織への認可で問題がなければ「Authorize heroku」 ボタンをクリックしましょう。

Screen Shot 2018-12-09 at 16.58.10.png

正常に認可されると、次のようにConnect to Github欄に「search box」が出てきます。左側がユーザ/組織を選択する部分で、そこを指名したあと、今回、連動したいGitHubリポジトリの名前を入れて「Search」ボタンを押します。

Screen Shot 2018-12-09 at 17.03.19.png

対象のリポジトリの「Connect」をクリックして、問題がなければ「Create pipeline」をクリックします。これで、Heroku Pipelineの作成は完了です。

2. 必要な環境を割り当てる

正常に作成されると、Heroku Pipelineのダッシュボードになります。まだHeroku Appが、STAGINGPRODUCTIONに割り当てていません。次にそれらのHeroku Appを作成します。

Screen Shot 2018-12-09 at 17.06.52.png

おもむろに該当環境の「Add app...」ボタンをクリックします。既存のHeroku appも指定する場合には、Search for existing app...へ文字を入れて該当のアプリケーションを指定して選択して割り当てます。今回は新規に作成しますので、「Create new app...」を押します。

Screen Shot 2018-12-09 at 17.08.38.png

画面右側に、Heroku appを新しく作成できる画面がにゅっと現れます。App nameに好きな名前を入れて作成することもできますが、全世界で唯一の名前になる必要がありますので、根気よく緑色になるまで入力してください。「めんどくさい」と思われたら、空欄のママでも自動的にHeroku側が割り当ててくれますので、そちらもご利用ください。ここでは「Create app」ボタンをクリックすれば、すぐにHeroku appが作成されます。

Screen Shot 2018-12-09 at 17.11.33.png

問題なく作成されたでしょうか?

うまくいきましたら、同じ要領で、もう一つの環境にもHeroku appを割り当ててください。わたしの方ではこの様になりました。慣れてくれば、ここまでで30秒とかからないはずです。

Screen Shot 2018-12-09 at 17.16.26.png

ここまでで、テスト環境と本番環境を割り当てるところまでが終了です。あとは、自動的なテストとデプロイの設定です。

3. 各機能をオンにする

次の3つの機能をオンにします。それだけです。

  1. Heroku CI - 自動テスト (有償です orz)
  2. Review App - PR環境の自動生成
  3. Auto Deploy - ブランチと連動して自動的にアプリをリリース

1. Heroku CI - 自動テスト

Heroku Pipelineダッシュボードの上の方に、次のよな帯が出ていればしめたものです。「Enable CI」ボタンをクリックすれば完了です。

Screen Shot 2018-12-09 at 17.18.04.png

正式な設定方法は、Heroku PipelineダッシュボードのSettingsタブ内にあるHeroku CI欄で「Enable Heroku CI」ボタンをクリックすればよいです。

Screen Shot 2018-12-09 at 17.18.30.png

このHeroku CIですが、無償アカウントでは利用できません。ごめんなさい。試しにやってみると、こんな赤いポップアップが出ます。ツラい。

Screen Shot 2018-12-09 at 17.24.00.png

Heroku CIを利用するには、クレジットカードを登録したユーザアカウントか、Heroku Enterprise 組織内のユーザアカウントを利用する必要があります。また、クレジットカードユーザの場合は月に$10/月かかります。よーく見ると書いてありますよね。

Each pipeline with Heroku CI enabled is charged $10/month. Charges for dyno and add-on usage from test runs are prorated to the second. All charges are billed to the selected pipeline owner.

また、テスト用に起動するCI環境のDynoやAdd-onも秒単位で課金の対象となりますとあります。好き放題に使うには Heroku Enterprise契約にしましょう。営業紹介するので、いつでもお声がけください。

Heroku CIを使えるようにすると、GitHubリポジトリ内のソースコードが変更されるたびに、Heroku CIが実行され、そのテスト記録が全て残されます。ダッシュボード内の「Tests」タブ内がこんな画面で埋め尽くされます。テストに失敗すると、赤い文字になりますよ。

Screen Shot 2018-12-09 at 17.30.09.png

2. Review App - PR環境の自動生成

PR環境を作成しましょう。これをHerokuではReview Appと呼んでいます。GitHubでプルリクエストを上げると、そのプルリクエストソースコードツリーを拾って、一時的にレビュー専用の環境として作成します。作り方もカンタンですし、無償アカウントでも利用いただけます。まずは「REVIEW APPS」の「Enable Review Apps...」ボタンをクリックします。

Screen Shot 2018-12-09 at 17.32.55.png

「Enable Review Apps」では3つ、選択するものがあります。

  1. Inherit config vars from an app in this pipeline - 環境変数を、どのHeroku Appベースとするかを指定します。どの環境を引き継ぐか、ということですね。
  2. Create new review apps for new pull requests automatically - GitHubPull Request があがったら、自動的にReview Appを作成します。チェックしておきましょう。
  3. Destroy stale review apps - 作成してから経過した時間で自動的に勝手に削除します。1、2、5、30日から選択できます。なお、Pull Requestされたソースコードが、別のブランチにマージされると、自動的にReview Appも削除されます。

Screen Shot 2018-12-09 at 17.33.17.png

※ これらのうち、2. 3. は後でいつでもカンタンに変更可能です。1.は変更できないので、一度Disableしてからの再作成となります。

3. Auto Deploy - ブランチと連動して自動的にアプリをリリース

最後の設定ですね。ここまででだいたい45秒です。

本番の環境へもできますが、いきなり本番ってのはきついので、masterブランチと連動して、ステージングの環境へリリースされるように設定します。STAGINGに設定されている Heroku app内の上下矢印になっているボタンをクックします。次のプルダウンメニューが出てきますから「Configure automatic deploys...」をクリックしましょう。

Screen Shot 2018-12-09 at 17.43.08.png

ここでの設定は2つだけです。

  1. Choose a branch to deploy - どのブランチにマージ(コミット)されたら、自動的にこの環境へデプロイするか、という指定です。今回はmasterとしておきましょう。
  2. Wait for CI to pass before deploy - デプロイ前に、Heroku CIが成功していることを条件とする。Heroku CIが失敗したときはデプロイしないようにできるわけです。無償アカウントの場合もチェック入れられますが、Heroku CIは実行されないので、とくに関係なく自動的にデプロイされるようです。

Screen Shot 2018-12-09 at 17.44.40.png

これらの設定が終わったら「Enable Automatic Deploys」ボタンをクリックします。次の画面が出てくれば成功でしょう。なぜか、この画面が出て止まりますので、問題なければ右上の「☓」を押しときます。

Screen Shot 2018-12-09 at 17.44.54.png

設定を終えて

ここまでで55秒程度で実演可能です。ほんのこれだけで、CI/CDを実現するに十分な環境を準備することができます。必要最低限な少ない設定しかありませんが、これ以上に細かく何かを設定する必要がある場合には、そのようなサービスを利用・連携する必要があります。しかし、そこまで必要なことがどれだけあるのか、そこまでする必要性はどこまであるのか。本当に必要なことを、必要なだけ、シンプルにアイディアを高めて実践していきましょう。

今回は設定しかご紹介していませんが、実際にどのようにフローを回したら良いのか、実際にフローを回すとどの様になるのかについては、以前に「Herokuとチーム開発のおいしいレシピ~HerokuとGitHubを連携してCI/CDを実現する」を書いておりますので、こちらを参考にしていただけると幸いです。

中級編はここまでです。次回の上級編でお会いしましょう。

heroku上でプロセスのメモリ使用率を正確に取得できない件について

External article

Heroku の Preboot 機能を深掘りした

External article

BitBar の Heroku plugin はいいぞ

External article

Heroku の環境変数の管理

External article

Herokuのビジネス的な利用価値

External article

Heroku Changelog 2018

はじめに

Heroku Advent Calendar 2018、16 日目です。Changelog はどういうタイミングで確認していますか?みなさんのアプリが日々進化しているのと同様に Heroku Platform もより洗練され、新機能が追加されています。この 1 年でどんなことがあったか振り返ってみましょう。

Changelog

1 月 1 日 から 12 月 15 日までで 209 ありました。みなさん何か印象に残っているものはありますか?

今年最初の Changelog はこちら

現在は既存のものを除き 9.3 は新規作成できなくなっています。サポートし始めたのが 09 September, 2013 なので 5 年程たっています。息が長い!version 11 は現在ベータなので来年は GA になっていることでしょう。

現時点で今年最後の Changelog はこちら

この Changelog にある Ruby を含め公式の Buildpack を提供している言語は引き続き手厚くサポートされていますね。

大きな変更やリリースはどんなものがあったか

全ては挙げられないので2018年にちなんで、18つほどピックアップ、というようにしていくと毎年増えていくので 10 つに絞りました。時系列に並べていきます。

公表日 内容
14 March 2018 Shield-S dynos are now available for Shield Private Spaces
20 April 2018 Heroku Connect Bulk Writes to Salesforce Now Generally Available
24 April 2018 Webhook dyno events now in public beta
24 May 2018 Heroku CLI Autocomplete in GA
12 September 2018 Heroku CI Parallel Test Runs now generally available
13 September 2018 Private Space VPN and Internal Routing are now generally available
17 September 2018 Adding a custom domain will now return a randomly generated DNS target
22 October 2018 Automatic HTTPS support for .herokuapp.com domains in Private Spaces
13 November 2018 Building Docker images with heroku.yml is now generally available
05 December 2018 Heroku CLI login now opens the browser by default

ブラウザからのログインは 1Password とか LastPass とか使っていちいちパスワードを覚える必要がないので、CLI のログインもブラウザ経由になるのは地味に便利ではないでしょうか。Docker image も Heroku 側でビルドできるようになったりとこのあたりの変化も要チェックですね。

Changelog をどうやって追うか

その他

Heroku Blog: 主な新機能についてアナウンス

Changelog より技術的につっこんだ内容が多く面白いと思うので、こちらも時々見ることをお勧めします。

Heroku のアドオンを自作する方法を見てみた

あまり試せていないですが、Heroku のアドオンの作り方についての情報が少なかったので、ざっと調べられる範囲で書いてみました。

はじめに

Heroku のアドオンは次の条件を満たしている必要があるんだそう

  1. HTTPSのリクエストを受信できること
  2. JSONをパースすることができる

アドオンパートナーに登録する

Herokuのアドオンを作るためにはアドオンパートナーになる必要があるため、次の手順を行います

  1. Herokuの無料アカウントを作成
  2. addons-next.heroku.com にアクセス
    Herokuパートナーポータル.png

  3. 規約に同意するよう求められるので、内容を確認してAcceptボタンをクリック

これでパートナーポータルの画面に遷移することができます。

手順

ここからアドオンの開発手順に移っていきます。

  1. addon-adminプラグインをインストール

    $ heroku plugins:install addons-admin
    
  2. addon-adminプラグインを使用してマニフェストファイルを作成

    $ heroku addons:admin:manifest:generate
    Input manifest information below: 
    ? Enter slugname/manifest id: my-addon
    ? Addon name (Name displayed to on addon dashboard): MyAddon
    ? Choose regions to support
      <space> - select
      <a> - toggle all
      <i> - invert all 
      ↑↓ use arrow keys to navigate
     tokyo
    ? Would you like to generate the password and sso_salt? Yes
    ? This prompt will create/replace addon-manifest.json. Is that okay with you? Yes
    Generating add-on manifest... done
    The file addon-manifest.json has been saved!
    
  3. Add-on Partner APIを使用してアドオンインスタンスの作成・追加・削除などの実装を行う

  4. 次のコマンドでアドオンをプッシュする

    $ heroku addons:admin:manifest:push
    

だいぶアレですが、ざっくりだとこんな感じみたいです。
以前は Provider API というものを使っていたみたいですが、今だと名前が変わっていました。
また、2018年4月からAdd-on Partner API のバージョンも変わっているみたいでした。

参考

Heroku Metricsについて

External article

HerokuのRelease PhaseやPreDeploy Script中に得た値を保持する方法

Release Phase, predeploy 中に得た値を pr-predestroy でも使いたい

HerokuにはRelease Phaseやpredeploy,pr-predestroyといった、アプリケーションがビルド・リリースされる際に自由にScriptを差し込むことができる機能があります。
image.png
Release Phase : https://devcenter.heroku.com/articles/release-phase

非常に便利なのですが、単純にScriptを動作させる機能ですので生成・取得した値をアプリケーションに渡す方法などは備わってません。
しかしHerokuをCI/CDの実現の為にPipelineサービスとして利用するようなケースだと、predeployやRelease Phaseの中でビルド処理などを行い、pr-predestroyで環境のクリーンアップを行う様なケースも出てきます。その際には、Script中で得られたビルドに関する情報を保持しておく必要があります。

例えばSalesforceアプリをCI/CDするケースでは、Herokuはそのビルド処理とパイプライン管理を担当します。
predeployのScript中でインスタンスの情報(インスタンスURL、Usernameなど)を生成しますが、この情報を覚えておけないため後で作成したアプリを破棄することができず、PRが作成されるたびに無駄なSalesforceインスタンスが生成され続ける事になります。

ここでHeroku標準では環境変数の置き場であるConfig Varsの機能がありますが、Herokaiな貴方ならもうお気付きの通りHeroku Config Varsは変更されるとリリースプロセスが再実行されます。つまり場合によっては無限ループとなってしまったり、そもそもHerokuコマンドでHeroku VarsをDynoの中で利用するには自分のアプリ名を受け渡す必要があるなど、あまりシンプルな作りになりません。

ではどのように解決するか? ですがHeroku Redisを利用するという方法があります。

Heroku Redis Add-onを利用して値を受け渡す

言ってしまえば単純な話ですが、Heroku Redis Add-onを用意してRedis経由で値をやりとりします。
もちろんPostgresを使ったり、他の何かしらのデータ永続化サービスを使えば同様の事は実現できますが、Redisの場合には設定及びCLI経由でのアクセスが簡単なのでお手軽です。

Step1. 必要な BuildPack 及び Add-on の追加

RedisにRelease Phaseやpredeploy, pr-predestroyからアクセスするには、redis-cliを利用する方法が手っ取り早いです。Heroku標準ではredis-cliは入っておらず、専用のBuildPackもありませんが、aptコマンドを実行して任意のパッケージをインストール可能にする apt BuildPack (https://github.com/heroku/heroku-buildpack-apt.git) があるのでこれを利用します。
サンプルでは他の処理をするSalesforce-cliとJSONの処理用にjqの BuildPackが定義されていますが、apt BuildPackはこのように他のBuildPackと併用して利用することが可能です。
また当然Redisが必要となりますので、heroku-redis Addonも追加しておきます。
app.jsonで表現すると以下の様な構成です。

app.json
{
    "name": "Sample App",
    "description": "Sample app for Salesforce Pipeline",
    "keywords": [
        "heroku"
    ],
    "scripts": {
        "predeploy": "./predeploy.sh",
        "pr-predestroy": "./pr-predestroy.sh"
    },
    "addons": [
        "heroku-redis"
    ],
    "buildpacks": [
        {
            "url": "https://github.com/mokamoto/salesforce-cli-buildpack.git"
        },
        {
            "url": "https://github.com/heroku/heroku-buildpack-apt.git"
        },
        {
            "url": "https://github.com/chrismytton/heroku-buildpack-jq.git"
        }
    ]
}

実際のRedis-cliはaptのredis-toolsのパッケージの中にあります。apt BuildPackはトップディレクトリのAptFileというファイルを読み込んでパッケージを展開する仕様となっていますのでこちらも用意します。

Aptfile
redis-tools

Step2. Script 中で Redis を利用する

環境さえ整えばあとは簡単です。
Heroku Redis Add-onを入れるとConfig VarsのREDIS_URLに接続するためのURIが入りますので、これを利用するだけです。
サンプルとしてSalesforce CLIを用いた組織生成のコードの一部を書いていますが、重要な部分は下部のredis-cliを利用すれば任意のkeyに対して値を保存できるという部分です。

predeploy.sh
#!/bin/sh

############  Salesforce関連処理。検証用インスタンス(Scratch組織)を立ち上げ、ソースコードをデプロイする ############ 
#Decrypt server.key
openssl aes-256-cbc -d -pass pass:$SFDX_DEVHUB_KEY_CRYPT_PASS -in assets/server.key.enc -out assets/server.key

#管理アカウントで認証
sfdx force:auth:jwt:grant --clientid $SFDX_DEVHUB_CONSUMERKEY --jwtkeyfile assets/server.key --username $SFDX_DEVHUB_USERNAME --setdefaultdevhubusername -a HubOrg

#Salesforceインスタンス生成
sfdx force:org:create -v HubOrg -s -f config/project-scratch-def.json -a DevOrg

#ソースコードデプロイ
sfdx force:source:push -u DevOrg

#権限セットアサイン
sfdx force:user:permset:assign -n purealoe -u DevOrg

#サンプルデータロード
sfdx force:data:tree:import -p data/sample-data-plan.json -u DevOrg

#設定情報の取得
TEMP_JSON_RESPONSE=$(sfdx force:org:display --json)
TEMP_LOGIN_URL=${INSTANCE_URL}/secur/frontdoor.jsp?sid=${ACCESS_TOKEN}
TEMP_USER_NAME=$(echo $SFDX_JSON_RESPONSE | jq -r ".result.username")
################################################################################################

####################################  Redisへ値を保持しておく ####################################

#ログインURL (WebアプリがRedirectするURL)
redis-cli -u $REDIS_URL set SFDX_SCRATCH_ORG_LOGIN_URL ${TEMP_LOGIN_URL}

#ユーザ名 (Salesforceインスタンスを削除する際に必要)
redis-cli -u $REDIS_URL set SFDX_SCRATCH_ORG_USERNAME ${TEMP_USER_NAME}
################################################################################################

保持した値を利用する場合にも、redis-cliを利用します。
例えばPull RequestがCloseされた際に、Redisから取得してDeploy時に作成したSalesforceインスタンスを削除します。

pr-predestroy.sh
#!/bin/sh

####################################  Redisから値を取得する ####################################

TEMP_USERNAME=$(redis-cli -u $REDIS_URL get SFDX_SCRATCH_ORG_USERNAME)

################################################################################################


############  Salesforce関連処理。一時的に作成したSalesforceインスタンスを削除する ############ 
#Decrypt server.key
openssl aes-256-cbc -d -pass pass:$SFDX_DEVHUB_KEY_CRYPT_PASS -in assets/server.key.enc -out assets/server.key

#管理アカウントで認証
sfdx force:auth:jwt:grant --clientid $SFDX_DEVHUB_CONSUMERKEY --jwtkeyfile assets/server.key --username $SFDX_DEVHUB_USERNAME --setdefaultdevhubusername -a HubOrg

#Salesforceインスタンスを削除
sfdx force:org:delete -u $(TEMP_USERNAME)

Pull Requestが来るたびにRedis Addonなどの環境は都度出来上がりますので、この様な簡易的なScriptでもSalesforceのPilelineを上手く回すことができます。リクエスト環境に応じて適宜書き換えていけば、かなり自由度が高くScriptingができると思います。

Happy Hacking!!

【Heroku検討者向け】デプロイ方法5選!

皆さんはHerokuへのデプロイ方法どうしてますか。
スタンダードだとgitでpushとか、今回のheroku Advent Calendar 2018 1日目でも@sho7650さんが、Githubとの連携方法を分かりやすく解説してくれていますね。

さて、今回は「Heroku、使ってみようかな〜」という方向けに、こんなデプロイ方法あるよ!っていうのを5つ、ご紹介していこうと思います。

検証環境

OS
macOS High Sierra 10.13.6
git
git version 2.17.2 (Apple Git-113)
heroku cli
heroku/7.19.3 darwin-x64 node-v11.3.0
docker
docker for mac Version 2.0.0.0-mac81 (29211)

はじめに

サンプルアプリはこちらを採用しました。
https://github.com/heroku/ruby-getting-started
本記事の内容で遊んでみたい方はアプリのダウンロードを最初にお願いします。

$ git clone https://github.com/heroku/ruby-getting-started.git
Cloning into 'ruby-getting-started'...
remote: Enumerating objects: 363, done.
remote: Total 363 (delta 0), reused 0 (delta 0), pack-reused 363
Receiving objects: 100% (363/363), 72.09 KiB | 403.00 KiB/s, done.
Resolving deltas: 100% (136/136), done.

これから実行するコマンドは特別な指定がない限り、全てアプリケーションのルート直下で実行します。

また、料金にはお気をつけ下さい。
本記事の内容は全て無料枠内で再現可能ですが、万が一オペレーションミス等で料金請求が発生しても一切の責任を負いかねます。

(1)git(https)

参考ドキュメント:
https://devcenter.heroku.com/articles/getting-started-with-ruby

一番スタンダードなやつです。

まずはherokuアプリを作成します。

$ heroku create
Creating app... done, ⬢ still-mesa-87412
https://still-mesa-87412.herokuapp.com/ | https://git.heroku.com/still-mesa-87412.git

続いてbuildpackの指定。

$ heroku buildpacks:set heroku/ruby -a still-mesa-87412
Buildpack set. Next release on still-mesa-87412 will use heroku/ruby.
Run git push heroku master to create a new release using this buildpack.

ちなみにbuildpackの指定というのはgithubのURLを直接指定してもできるのですが、
オフィシャルなbuildpackの指定をURLで行うのは、開発中のbuildpackを取り込んでしまう恐れがあるので非推奨です。
ちゃんとheroku/xxxで指定しましょう。

https://devcenter.heroku.com/articles/buildpacks#using-a-third-party-buildpack

You can also specify the full Git URL of an official buildpack. This causes the master Git branch of the buildpack to be used, instead of the last released version. Because the latest Git version might contain unexpected changes, it is highly recommended to use the heroku/… syntax for official buildpacks.

デプロイはgit pushで行います。

$ git push heroku master

(2)git(ssh)

参考ドキュメント:
https://devcenter.heroku.com/articles/git#ssh-git-transport

(1)でご紹介した方法だと、デフォルトでgitの通信プロトコルにhttpsが指定されてしまっています。
ちゃんとsshキーでデプロイする方法もございます。

まずはアプリの作成をします。

$ heroku create
Creating app... done, ⬢ tranquil-badlands-65917
https://tranquil-badlands-65917.herokuapp.com/ | https://git.heroku.com/tranquil-badlands-65917.git

ここでgitの接続先を確認するとhttpsになっているのが分かります。

$ git remote -v
heroku    https://git.heroku.com/tranquil-badlands-65917.git (fetch)
heroku    https://git.heroku.com/tranquil-badlands-65917.git (push)

以下のコマンドを実行すると接続先が切り替わります。

$ heroku git:remote --ssh-git --app tranquil-badlands-65917
set git remote heroku to git@heroku.com:tranquil-badlands-65917.git

切り替わったことの確認。

$ git remote -v
heroku    git@heroku.com:tranquil-badlands-65917.git (fetch)
heroku    git@heroku.com:tranquil-badlands-65917.git (push)

キーの登録をします。
PATHは良しなにお願いします。

$ heroku keys:add ~/.ssh/public_key

あとは(1)と同じようにbuildpackを設定してデプロイするだけです。

$ heroku buildpacks:set heroku/ruby --app tranquil-badlands-65917
$ git push heroku master

(3)buildpackをtarballにする

参考ドキュメント:
https://devcenter.heroku.com/articles/buildpacks

buildpackは公式のものやpublic githubにあるものを用いる方法がありますが、
httpsアクセス可能かつPublicな場所にbuildpackをアーカイブ(tarball)にして配置してアプリをデプロイするという方法もあります。

buildpackを自作した際に有用かもしれませんね。

公式ドキュメントで推奨されているAWS S3を用いて検証してみます。
https://devcenter.heroku.com/articles/buildpacks#buildpack-references

Your buildpack value can point to either git repositories or a tarball URL. Hosting a buildpack on S3 can be a good way to ensure it’s highly available.

まずはpublicなs3バケットを作りましょう。
S3バケットをAWSのマネジメントコンソールから作成し、
作成した対象のバケット→アクセス権限→バケットポリシー
と進んで、バケットポリシーエディタに以下の権限を書いて保存します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::test-ruby-heroku-buildpack/*"
        }
    ]
}

ResourceのARNは良しなにお願いします(バケットポリシーエディターの横に書いてあります)。

続いてbuildpackのtarballを作ります。
いきなりカスタムビルドパックを作れというのも敷居が高いので、
今回はオフィシャルなBuildpackを使いましょう。

$ git clone https://github.com/heroku/heroku-buildpack-ruby.git
$ cd heroku-buildpack-ruby/
$ tar cfvz heroku-buildpack-ruby.tar.gz ./

作成したbuildpackは先ほど作ったPublicなS3バケットに配置します。

続いてアプリを作ります。

$ heroku create
Creating app... done, ⬢ secret-wave-57965
https://secret-wave-57965.herokuapp.com/ | https://git.heroku.com/secret-wave-57965.git

先ほど作成したS3バケットに保存したbuildpackのエンドポイントを指定します。

$ heroku buildpacks:set https://s3-ap-northeast-1.amazonaws.com/test-ruby-heroku-buildpack/heroku-buildpack-ruby.tar.gz
Buildpack set. Next release on secret-wave-57965 will use https://s3-ap-northeast-1.amazonaws.com/test-ruby-heroku-buildpack/heroku-buildpack-ruby.tar.gz.
Run git push heroku master to create a new release using this buildpack.

最後は(1)と(2)と同様にgit pushして下さい。

$ git push heroku master

(4)マニフェスト

参考ドキュメント:
https://devcenter.heroku.com/articles/buildpack-builds-heroku-yml

なんだか1年くらいdeveloper preview状態な気がします。
多分、きっと、恐らく、そろそろ大丈夫な気がしますので取り上げます。

このデプロイ方法は、マニフェスト(heroku.yml)というファイルにアプリ周りのいろんな情報を記載してデプロイすることができます。

例えば、(1)(2)ではデプロイするためのアプリがrubyであることを以下のコマンドで明示的に示したりしていました。

$ heroku buildpacks:set heroku/ruby -a still-mesa-87412
Buildpack set. Next release on still-mesa-87412 will use heroku/ruby.
Run git push heroku master to create a new release using this buildpack.

これをデプロイの際に行うのは煩雑です。
こういった情報をマニフェストに記載できます。

この他にもherokuにはアプリにDBやcacheを提供するアドオンという機能もあるのですが、
マニフェストを使わない場合は、都度コマンドやコンソール画面からアドオンと対象のアプリを紐付けるか、app.jsonという別ファイルに記載する必要があります。
また、Procfileというアプリコンテナ(Dyno)で立ち上がるプロセスを管理する設定ファイルがあるのですが、これもマニフェストにまとめることができます。

つまり多岐に渡るアプリ周りの設定を1つのマニフェスト(heroku.yml)というファイルで一元管理できるのです。

では、触ってみましょう。

開発中の機能のため、heroku cliをbeta版に引き上げます。

$ heroku update beta
heroku: Updating CLI from 7.19.3 to 7.19.3-beta.1039421 (beta)... done
heroku: Updating CLI... done

続いて、manifestプラグインを導入します。

$ heroku plugins:install @heroku-cli/plugin-manifest
Installing plugin manifest... installed v0.0.5

サンプルアプリのルートディレクトリにマニフェストファイル(heroku.yml)を作成します。

heroku.yml
setup:
  addons:
    - plan: heroku-postgresql
      as: DATABASE
build:
  languages:
    - ruby
run:
  web: bundle exec puma -C config/puma.rb

Procfileで実行予定だったものはマニフェストに記載したので、Procfileは削除しちゃいましょう。

$ rm Procfile

デプロイするため、ここまでの変更をコミットします。

$ git rm Procfile
$ git add heroku.yml
$ git commit -m "Added heroku.yml and removed Procfile"

続いてアプリを作成します。

$ heroku create --manifest
Reading heroku.yml manifest... done
Creating app... done, ⬢ evening-falls-33930, stack is container
Adding heroku-postgresql... done
https://evening-falls-33930.herokuapp.com/ | https://git.heroku.com/evening-falls-33930.git

--manifestオプションを付ける事によって、スタックにコンテナが使われたことがわかります。
スタックとはアプリケーションが動くオペレーティングシステムイメージのことです。
ubuntuをベースとしてherokuが手を加えたものになります。

デフォルトだとheroku-18が採用されますが、このマニフェストの場合はコンテナとなるのもマニフェストデプロイの特徴です。

コードをデプロイします。

$ git push heroku master

無事にstackにはコンテナが設定されています。

$ heroku stack --app evening-falls-33930
=== ⬢ evening-falls-33930 Available Stacks
  cedar-14
* container
  heroku-16
  heroku-18

まぁ、でもとはいえ、ベースはubuntuなんですけどね。

$ heroku run bash
Running bash on ⬢ evening-falls-33930... up, run.8448 (Free)
~ $ uname -a
Linux 21f3c783-4450-4493-b01f-17c5371fd07f 4.4.0-1031-aws #34-Ubuntu SMP Tue Sep 25 09:08:48 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

さあ、遊び終わったらHeroku CLIを安定版に戻して、manifestプラグインをremoveしましょう。

$ heroku update stable
$ heroku plugins:remove manifest

(5)Docker

参考ドキュメント:
https://devcenter.heroku.com/articles/build-docker-images-heroku-yml
https://devcenter.heroku.com/articles/container-registry-and-runtime

最近何かと話題のDockerですが、Herokuでも利用可能です。
HerokuにDockerをデプロイするには以下の2つのやり方があります。

  • マニフェストを利用し、Dockerfileをheroku上でbuildする
  • Dockerコンテナをherokuのレポジトリに保存し、それをリリースする

まず、マニフェストを利用し、Dockerfileをheroku上でbuildする方法ですが、
(4)で使用したマニフェストファイル(heroku.yml)を以下のように変更します。

heroku.yml
build:
  docker:
    web: Dockerfile
run:
  web: bundle exec puma -C config/puma.rb

こうすることで、webプロセスのビルドをDockerfileにすることができます。
このDockerfileのPATHはheroku.ymlからみた相対PATHとなります。

buildの下にあるrunですが、これはDockerfileが存在しなかった場合にはrunを実行するということになります。

この時、stackをcontainerにすることを忘れないようにしましょう。

$ heroku stack:set container
Stack set. Next release on ⬢ nameless-lowlands-11461 will use container.
Run git push heroku master to create a new release on ⬢ nameless-lowlands-11461.

あとはgit pushすれば先ほどheroku.ymlで指定した箇所はDockerfileの内容でbuildされて立ち上がる・・・はず。
※すみません、ここだけサンプルアプリでの検証が間に合いませんでした。。。

$ git push heroku master

続いて、Dockerコンテナをherokuのレポジトリに保存し、それをリリースする方法です。
これにはこちらのサンプルアプリを使いましょう。
https://github.com/heroku/alpinehelloworld/

まずはサンプルアプリをダウンロードします。

$ git clone https://github.com/heroku/alpinehelloworld.git
Cloning into 'alpinehelloworld'...
remote: Enumerating objects: 59, done.
remote: Total 59 (delta 0), reused 0 (delta 0), pack-reused 59
Unpacking objects: 100% (59/59), done.

続いてアプリを作ります。

$ heroku create
Creating app... done, ⬢ pacific-island-27732
https://pacific-island-27732.herokuapp.com/ | https://git.heroku.com/pacific-island-27732.git

Heroku Container Registryにログインします。

$ heroku container:login
Login Succeeded

サンプルアプリのルートディレクトリに移動し、以下のコマンドを叩きます。

$ heroku container:push web

サンプルアプリのルートディレクトリにはDockerfileが置かれているため、
Heroku Container Registry上でDockerのbuildが行われます。

ちなみにpushの後ろにあるwebはプロセスタイプのことです。
https://devcenter.heroku.com/articles/procfile#the-web-process-type

pushしたコンテナはビルド済みなので、以下のコマンドですぐにリリースできます。

$ heroku container:release web

最後に

いかがでしたでしょうか。
普段業務だとあまりHerokuに触る機会がなく、久しぶりに調べてみたら色々と発見があり楽しかったです。

少しでも皆さんの知見に貢献できたなら幸いです。
最後までお読み頂き有難うございました。

Heroku の Slug は友達

External article

heroku 上級編 - Private Space でできること -

Advent Calendar 2018 Heroku 編 22日目、このまま順当にすべて埋まるかどうかは、なんか私にかかっているような気がする今日このごろ、しょっさんです。

本日は、Private Space についてです。無償・クレカアカウントなどで、普段はCommon Runtimeご利用の方の認知率がいかほどか、とても気になるサービスです。Herou Private Space については、以前、Codezineにて「 Herokuの運用とセキュリティ~HerokuでSSL証明書の自動化とPrivate Spacesでセキュリティを強化しよう」と題した記事で紹介しています。こちらも合わせてご覧いただければ幸いです。

Heroku Private Spaces

Heroku Private Spaces の最新情報についてはHeroku Private Spaces のWebページでご覧いただけます。今回は、この中からエンジニアのみなさんが飛びつきそうな機能について紹介します。

まず、Private Space にすると何が良くなるのでしょうか。一言でいえば、よりセキュアになります。そして、Herokuをより安全に拡張することのできる仕組みがたくさんついています。今日はその中から主な次の機能について説明します。

  1. 専用の隔離されたネットワーク
  2. マルチリージョン
  3. 接続IPアドレスの制御
  4. DNS サービスディスカバリ
  5. サイト間VPN/Peering
  6. Internal Routing

このようにHerokuをよりセキュアなプラットフォームで稼働させることで、オンプレを拡張したクラウドアプリケーション拡張基盤として、大企業での利用にも考慮した安全なネットワークを提供するプラットフォームとして、ご利用いただける代物となってるわけです。

1. 専用の隔離されたネットワーク

Heroku アプリケーションと、Heroku の提供するデータサービス(Postgres, Redis, Kafka)が、論理的に隔離されたネットワーク内に配置されます。AWS の VPC内に Heroku Dyno とデータサービスが配置される、という仕組みです。

従って、外部からデータベースへは直接アクセスすることができないようになっていたり、Private Space内だけで稼働するような内部用アプリケーションサービスなどの開発も実現できます。

2. マルチリージョン

Heroku Common Runtime では、EU/北米の2つのリージョンしか選択ができません。

Private Space を作成いただくことによって、2018年12月22日現在、次の6拠点のリージョンでHerokuのアプリケーションを配置することができるようになっています。

  1. 東京
  2. バージニア
  3. オレゴン
  4. フランクフルト
  5. シドニー
  6. ダブリン

主に日本向けのサービスを展開するようなとき、レイテンシが気になるような場合は東京リージョンを選択すると、低レイテンシでアクセス可能なWebアプリケーションサービスを提供できます。また、複数のリージョンにSpaceを配置して、国をまたいだ災対環境を準備することも可能です。Heroku Postgres のフォロワー機能を使えば、異なるリージョンへのデータ同期も、クリックひとつで実現できちゃいます。

3. 接続IPアドレスの制御

隔離されたネットワークだからこそ実現できるとも言えるでしょう。接続元のIPアドレスを制限できます。

特定の社内や企業からだけのアクセスしかさせたくない、開発テスト環境なので、開発者たちからしかアクセスさせたくない、そのようなニーズに応えることができます。

また、Private Spaceにしていただくと、Heroku からのアクセスについて、IPアドレスが4つに固定されます。Heroku アプリケーションから、特定のネットワークへ接続するようなとき、IPアドレスでアクセス制御を行う場合にも、Private Space は活躍します。

4. DNS サービスディスカバリ

Common Runtime では、Web Dyno以外の Worker Dynoへダイレクトにアクセスしたいということが実現できません。ですから、非同期アプリケーションとWebアプリケーションを連携させたいようなときは、間に Redisなどをいれて、キューイングさせたりすることが王道パターンのようになっています。結局、すべてを Web Dynoとして、必要なサービスをすべて Herokuアプリケーションとして公開してしまえば、該当のホスト名へアクセスすればよいわけです。しかし、外部に公開したくないようなサービスだったり、特定の非同期アプリケーションとAPIで連携したいケースは多々あります。

そういったわがままにも柔軟に対応できるのが、Private Spaceのもつ DNS Service Discovery です。

Private Space内のすべてのDynoは、内部的にホスト名を持ちます。どのHerokuアプリケーションの、どのプロセスタイプの、どのDynoまで細かく指定をすることができます。この機能は同一のPrivate Space内だけにはなりますが、外部からアクセスさせたくないサービスや、非同期アプリケーションサービスへの引き渡し、などに対してAPIコールを実現できるすぐれものです。Private Space内での Microservicesもカンタンに実現できてしまう、ということです。

内部アドレスは、次のように定義されています。

内部アドレスのFQDN: [Dyno番号].<プロセスタイプ>.< Herokuアプリ名>.app.localspace

例えば、test-private-space という名前の Herokuアプリケーション上に、webworker Dynoが2つずつ稼働していて、この中の worker の1つ目の Dynoへアクセスしたい場合であれば、1.worker.test-private-space.app.localspace というホスト名へアクセスすれば、該当のアプリケーションへダイレクトに接続することができます。

実際に稼働中のDynoを指定してアクセスできるのはありがた嬉しいのですが、スケールしていて複数のDynoが動いているような場合、わざわざ特定のDynoをアプリケーションで指定するには荷が重すぎます。いくつ動いているかもわからないのに...。

ということで、このFQDNのうち[Dyno番号]は省略することができます。[Dyno番号]を省略してホスト名解決を行うと、稼働中のプロセスタイプのDynoのうち、ランダムで対象のDynoの3つのIPアドレスが返ってくる仕様です。もちろん3台稼働していなければ、1つや2つしか返ってこないケースもあります。この取得したIPアドレスを元にアクセスすれば、自動的に負荷分散の機能も享受されるという仕組みにもなっています。お便利すぎますね!!

5. サイト間VPN/Peering

Heroku Private Spaceでは、オンプレや他のクラウドとセキュアに接続するための方法を2つ、提供しています。

Private Space VPN Connections

Heroku Private Space と Internet VPN を使って、オンプレや他のクラウドとネットワークをセキュアに接続できます。

いくつか制限事項があるので、それらに従っていただく必要はありますが、オンプレのリソース不足を解消するためのオンプレ専用のWebアプリケーションクラウドとして、他のクラウドで使っているリソースと安全に連携させたい、と言ったわんぱくな機能要求に応えることができます。

とくに、Google Cloud Platformとはカンタンに接続しやすく、Site-to-site VPN Connections to Google Cloud Platformという記事も準備されている程度です。実際に試してみたら、カンタンに実現できましたので、そろそろ手順を公開したいなとは考えてます。

で、従っていただく制約は次のとおりです。

  • Private Space で定義されたCIDRと同じネットワークは接続できません (Space作成時にIPネットワークレンジの変更
  • BGPは非サポートです。静的ルーティングのみ設定可能です
  • 相手側のVPNルータには、公開されたIPアドレスで接続できる必要があります
  • VPNプロトコルは、IPsec IKEv1事前共有鍵方式 aes-128-cbc暗号化「のみ」が利用可能です
  • Firewall 内のVPNルータへアクセスさせる場合には、4500/udp, 500/udp のポート開放が必要です
  • データサービスとのダイレクト接続はできません

Private Space Peering

セキュアに相手のネットワークと接続する先が、Amazon Web Servicesの場合、Private Space Peeringの機能が利用可能です。

いわゆるVPC Peering機能をそのまま実装しているだけですが、AWS上のVPCとHerokuのPrivate Spaceを内部的に結合する仕組みです。

基本的には、Herokuアプリケーションから、AWS VPC内のリソースへのアクセスの一方向です。次のInternal Routing機能を利用すると、AWS VPC内のサーバから、Herokuアプリケーションへのアクセスが可能になります。

ただし、このサービスも、データベースへのダイレクト接続はできません。ので、あしからず。
Heroku Private Spaceで利用しているデータベースへダイレクト接続したい場合は、trusted IP whitelisting(β)を利用します。現時点では、まだベータサービスとしての提供となっています。

6. Internal Routing

前述のVPNPeeringで接続したネットワークから、Herokuへアクセスしたい! という要望を叶える機能が、このInternal Routingです。

この機能を使ってHerokuアプリケーションを作成すると、内部からのみアクセス可能なIPアドレスが振られる仕組みとなっています。該当のHerokuアプリケーションのホスト名を解決すると、内部ネットワーク経由でHerokuアプリケーションへアクセスする仕組みとなっています。

このInternal Routingで作成されたHerokuアプリケーションは、Internetからのアクセスは一切できないものとなっています。ですが、同じPrivate Space内であれば、前述のDNS サービスディスカバリを使ってアクセスすることができます。

まとめ

すべての機能ではありませんが、特徴的なPrivate Spaceの機能を紹介しました。今お使いのHerokuアプリケーション、ステップアップしたい、よりセキュアな構成にしたい、クラウドやオンプレ連携を実現したい場合には、ぜひ Private Spaceの利用も検討ください。

Herokuでマルチ(バーチャル)ホストを実現してかしゆかをお祝いする

おめでとうございます。本日はかしゆかの誕生日、良い休日ですね。元気に過ごされていますか、しょっさんです。
Heroku Advent Calendar 2018 23日目、一人で4本目になります、ホント申し訳ない。

かしゆかをどのようにHerokuでお祝いするかと一所懸命考えていたときに、ふと昔作ったテストのサイトを思い出したので、そちらを紹介します。ふくすうの「これはできるの?」に回答できる内容です。

  • Private Space で ACMは使えるの?
  • Heroku でマルチ(バーチャル)ホストは使えるの?

答えはともに「YES」です。具体的な実装方法です。

Automated Certificate Management in Private Space

2018/5/24に紹介されていますが、ACM機能は Private Spaceでも利用可能になりました。ACMとは、Let's Encrypt証明書を自動的に発行・更新し、SSLのサイトを適用するものです。具体的な利用方法については拙作「Herokuの運用とセキュリティ~HerokuでSSL証明書の自動化とPrivate Spacesでセキュリティを強化しよう」をごらんください。

Private Space利用時にも、自動的にSSL証明書を発行し、更新してくれるのお便利ですね。

Heroku でマルチホストはどうするの?

同じくドメイン周りの設定になりますが、具体的な手順を説明します。

Herokuアプリケーションのダッシュボードから、「Settings」タブへ移動します。

中程に「Domains and certificates」があります。見てわかるように、すでに2つ登録されていますね。なんとなく想像がついたと思いますが、「Add domain」ボタンをクリックします。

Screen Shot 2018-12-22 at 13.37.13.png

「New domain」画面が現れますので、登録したいホスト名(FQDN)をここに入力します。すでに割り当て済みのホスト名の場合(多分、名前解決やってみてA/CNAMEなどが割り当てられていると)は、エラーが出て登録できません。
Screen Shot 2018-12-22 at 13.37.54.png

先程の画面に戻ってきますと、登録したホスト名が追加されています。これで3つになりましたね。
Screen Shot 2018-12-22 at 13.38.26.png

DNS Targetという欄があります。ここがCNAMEとして登録すべきホスト名が入っています。おもむろに、ご自分で管理されているDNSサーバにて、該当のFQDNにたいしてCNAMEとして、このDNS Targetのホスト名を入れます。たいていは45〜60分でACM含め登録が完了します。正常に登録されると、上2つのようにACM Statusが「OK」となります。

プログラム側ではどのように対処するの?

HTTP/1.1以上でアクセスしてくるの絶対のはずなので、HTTPヘッダのhostにアクセスしてきたホスト名が入っているはずです。各言語で取得方法は変わるでしょうが、例えば Node.js + Express では次のようになります。

index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function (req, res, next) {
  const hostname = req.headers.host;
  console.log('hostname = ' + hostname);

  if (hostname.match(/^localhost/))
    res.render('local', { title: 'access to localhost' });
  if (hostname.match(/^multi.kashiyuka.info/))
    res.render('kashiyuka', { title: 'access to kashiyuka' });
  if (hostname.match(/^multi.prfm.jp/))
    res.render('index', { title: 'Heroku Meetup #23' });

  console.log('no hostname');
  let err = new Error('host not found');
  err.status = 400;
  next(err);
});

localhostmulti.kashiyuka.infomulti.prfm.jp それぞれで異なるページをレンダリングしていることがわかります。これだけです。

2つのサイト、適当にアクセスしてみてくださいね。今日のお土産はそちらです。

次世代の開発語ります

External article

ウェブサイトの高速化手法 (CDN活用)

概要

  • 費用の関係から Private Spaces を使えずUSリージョンを使う際、「おそくなるんでしょ?」ってたずねられる際には、CDN利用をオススメするので、その内容をご紹介
  • US リージョンの Heroku をそのまま使うケースと、CDNを利用したケースでどのくらいレイテンシーが向上するか?のテストを実施

はじめに

Common Runtime で Heroku を運用しているとき、どうしても気になるのが、データセンターのロケーション。米国かヨーロッパのみが選択可能なので、どうしてもレイテンシーが気になっちゃうところです。

とはいえ、東京リージョンを使うとなると、Private Spaces 利用ということになり、少し?!費用もかさんでしまうため、躊躇してしまうこともあるかと。。。ということで、Private Spaces に頼らず、CDN を使って高速化してみましょうという内容です。

どのくらいのレイテンシーなのか?

Heroku のデータセンターである米国・ヨーロッパへはどのくらいのレイテンシーなのか、まず、調べてみましょう。ところで、米国・ヨーロッパといってもかなり広いですよね。リージョンについては、以下のコマンドで確認できます。
heroku regions
heroku_regions.png
うーん。結局、場所は特定できないわけですが、Private Spaces のロケーションなんかをみると、なんとなく、場所が想像できるのではないかなーwという気がします。
ということで、米国リージョンにアプリケーションをデプロイして、pingしてみましょう。ping 元は東京某所です。

C:\Users\admin>ping advent2018.herokuapp.com

us-east-1-a.route.herokuapp.com [34.202.247.40]に ping を送信しています 32 バイトのデータ:
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。

34.202.247.40 の ping 統計:
パケット数: 送信 = 4、受信 = 0、損失 = 4 (100% の損失)、

うーん。pingが帰ってきませんねー。Heroku のロードバランサーは、ICMP は話せないので、ping してもタイムアウトしてしまいます。ということで、TCP でpingできる PsPing (Windows) を使います。

C:\Users\admin>psping advent2018.herokuapp.com:80

PsPing v2.10 - PsPing - ping, latency, bandwidth measurement utility
Copyright (C) 2012-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

TCP connect to 34.192.68.110:80:
5 iterations (warmup 1) ping test:
Connecting to 34.192.68.110:80 (warmup): from 10.0.2.15:50022: 174.76ms
Connecting to 34.192.68.110:80: from 10.0.2.15:50023: 171.98ms
Connecting to 34.192.68.110:80: from 10.0.2.15:50024: 259.04ms
Connecting to 34.192.68.110:80: from 10.0.2.15:50025: 171.05ms
Connecting to 34.192.68.110:80: from 10.0.2.15:50026: 169.55ms

TCP connect statistics for 34.192.68.110:80:
Sent = 4, Received = 4, Lost = 0 (0% loss),
Minimum = 169.55ms, Maximum = 259.04ms, Average = 192.90ms

ということで、5回の ping で平均192.90ミリ秒、つまり、約0.2秒かかるということがわかります。

Heroku Add-on の CDN

CDN の説明は割愛するとして、10年くらい前に CDN というと、費用も高く、大規模サイト向けという感がありましたが、ここ数年は、従量課金な CDN も多数登場し、小規模サイトでも手軽に導入できるようになりました。Heroku でも

の2種類の add-on が提供されています。違い等はそれぞれのウェブページを参照していただくとして、それぞれ、エッジロケーションの確認してみます。

詳細な場所は地図から読み取れないが、どちらも日本にエッジがあるようなので、CDN を活用できれば、その分レイテンシーを短縮できるはずです。

CDN 効果測定

Fastly

C:\Users\admin>psping advent2018-herokuapp-com.global.ssl.fastly.net:80

PsPing v2.10 - PsPing - ping, latency, bandwidth measurement utility
Copyright (C) 2012-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

TCP connect to 151.101.229.194:80:
5 iterations (warmup 1) ping test:
Connecting to 151.101.229.194:80 (warmup): from 10.0.2.15:50089: 6.90ms
Connecting to 151.101.229.194:80: from 10.0.2.15:50090: 4.73ms
Connecting to 151.101.229.194:80: from 10.0.2.15:50091: 4.50ms
Connecting to 151.101.229.194:80: from 10.0.2.15:50092: 3.62ms
Connecting to 151.101.229.194:80: from 10.0.2.15:50093: 3.51ms

TCP connect statistics for 151.101.229.194:80:
Sent = 4, Received = 4, Lost = 0 (0% loss),
Minimum = 3.51ms, Maximum = 4.73ms, Average = 4.09ms

Edge

C:\Users\masam>psping d3aolqo5e8tj6j.cloudfront.net:80

PsPing v2.10 - PsPing - ping, latency, bandwidth measurement utility
Copyright (C) 2012-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

TCP connect to 13.33.174.56:80:
5 iterations (warmup 1) ping test:
Connecting to 13.33.174.56:80 (warmup): from 10.0.2.15:50115: 4.69ms
Connecting to 13.33.174.56:80: from 10.0.2.15:50116: 6.09ms
Connecting to 13.33.174.56:80: from 10.0.2.15:50117: 3.90ms
Connecting to 13.33.174.56:80: from 10.0.2.15:50118: 4.50ms
Connecting to 13.33.174.56:80: from 10.0.2.15:50119: 8.05ms

TCP connect statistics for 13.33.174.56:80:
Sent = 4, Received = 4, Lost = 0 (0% loss),
Minimum = 3.90ms, Maximum = 8.05ms, Average = 5.64ms

Fastly だと平均4.09ミリ秒、Edgeだと平均5.64秒。CDN を使うと桁違い、今回のケースでは、少なくとも30倍以上高速化されることがわかります。使わない手はないですよねー。

CDN 利用時の注意点

キャッシュのコントロール。これがCDNを使いこなす肝と言ってよいでしょう。
CDNはエッジでコンテンツをキャッシュするから高速なレスポンスを実現しているので、キャッシュからコンテンツを送信するのか?それともオリジンから再度コンテンツを読み込むのか?といった、キャッシュのコントロール(=キャッシュ期間の設定)が重要です。キャッシュ期間を長くしすぎてしまうとユーザーに古いコンテンツを表示してしまったりすることがあります。逆に、キャッシュ期間を短くすると、元々のサーバー(=オリジンと呼ばれる事が多い)の負荷が増えますので、適切なキャッシュ期間を考慮します。

キャッシュをコントロールする

保存期間の設定は、httpヘッダのCacheーControlで制御するのがシンプルな方法の1つです。また、Fastlyには、キャッシュをフラッシュ(=削除)するAPIが用意されているので、CMSなどの構築の場合、コンテンツを公開したときに、フラッシュすような仕組みにしておくのも1つの解決方法です。

また、画像などを修正した際には、元々のファイル名でアップロードするのではなく、ファイル名自体を変更して新しくキャッシュさせるという方法もキャッシュコントロールの1つです。その場合、リンク元のHTMLのキャッシュクリアのタイミングを考慮しておく必要もあります。

動的なページでも CDN は有効か?

有効です!!
確かに動的ページの場合、例えば、個人情報を表示・編集するようなページの場合、個人情報は、キャッシュするべきでないので、そういったページでは、CDN 不要の様にも思えますが、共通の画像(アイコン、バナーなど)、スタイルシート、.jsファイルなど、動的に生成されていないファイルも多々あります。こういったファイルはCDNから配信すると、ウェブページ全体の速度の体感は向上するはずです。

デメリットは無いのか?

前述のキャッシュコントロールの必要性は、手間が増えるという点で、CDN利用のデメリットです。それ以外に考えられる、とくに、Heroku ならではのデメリットが1つあります。それは、CDNがトラフィック量による従量課金な点です。Herokuでは、Dynoとクライアント間のデータの送受信、データ転送量での課金はしていません。Heroku が利用しているAWS は、データ転送量で課金しているのにも関わらず、です。つまり、CDNを利用すると、データ転送の費用が、追加で発生するということを覚えておく必要があります。とはいえ、CDNを導入すれば、必要なDyno数の削減になる場合が多く、また、レイテンシー向上のために、Private Spaces の導入も不要になるので、コストメリットは大きいはずです。

Heroku で wkhtmltoimage を使う方法

External article
Browsing Latest Articles All 26 Live