((7回目の出直し🌼))

好きなことを自分のペースで、のんびり更新

GoogleのAPIを実行する2つのプログラムをHerokuで動かしてみよう

先日作ったGoogleのインデックスとサイトマップに関するPHPのプログラムを、Herokuにデプロイして自動化してみます。

個人用のメモ書きの延長なので、フォルダの位置やバージョンなどは必要に応じて適度に読み替えてください。

今回やったこと

この2つの記事で作った2つのプログラムをHerokuに置いて自動実行することです。 両方ともGoogleのインデックスに関するAPIを自動処理するPHPのプログラムです。

kanaxx.hatenablog.jp

kanaxx.hatenablog.jp

使ったもの

  • Heroku Free
  • Heroku CLI
  • Heroku Scheduler
  • PHP Composer

Herokuは、FREEプランで動く範囲でやってます。
f:id:kanaxx43:20200709190555p:plain

Windows10+Cmderのコマンドライン環境で実行しました

Herokuのアカウントとプラン

Herokuのアカウントは無料で作れます。
無料のアカウントにクレジットカードを登録すると無料動作枠が1000時間分になりますが、クレジットカードを登録しないと550時間分です。

今回使うHeroku Schedulerは、クレジットカードの登録済みのアカウントでしか使うことができません。 Heroku Schedulerの動作分も1,000dyno(1,000時間分)の範囲に含まれるので、当面は無料で使えます。(未確認です。8月のBillingで確認予定)

僕は、700円の有料プラン(Hobbyプラン)に乗っけたHeroku Schedulerのほうをメインで使っているのですが、Billingの内容を見ると1か月で$0.07(70円くらい)掛かってます。 f:id:kanaxx43:20200705003231p:plain

契約全体でいうとweb用のdynoと合わせて$7.07です。
f:id:kanaxx43:20200705003223p:plain

Herokuのアカウントはある前提で進めます。ない場合は、新規登録しておいてください。

ここ先インストール作業

ソースコードの準備

必要なものは、ソースコード(PHP)2つ、Googleのサービスアカウントの認証ファイル(JSON)が1つ、gitignoreファイルとHerokuのProcfileの4つです。
https://github.com/kanaxx/hatenablog-indexing

GIT慣れしてない場合は、zipファイルでダウンロードしても大丈夫です。

以下のディレクトリ構成にします。
GITからダウンロードするディレクトリ:C:\tmp\hatena_indexing
Herokuへデプロイするディレクトリ:C:\hatena_heroku

準備作業

作業用のディレクトリへ行き、gitからcloneしてソースを持ってくるまで

GITからコードを持ってくる

まずは、作業ディレクトリへ行きgithubからコードを持ってきます。

λ cd \tmp
λ git clone https://github.com/kanaxx/hatenablog-indexing.git
Cloning into 'hatenablog-indexing'...
remote: Enumerating objects: 45, done.
remote: Counting objects: 100% (45/45), done.
remote: Compressing objects: 100% (43/43), done.
Uremote: Total 45 (delta 23), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (45/45), done.

#確認
λ cd hatenablog-indexing
λ ls -al

#このファイルがあればOK
  .gitignore 
  LICENSE
  Procfile
  credential-sample.json
  publish_sitemap_to_indexing_api.php
  readme.md
  submit_sitemap.php
Herokuにデプロイ用にまとめる

Herokuへデプロイするディレクトリを作り、gitから持ってきたファイルをコピーします。

publish_sitemap_to_indexing_api.php
submit_sitemap.php
Procfile
.gitignore の4つをコピーして、さらに自分のGoogle APIのサービスアカウントの認証用のJSONファイルを置く。

#Heroku用のフォルダ作る
λ mkdir C:\hatena_heroku

#ここを起点
λ cd c:\tmp\hatenablog-indexing\

#ファイルコピー
λ cp publish_sitemap_to_indexing_api.php C:\hatena_heroku\
λ cp submit_sitemap.php C:\hatena_heroku\
λ cp Procfile C:\hatena_heroku\
λ cp .gitignore C:\hatena_heroku\

λ ls -al
total 21
drwxr-xr-x 1 user 197613    0 Jul  5 11:32 ./
drwxr-xr-x 1 user 197613    0 Jul  5 11:20 ../
-rw-r--r-- 1 user 197613   10 Jul  5 11:26 .gitignore
-rw-r--r-- 1 user 197613    44 Jul  5 11:26 Procfile
-rw-r--r-- 1 user 197613 2319 Jul  5 11:26 credential.json
-rw-r--r-- 1 user 197613 3508 Jul  5 11:26 publish_sitemap_to_indexing_api.php
-rw-r--r-- 1 user 197613 3521 Jul  5 11:26 submit_sitemap.php

Google Client Libraryをインストール

#google client libraryをインストール
λ composer require google/apiclient:"^2.0"
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 16 installs, 0 updates, 0 removals
  - Installing ralouphie/getallheaders (3.0.3): Loading from cache
  - Installing psr/http-message (1.0.1): Loading from cache
  - Installing guzzlehttp/psr7 (1.6.1): Loading from cache
  - Installing guzzlehttp/promises (v1.3.1): Loading from cache
  - Installing symfony/polyfill-php72 (v1.17.0): Loading from cache
  - Installing symfony/polyfill-mbstring (v1.17.1): Loading from cache
  - Installing symfony/polyfill-intl-idn (v1.17.1): Loading from cache
  - Installing guzzlehttp/guzzle (6.5.5): Loading from cache
  - Installing phpseclib/phpseclib (2.0.27): Loading from cache
  - Installing psr/log (1.1.3): Loading from cache
  - Installing monolog/monolog (2.1.0): Loading from cache
  - Installing firebase/php-jwt (v5.2.0): Loading from cache
  - Installing google/apiclient-services (v0.139): Loading from cache
  - Installing psr/cache (1.0.1): Loading from cache
  - Installing google/auth (v1.9.0): Loading from cache
  - Installing google/apiclient (v2.5.0): Loading from cache
(省略します)

Writing lock file
Generating autoload files

#この2行が出ればOK

#確認
λ ls -la
total 62
drwxr-xr-x 1 user 197613     0 Jul  5 11:39 ./
drwxr-xr-x 1 user 197613     0 Jul  5 11:34 ../
-rw-r--r-- 1 user 197613    10 Jul  5 11:26 .gitignore
-rw-r--r-- 1 user 197613    44 Jul  5 11:26 Procfile
-rw-r--r-- 1 user 197613    62 Jul  5 11:35 composer.json
-rw-r--r-- 1 user 197613 34030 Jul  5 11:39 composer.lock
-rw-r--r-- 1 user 197613  2319 Jul  5 11:26 credential.json
-rw-r--r-- 1 user 197613  4215 Jul  5 11:26 publish_sitemap_to_indexing_api.php
-rw-r--r-- 1 user 197613  3521 Jul  5 11:26 submit_sitemap.php
drwxr-xr-x 1 user 197613     0 Jul  5 11:39 vendor/

#composer.jsonとcomposer.lockができていて
#vendorのディレクトリができてればOK

Herokuにアプリを作る

PHPをデプロイする先をHerokuに作ります。この作業はブラウザでやります。

アプリの新規作成画面を開く

create new appで新規アプリを作る画面を開き、 f:id:kanaxx43:20200705011659p:plain

アプリ新規作成画面

何も入れずにCreate Appを押す。何も入れなかったら勝手にApp nameを付けてくれる
f:id:kanaxx43:20200705011712p:plain

アプリ作成完了

scenic-saguaro-44740という名前でApplicationが作られました。この名前は都度変わるので自分の名前を憶えておきましょう。 f:id:kanaxx43:20200705104427p:plain

デプロイコマンドの確認

Herokuへのデプロイは、Heroku GITで行います。1、2、3のコマンドを後で使います。 f:id:kanaxx43:20200705105211p:plain

Herokuへデプロイ

やっとHerokuへデプロイします。やることはシンプルです。Heroku Gitのデプロイ手順通りにコマンド打つだけです。

#起点のディレクトリにいき
λ cd C:\hatena_heroku

#まずログイン(ブラウザが立ち上がる)
λ heroku login
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/cli/browser/xxx-xxx-xxx-xxx-xxx
Logging in... done
Logged in as xxx@gmail.com

#作業ディレクトリでgit init
λ git init
Initialized empty Git repository in C:/hatena_heroku/.git/

#作成したappのgitのURLを設定
λ heroku git:remote -a scenic-saguaro-44740
set git remote heroku to https://git.heroku.com/scenic-saguaro-44740.git

#ソースをadd
λ git add .
warning: LF will be replaced by CRLF in composer.json.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in composer.lock.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in credential.json.
The file will have its original line endings in your working directory.

#ソースをコミット
λ git commit -am "first commit"
[master (root-commit) 7240b39] first commit
 6 files changed, 1210 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 composer.json
 create mode 100644 composer.lock
 create mode 100644 credential.json
 create mode 100644 publish_sitemap_to_indexing_api.php
 create mode 100644 submit_sitemap.php

#コミットしたファイルをデプロイ!
λ  git push heroku master
Counting objects: 8, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 9.33 KiB | 2.33 MiB/s, done.
Total 8 (delta 1), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> PHP app detected
remote: -----> Bootstrapping...
remote: -----> Installing platform packages...
remote:        NOTICE: No runtime required in composer.json; requirements
remote:        from dependencies in composer.lock will be used for selection
remote:        - php (7.4.7)
remote:        - apache (2.4.43)
remote:        - nginx (1.18.0)
remote: -----> Installing dependencies...
remote:        Composer version 1.10.7 2020-06-03 10:03:56
remote:        Loading composer repositories with package information
remote:        Installing dependencies from lock file
remote:        Package operations: 16 installs, 0 updates, 0 removals
remote:          - Installing phpseclib/phpseclib (2.0.27): Downloading (100%)
remote:          - Installing psr/log (1.1.3): Downloading (100%)
remote:          - Installing monolog/monolog (2.1.0): Downloading (100%)
remote:          - Installing ralouphie/getallheaders (3.0.3): Downloading (100%)
remote:          - Installing psr/http-message (1.0.1): Downloading (100%)
remote:          - Installing guzzlehttp/psr7 (1.6.1): Downloading (100%)
remote:          - Installing symfony/polyfill-php72 (v1.17.0): Downloading (100%)
remote:          - Installing symfony/polyfill-mbstring (v1.17.1): Downloading (100%)
remote:          - Installing symfony/polyfill-intl-idn (v1.17.1): Downloading (100%)
remote:          - Installing guzzlehttp/promises (v1.3.1): Downloading (100%)
remote:          - Installing guzzlehttp/guzzle (6.5.5): Downloading (100%)
remote:          - Installing psr/cache (1.0.1): Downloading (100%)
remote:          - Installing firebase/php-jwt (v5.2.0): Downloading (100%)
remote:          - Installing google/auth (v1.9.0): Downloading (100%)
remote:          - Installing google/apiclient-services (v0.139): Downloading (100%)
remote:          - Installing google/apiclient (v2.5.0): Downloading (100%)
remote:        Generating optimized autoload files
remote: -----> Preparing runtime environment...
remote:        NOTICE: No Procfile, using 'web: heroku-php-apache2'.
remote: -----> Checking for additional extensions to install...
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 17.5M
remote: -----> Launching...
remote:        Released v3
remote:        https://scenic-saguaro-44740.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/scenic-saguaro-44740.git
 * [new branch]      master -> master

##ここまでくれば完了です。

簡単ですね

デプロイの確認

デプロイしたものをが動くのか確認します。 heroku run bashでコマンドラインで作業します。

#Herokuのbash起動
λ heroku run bash

#PHPのバージョン確認
~ $ php -v
PHP 7.4.7 (cli) (built: Jun 18 2020 13:24:00) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.7, Copyright (c), by Zend Technologies

##sitemap apiの動作確認 途中でCTRL+Cで止めてOK
~ $ php submit_sitemap.php "https://kanaxx.hatenablog.jp/sitemap_index.xml"
-getting XML >> https://kanaxx.hatenablog.jp/sitemap_index.xml
 got 8 entries.
 sitemap URL :https://kanaxx.hatenablog.jp/sitemap_common.xml
 sitemap URL :https://kanaxx.hatenablog.jp/sitemap_periodical.xml?year=2020&month=7
(省略)

##indexing apiの動作確認 途中でCTRL+Cで止めてOK
~ $ php publish_sitemap_to_indexing_api.php   "https://kanaxx.hatenablog.jp/sitemap_index.xml"
-getting XML >> https://kanaxx.hatenablog.jp/sitemap_index.xml
 got 8 entries.
 sitemap URL :https://kanaxx.hatenablog.jp/sitemap_common.xml
 sitemap URL :https://kanaxx.hatenablog.jp/sitemap_periodical.xml?year=2020&month=7
(省略)

##heroku bashを抜ける
~ $ exit

(重要)ウェブから参照できないことの確認

今回のアプリはスケジューラで動くバッチプログラムです。ブラウザで参照する必要がないので、閲覧できないように対策しておきます。

特に、credential.jsonのファイルがウェブから参照できてしまうと、何が起きるか分かりませんので確認しておいてください。
http://scenic-saguaro-44740.herokuapp.com/credential.json

対策1 Heroku Procfile

GitにあげてあるProcfileで、webのrootディレクトリを/publicに変更してあります。手順通りにやっていれば/publicより上のディレクトリはインターネットから見えないはずです。

対策2 Webのプロセスを止める

Webを使わないのであれば止めておくのが一番安全です。アプリケーションのOverviewDyno formationで止めます。 3で右に倒れている(ONの状態の)スイッチを左に倒しOFFにし、「confirm」を押し、OverviewでwebがOFFになっていることを確認しておきます。 f:id:kanaxx43:20200705193434p:plain

止めたあとにブラウザでアクセスするとApplication Errorの画面が表示されるようになります。見えないのが期待値なので、エラーになるのは気にしなくていいです。
f:id:kanaxx43:20200705163849p:plain

ログファイルには、このようなエラーメッセージが出ます。No web process runnningで503ステータスです。

2020-07-05T07:16:41.243668+00:00 
 heroku[router]: at=error code=H14 
 desc="No web processes running" 
 method=GET path="/" host=scenic-saguaro-44740.herokuapp.com 
 request_id=b11a0b60-6ba1-4a1c-8793-818e0a6c03df 
 fwd="122.26.3.129" 
 dyno= connect= service= status=503 bytes= protocol=http

Heroku Schedulerのセットアップ

最後に、Herokuのスケジューラを設定して自動実行を仕掛けます。

Heroku Scheduler Add-onを追加する

Add-onの設定画面へ

アプリのOverviewから、Configure Add-onをクリックする。
f:id:kanaxx43:20200705130959p:plain

Add-onの検索

"schedule"と入力して、Heroku Schedulerを選択 f:id:kanaxx43:20200705131002p:plain

Provisionボタンを押す
f:id:kanaxx43:20200705131006p:plain

Heroku Schedulerにジョブを追加する

ジョブ設定画面へ

Heroku Schedulerの設定画面を開き f:id:kanaxx43:20200705131010p:plain

Create Jobを押す f:id:kanaxx43:20200705131014p:plain

この画面が開くので、2回作業をして2つのジョブを追加します。 f:id:kanaxx43:20200705131017p:plain

sitemap api

Google Search Console API Sitemap は実行回数に制限がないので、Every Hour at で指定しました。1時間に1回、全てのサイトマップをGoogleにPushします。

f:id:kanaxx43:20200705150812p:plain

Commandには、以下をコピペします。
サイトマップのURLは自分のものに書き換えます。
php submit_sitemap.php "https://kanaxx.hatenablog.jp/sitemap_index.xml"

indexing API

Google Indexing APIは1日あたり200回までの制約があるので、Every day atでスケジュール設定をしました。
1日1回、指定の時間で更新のあった記事URLを上位200件、GoogleにPushします。時間の指定はUTC(世界標準時間)での設定です。日本時間ではないので、設定した時間まで待っても動かないと慌てないように。

f:id:kanaxx43:20200705150835p:plain

Commandには、以下をコピペします。
サイトマップのURLは自分のものに書き換えます。
php publish_sitemap_to_indexing_api.php "https://kanaxx.hatenablog.jp/sitemap_index.xml"

2つのジョブ定義が終わったら、こんな状態になるはずです。
f:id:kanaxx43:20200705151156p:plain

これで全ての作業が完了です。
今後は、日々何もしなくてもHerokuに乗ってるプログラムが自動的に動き、個別サイトマップのURL記事ページURLをAPIに投げて、クローラーを呼び込むことができます。

まとめ

PHPのバッチプログラムをHerokuにデプロイする作業をやりました。ここまでやれば、サイトマップとGoogleのインデックス(キャッシュ)に悩まされることはないと思います。

この行為がGoogleに好かれるのか、嫌われるのかは分かりません。参考にしてもよいですが全てに関して自己責任で実施してください。ペナルティに関する責任は負えません。

参考にした資料

特になし