分割されたログを結合する方法

前回までのまとめ

前回、dockerのログが16kで分割されてしまう原因がdockerのログドライバの制限のためだったというところまで記載しました。

今回は分割されたログをどのようにして結合したかを記載したいと思います。

そういえば、分割されるとなぜ困るのかを記載してなかったかもしれません。なぜ困るかというと、ログはJSONで、分割されると妥当なJSONではなくなってしまうからです…

結合する方法

試してみた方法を2つ紹介します。

lambdaで結合する

最初はKinesis Data Firehoseで設定したLambdaで結合しようと試みました。

前回に少し紹介した、ログに含まれる分割されたかどうかを示す情報を元に、結合する場合は改行コードを追加せず、JSONの終端の場合は改行を追加するようにしました。

Lambdaはこんな感じになりました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
exports.handler = async (event, context) => {
/* Process the list of records and transform them */
//console.log(JSON.stringify(event, null, 2));
const output = event.records.map((record) => {
const payload = Buffer.from(record.data, 'base64').toString('ascii');
const payload_json = JSON.parse(payload);
let d = payload_json["log"];
if (add_line_feed(payload_json) === true) {
d = `${d}\n`;
}
const buf = Buffer.from(d);

/* This transformation is the "identity" transformation, the data is left intact */
return {
recordId: record.recordId
result: 'Ok',
data: buf.toString('base64')
}
});
console.log(`Processing completed. Successful records ${output.length}.`);
return { records: output };
};

function add_line_feed(obj) {
if (obj.hasOwnProperty("partial_message") === false) {
return true;
}
if (obj.hasOwnProperty("partial_message") === true && obj["partial_last"] === "true") {
return true;
}
return false;
}

改行を付与する(=結合するかどうか)条件は関数にまとめてみました。このように行うことで、ログは適切に結合されました。

Lambdaで結語することの問題点

無事ログを結合することができたのですが、Kinesisでバッファリングしたデータを出力するタイミングが必ずしもログを結合したあととは限りません。

ですので、なにが起こるのかというと、S3に保存されるファイルは、約1/2の確率で、分割されたログで終わってしまっているのです。

これでは解決になっていません。Kinesisに渡される前に分割されたデータを結合しないといけないということがわかりました。

代替案の検討

Kinesisに渡される前となると、FireLensで出力されたときには結合されていないといけません。つまり、FireLensで結合しないといけないということになります。

FireLensは、以下のクラスメソッドさんの記事を参考に設定しました。

https://dev.classmethod.jp/articles/ecs-firelens/

ここでは、FireLensのコンテナイメージとして、AWSが提供するaws-for-fluent-bit:latestを利用しています。

しかし、fluent-bitにはログを結合するプラグインはこの記載時点では存在していませんでした。fluentdにはログ結合のためのプラグインが存在していました。

よって、fluentdを使ってログの結合を行おうと思います。

fluentdで結合

fluentdで受け取ったログを結合するにはconcatプラグインを利用します。また、Kinesis Data Firehoseと接続するためにkinesis接続用プラグインも利用します。

concatプラグインはこちら

https://github.com/fluent-plugins-nursery/fluent-plugin-concat/

Kinesisのプラグインはこちら

https://github.com/awslabs/aws-fluent-plugin-kinesis

fluentdのイメージ

ではまずfluentdでログを結合するためにfluentdのベースイメージを探そうと思います。fluent-bitはAWS推奨のイメージがありましたが、fluentdにはないようです。ですので、公式のイメージをベースイメージとしました。

Dockerfileは以下になります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FROM fluent/fluentd:v1.9.1-1.0

USER root

RUN apk add --no-cache --update --virtual .build-deps \
sudo build-base ruby-dev \
# cutomize following instruction as you wish
&& sudo gem install fluent-plugin-concat \
&& sudo gem install fluent-plugin-kinesis \
&& sudo gem sources --clear-all \
&& apk del .build-deps \
&& rm -rf /home/fluent/.gem/ruby/2.5.0/cache/*.gem

COPY fluent.conf /fluentd/etc/fluent-custom.conf
COPY entrypoint.sh /bin/
RUN chmod +x /bin/entrypoint.sh

USER fluent

1箇所、不思議な点があります。

1
COPY fluent.conf /fluentd/etc/fluent-custom.conf

こちらですが、fluent.confではなくfluent-custom.confとしています。なぜかというと、fluent.confはECS FireLensで自動的に上書きされてしまうため、ファイル名を変更してfluentdのホスト内に置いておきます。

fluent-custom.confの内容は以下になります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<filter firelens**>
@type concat
key log
stream_identity_key partial_id
multiline_start_regexp /{"JSONの先頭":/
multiline_end_regexp /"JSONの終点"}$/
separator ""
timeout_label @TIMEOUT
</filter>

<label @TIMEOUT>
<match **>
@type kinesis_firehose
delivery_stream_name kinesis-data-stream
region ap-northeast-1
</match>
</label>

<label @TIMEOUT>については、また次回紹介します。

プラグインの設定のみ行なっています。sourceディレクティブを入れると、

1
unexpected error error_class=Errno::EADDRINUSE error="Address in use - bind(2) for 127.0.0.1:24224"

と表示されてエラーになってしまいます。この辺りはECSが自動的に設定してくれるので、必要最小限の設定で動作します。

こちらでビルドし、ECRにpushします。

タスク定義ファイルの修正

ECSのタスク定義ファイルを変更します。以前はfluent-bitを利用していたので、fluentdに変更する必要があります。

イメージの変更

まずはイメージを変更します。

1
2
3
4
5
6
7
8
9
     {
"name": "log-router",
- "image": "906394416424.dkr.ecr.ap-northeast-1.amazonaws.com/aws-for-fluent-bit:latest",
+ "image": "xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/fluentd-for-docker-log:1.0.0",
"essential": true,
"firelensConfiguration": {
- "type": "fluentbit"
+ "type": "fluentd"
},

ここで一旦デプロイしてみましたが、エラーが発生しました。

1
Unable to generate firelens config file: unable to generate firelens config: unable to apply log options of container ap to firelens config: missing output key @type which is required for firelens configuration of type fluentd

ログ出力の設定をfluent-bit形式からfluentd形式に変える必要があります。

FireLensをログドライバとして指定するアプリケーションのログの設定を以下のように変更します。

1
2
3
4
5
6
7
8
"logConfiguration": {
"logDriver": "awsfirelens",
"options": {
"@type": "kinesis_firehose",
"region": "ap-northeast-1",
"delivery_stream_name": "kinesis-data-stream"
}
},

fluent-bitの場合は"Name": "firehose""delivery_stream": "kinesis-data-stream"でしたが、fluentdの場合は上記のように設定する必要があります。この辺りのfluent-bitとfluentdの違いについてはタスク定義ファイルで吸収してくれるとありがたいのですが、そうではないようです。

この辺りの設定は以下のページを参考にしました。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/using_firelens.html

最後にgithub actionsでデプロイして無事ログが結合された状態でKinesis Data Firehoseに渡ることが確認できました。S3上でも分割されていないことが確認できました。

まとめ

fluent-bitにはconcatプラグインがなかったのと、AWS推奨のfluentdイメージがなかったので、fluentd公式のイメージをベースにイメージをビルドしました。

タスク定義ファイルでもfluent-bitとfluentdの違いに少し戸惑ったのと、ECSならではの自動化された設定をこちらで準備してはいけないということころで、少しハマりました。

次回はflunet.confにあるTIMEOUTラベルについて記載したいと思います。

Dockerのログが16Kで分割されてしまう制限について

背景

ブラウザからデータを受け取り、それをS3に保存するアプリケーションの構築をAWS ECS Fargateで行いました。

フロントはnginx + nodejsを利用しています。フロントはブラウザから受けとったデータを加工して標準出力に出力するだけの役割です。

データはログルーターのFireLensを経由して、Kinesis Data Firehoseに送られ、LambdaをS3に保存するようにしました。

構成は上記の画像のようになります。

実際にデータを送ってみると、S3に保存された1つのJSONが途中で分割され2行になってしまっていました。

原因の調査

Lambdaでの調査

Kinesis Data Firehoseから起動しているLambdaでは、FireLensから送られてくるデータの必要な箇所(logというキーで取得できるログ本体)のみを取得し、改行をつけるだけの処理を行なっていました。(Kinesisからのデータなので、Base64デコードエンコードは行なっています)

なぜ分割されるのかがわからないのですが、なにか法則性がないかを調査したところ、分割されたデータの前半の長さは必ず16384バイト(16K)ということがわかりました。

しかも、Kinesis Data Firehoseに送られてくるデータには、データ本体のlog以外にも、partial_idpartial_messagepartial_lastなどのキーが含まれていました。

つまり、Kinesis Data Firehoseに入ってくる前にデータは分割されていたということです。

コンテナの調査

ECS Fargateで出力したデータを調査しました。nodejsアプリケーションから出力するデータをCLoudWatchで見てみると、その段階ですでに分割されていました。

ということはFireLensが原因ではないようです。

原因はDockerのロギングドライバの制限

調査の結果、原因はDockerロギングドライバの制限でした。1行あたり16Kが上限になっていて、現時点では変更できないようです。

https://github.com/moby/moby/issues/32923

まとめと次回予告

Dockerのロギングドライバの制限によってデータが16Kを超えると分割されてしまうということがわかりました。調べても意外と載っていないので、原因がわかるまで時間がかかりました。

次回はこの問題についてどう対応したかを記載したいと思います。

hexoアプリケーションの設定

前回までのまとめ

前回、新しいhexoアプリケーションのドメインの設定、nginxの設定、let’s EncryptでのSSLの設定を行いました。

今回は、既存のhexoのバージョンアップを行う予定でしたが、既存と新規のhexoは完全に独立しているので、既存のhexoはそのままでも大丈夫そうです。

なので今回は、hexoをsystemdを使って起動するようにするのと、hexoの細かな設定を行って、サイトが常時表示されるようにしようと思います。

systemdの設定

以前、systemdの設定でハマったことを書きました。これを参考に進めていきます。メモしておくと便利ですね!

unitファイルの追加

以前作成したファイルを少し変更すれば利用できそうです。ファイルをコピーします。

1
$ sudo cp /etc/systemd/system/hexo.service /etc/systemd/system/business_book_reviews_hexo.service

WorkingDirectoryなどを変更します。変更した結果は以下です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ diff -u /etc/systemd/system/hexo.service /etc/systemd/system/business_book_reviews_hexo.service
--- /etc/systemd/system/hexo.service 2020-05-07 01:21:21.271546129 +0900
+++ /etc/systemd/system/business_book_reviews_hexo.service 2020-12-11 01:12:18.544145188 +0900
@@ -1,11 +1,11 @@
[Unit]
-Description=hexo
+Description=business_book_reviews_hexo
After=syslog.target network.target

[Service]
Type=simple
-ExecStart=/usr/bin/sudo /home/ec2-user/.anyenv/envs/nodenv/shims/hexo server -p 8080
-WorkingDirectory=/home/ec2-user/blog
+ExecStart=/usr/bin/sudo /home/ec2-user/.anyenv/envs/nodenv/shims/npx hexo server -p 8081
+WorkingDirectory=/home/ec2-user/business-book-reviews
StandardOutput=syslog
StandardError=syslog
KillMode=process

systemdの登録確認

unitファイルが追加されたか確認します。

1
2
3
$ sudo systemctl list-unit-files --type=service | grep hexo
business_book_reviews_hexo.service disabled
hexo.service enabled

systemdで起動する

今はdisableになっているのでenableにします

1
2
$ sudo systemctl enable business_book_reviews_hexo
Created symlink from /etc/systemd/system/multi-user.target.wants/business_book_reviews_hexo.service to /etc/systemd/system/business_book_reviews_hexo.service.

起動します

1
$ sudo systemctl start business_book_reviews_hexo

プロセスを確認します

1
2
3
$ ps -ef | grep npx
root 10987 1 0 01:17 ? 00:00:00 /usr/bin/sudo /home/ec2-user/.anyenv/envs/nodenv/shims/npx hexo server -p 8081
ec2-user 11034 10660 0 01:17 pts/0 00:00:00 grep --color=auto npx

大丈夫そうですね。画面を確認します。

hexo初期設定起動確認

大丈夫そうですね!

hexoの設定

サイトの設定

アプリケーションをbusiness.book-reviews.blogにします。_config.ymlを編集します。

差分は以下になります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 # Site
-title: Hexo
-subtitle: ''
+title: business.book-reviews.blog
+subtitle: ビジネス書の読書ブログ
description: ''
keywords:
-author: John Doe
-language: en
-timezone: ''
+ - ビジネス書
+ - 書評
+author: Motoaki Shibagaki
+language: ja
+timezone: Asia/Tokyo

subtitlekeywordsも設定しましたが、TOPページには反映されないようです。

URL設定

以前、URLから日付を削除するという記事を書きました。それと同じ対応を行います。

編集した結果は以下です。

1
2
3
4
5
-url: http://example.com
+url: https://business.book-reviews.blog
root: /
-permalink: :year/:month/:day/:title/
+permalink: :title/

動作確認

再起動して動作確認を行います。まず再起動します。

1
$ sudo systemctl restart business_book_reviews_hexo

サンプル記事をクリックして表示します。

サンプル記事の表示

いい感じですね!

まとめ

systemdの設定を行い、常時起動するようにしました。また、hexoの最低限の設定を行いました。

次回は記事の引っ越しを行いたいと思います。Google Search ConsoleでURLの削除、GAの設定なども行いたいと思います。

hexoアプリケーションのWebサーバ・SSLの設定

前回までのまとめ

前回、hexoアプリケーションのテーマを決めました。今回は細かい設定とサーバー側の設定を行っていきます。

ドメインの設定

リクエストを受け付けるサブドメインを作成します。一旦、business.book-reviews.blogとします。サブドメインの設定は契約しているバリュードメインの管理画面で行います。

久々見ると忘れてしまっていて、どこからDNS設定を行っていいかわかりません…しばらく探したあと、左メニューのドメインをクリックするとページが遷移します(フォーカスをあてた後のメニューではありません)。その中にドメインの設定操作があり、その中にDNSレコード/URL転送の設定があります。対象のドメインを選択すると、大きなテキストボックスがあり、その中にDNSレコードを入力します。

現状、

1
a * 18.182.54.190

となっているため、どのサブドメインでもアクセスできます。これを機に限定して設定します。

1
2
a book-reviews.blog. 18.182.54.190
a business.book-reviews.blog. 18.182.54.190

TTLが切れた後にdigコマンドで確認します。

1
2
3
4
5
6
7
8
$ dig book-reviews.blog a
(省略)
;; QUESTION SECTION:
;book-reviews.blog. IN A

;; ANSWER SECTION:
book-reviews.blog. 113 IN A 18.182.54.190
(省略)

ちゃんと名前は引けています。新しく追加したドメインも確認します。

1
2
3
4
5
6
7
8
$ dig business.book-reviews.blog a
(省略)
;; QUESTION SECTION:
;business.book-reviews.blog. IN A

;; ANSWER SECTION:
business.book-reviews.blog. 152 IN A 18.182.54.190
(省略)

大丈夫そうですね。念のため、設定していないドメインで名前が引けないことも確認しておきます。

1
2
3
4
5
6
7
8
$ dig test.book-reviews.blog a
(省略)
;; QUESTION SECTION:
;test.book-reviews.blog. IN A

;; AUTHORITY SECTION:
book-reviews.blog. 120 IN SOA ns1.value-domain.com. hostmaster.book-reviews.blog. 2020120716 3600 900 604800 120
(省略)

名前が引けないことを確認しました。

これでドメインの設定は完了です。

nginxの設定

次にnginxの設定を行います。
最低限の設定のみ行います。

1
2
3
4
5
6
7
server {
server_name business.book-reviews.blog;

location / {
proxy_pass http://localhost:8081/;
}
}

設定を繁栄します。

1
$ sudo systemctl reload nginx

反映されたことを確認します。ブラウザでhttp://business.book-reviews.blogにアクセスして、502 BadGatewayがかえってくることを確認します。

確認できたので、次はSSLの設定を行います。

SSLの設定

以前let’s encryptの導入を行ったページを参考に設定を行っていきます。

インストールはされているので、CertBotの実行から行います。

1
2
3
4
5
6
7
8
9
10
11
$ sudo certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: book-reviews.blog
2: business.book-reviews.blog
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 2

今回はドメインが2つあるので、選択肢が2つ出てきます。2を選んで実行します。

1
2
Congratulations! You have successfully enabled
https://business.book-reviews.blog

無事HTTPSが有効になりました。

nginxの設定で、proxy_set_headerがまるっと抜けていたので追記してリロードします。

追記した内容

1
2
3
4
5
proxy_set_header    Host    $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

ブラウザでhttps://business.book-reviews.blogにアクセスし、同じように502 BadRequestが返ってくることが確認できました。

まとめ

新しいhexoアプリケーションのWebサーバ、SSLの設定を行いました。

次回は、新しくインストールするhexoアプリケーションと既存のhexoアプリケーションのバージョンの差が機になるので、既存のhexoのバージョンアップを行いたいと思います。

docker-composeで複数のRailsローカル開発環境を作成する

背景

今は一つのRailsローカル開発環境を使って開発を行なっています。ところが、別のRailsアプリケーションの開発を行うことになりました。なので、もう一つのRailsローカル開発環境を作成する必要が出てしまいました…そのときの作成メモを記載します。

ローカル開発環境の構成

既存の開発環境は以下の2つの要素でできています

  • docker-compose
  • docker-sync

それぞれ、なぜ利用するかなど確認してきましょう。

コンテナ間通信

RailsアプリケーションはRailsが動作するアプリケーションコンテナとMySQLが動作するDBコンテナが協調して動作することで成り立ちます。

複数のコンテナを通信させる場合、2つの方法があります。一つは--linkオプションを使う方法、もう一つはdockerネットワークを利用する方法です。

–linkオプションを利用する方法

詳しくはこちらに記載があります。このサイトによると、--linkオプションはレガシー機能で、将来的に削除される可能性があるということです。

dockerネットワークを利用する方法

dockerネットワークを利用する方法もこちらに記載されています。ネットワークを作ることで、コンテナ同士がコンテナ名で通信が行えるようになります。

dockerネットワークの作成を個別で行なってもよいですが、もっと便利な方法があります。docker-composeを利用することです。

docker-compose

docker-composeについてもさくらのページに説明があります。

docker-composeはdocker-compose.ymlというファイルに構成を記載します。YAMLの最初にバージョン番号を記載するのですが、今のバージョンはいくつなんだろうと思って調べてみると、以下のページが見つかりました。

https://docs.docker.com/compose/compose-file/compose-versioning/

マイナーバージョンもあったんですね…知りませんでした。既存で使っているdocker-composeのversionは3です。

docker-sync

ローカル開発環境を構成するもう一つの要素はdocker-syncです。

docker-syncを使う理由

docker-syncを使う理由としては、すでに詳しい記事がいくつかあります

docker-syncでホスト-コンテナ間を爆速で同期する

上記の記事の中に、docker-sync以外の方法も記載されていました

Docker for Mac の Mutagen-based caching で Volume のパフォーマンスが劇的に改善した

現状ですと、docker-sync以外にvolumeのパフォーマンスを改善する方法がないようです。それがdocker-syncを使う理由だと思います。

docker-syncの仕組み

仕組みについても先ほどの記事に記載がありました。

docker-syncの仕組みとしては、 docker の -v で直接ホスト側のディレクトリをマウントするのではなく、rsyncやunisonの仕組みでホスト側のファイルをコンテナ側に転送しよう、というものです。

なるほど、ファイル転送専用のコンテナを準備して同期を取るということですね。

設定に関しては、docker-sync.ymlで行います。

既存のローカル開発環境の設定

既存のアプリケーションの設定ファイルを確認します

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
version: '3'

services:
db:
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- '3306:3306'
volumes:
- mysql:/var/lib/mysql
- ./docker/mysql/conf.d:/etc/mysql/conf.d
- ./docker/mysql/init:/docker-entrypoint-initdb.d

web:
build:
context: .
dockerfile: ./docker/rails/Dockerfile
command: ['rails', 's', '-p', '3000', '-b', '0.0.0.0']
ports:
- "3000:3000"
volumes:
- rails-sync-volume:/var/www/html:nocopy
- bundle:/usr/local/bundle
tmpfs:
- /var/www/html/tmp/pids
links:
- db
tty: true
stdin_open: true

volumes:
bundle:
driver: local
mysql:
driver: local
rails-sync-volume:
external: true

docker-sync.yml

1
2
3
4
5
6
7
8
9
10
version: '2'

syncs:
rails-sync-volume:
src: './'
sync_strategy: 'unison'
sync_excludes:
- '.docker-sync'
- '.git'
- '.gitignore'

新しいローカル開発環境の作成

既存設定ファイルのコピー

まずは新しいアプリケーションのルートディレクトリに、docker-compose.ymldocker-sync.ymlをコピーします。

1
2
$ cp app_A/docker-compose.yml app_B/docker-compose.yml
$ cp app_A/docker-sync.yml app_B/docker-sync.yml

docker-sync.ymlの編集

app_Bの方のdocker-sync.ymlを修正します。このままだと名前が被ってしまうので、名前を修正します。

1
2
3
4
5
6
7
8
9
10
version: '2'

syncs:
app_B-sync-volume:
src: './'
sync_strategy: 'unison'
sync_excludes:
- '.docker-sync'
- '.git'
- '.gitignore'

docker-syncの起動

編集したので起動してみます。

1
2
3
4
5
6
$ docker-sync start
ok Starting unison for sync app_B-sync-volume
ok Synced /Users/user/github/app_B/
success Unison server started
ok Synced /Users/user/github/app_B/
success Starting Docker-Sync in the background

コンテナを確認します。

1
2
3
$ docker ps
f98368a0a9e5 eugenmayer/unison:2.51.2.2 "/entrypoint.sh supe…" 28 hours ago Up About a minute 127.0.0.1:32771->5000/tcp app_B-sync-volume
129681851c64 eugenmayer/unison:2.51.2.2 "/entrypoint.sh supe…" 5 weeks ago Up 29 hours 127.0.0.1:32770->5000/tcp rails-sync-volume

無事起動できています。

docker-composeを試しに起動してみる

次はdocker-composeです。コピーした設定のままで一旦起動してみます。

1
2
3
4
$ docker-compose up
(省略)
Bind for 0.0.0.0:3306 failed: port is already allocated
(省略)

3306ポートは既存の開発環境が利用しているということで、エラーになってしまいました。
ポートの調整が必要ですね。

dockerのポート番号の調整を行う

ホスト側に公開するポートを3307に変更します

1
2
3
4
5
6
db:
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- '3307:3306'

これで再度試します。

1
2
3
4
$ docker-compose up
(省略)
Bind for 0.0.0.0:3000 failed: port is already allocated
(省略)

ある意味予想通りですが、Railsのポートも重複しているので、3001に変更します

1
2
3
4
5
6
7
web:
build:
context: .
dockerfile: ./docker/rails/Dockerfile
command: ['rails', 's', '-p', '3000', '-b', '0.0.0.0']
ports:
- "3001:3000"

これでもう一度試します。

1
2
3
4
5
$ docker-compose up
(省略)
caecf6ab0866_app_B_web_1 | * Environment: development
caecf6ab0866_app_B_web_1 | * Listening on tcp://0.0.0.0:3000
caecf6ab0866_app_B_web_1 | Use Ctrl-C to stop

無事起動しました!

Rails側の調整

MySQLのポート番号を修正しているので、config/database.ymlport: 3307を追記してコンテナを再起動します。

動作確認

http://localhost:3001 にアクセスします。すると、エラーが表示されました…

Can't connect to MySQL server on 'db' (111)

dbへの接続ができていないようです…

コンテナ間通信時のポート指定

原因調査のためドキュメントを調べていると、以下のページが見つかりました。

https://matsuand.github.io/docs.docker.jp.onthefly/compose/networking/

ネットワークにより接続されているサービス間の通信は CONTAINER_PORT を利用します。

ということは、docker-compose.ymlでのポート指定が3307:3306なので、Railsアプリケーションのコンテナからは3306でアクセスすればよいということですね。config/database.ymlの修正は必要がなかったということです。

config/database.ymlport: 3307を削除したら、無事動作確認できました。

まとめ

今回新しくRailsアプリケーション開発環境を作成しました。既存の設定ファイルをコピーして少し編集しただけですが、docker-sync, docker-composeの理解が進んだと思います。

次回は新しいhexoのアプリケーション設定を行いたいと思います。

rails consoleでpathヘルパーを利用する

背景

_pathヘルパーで疑問が発生しました。qというクエリパラメータがnilだった場合、?q=となるのか、クエリパラメータなしになるのかが気になりました。

わざわざローカルでrails serverをせず確認する方法はないのかな?と思ってググってみました。

rails consoleでpathヘルパーの実験

appというオブジェクトを利用すると呼び出せるよと書かれていたので、早速試してみます

1
2
3
4
5
6
7
$ rails c
[1] pry(main)> app.login_path
=> "/login"
[2] pry(main)> app.login_path q: nil
=> "/login"
[3] pry(main)> app.login_path q: 'abc'
=> "/login?q=abc"

ということで、クエリパラメータの値がnilの場合はクエリパラメータなしになるようでした。

最初に思った?q=になる場合は、q: ''でした。

appというオブジェクトはなにか?

appというオブジェクトはなにでしょうか?試してみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[1] pry(main)> app.class
=> ActionDispatch::Integration::Session
[2] pry(main)> ActionDispatch::Integration::Session.ancestors
=> [ActionDispatch::Integration::Session,
ActionDispatch::Routing::UrlFor,
ActionDispatch::Routing::PolymorphicRoutes,
ActionController::ModelNaming,
ActionDispatch::TestProcess,
ActionDispatch::Integration::RequestHelpers,
ActionDispatch::Assertions,
ActionDispatch::Assertions::RoutingAssertions,
ActionDispatch::Assertions::ResponseAssertions,
Rails::Dom::Testing::Assertions,
Rails::Dom::Testing::Assertions::TagAssertions,
Rails::Dom::Testing::Assertions::SelectorAssertions,
Rails::Dom::Testing::Assertions::SelectorAssertions::CountDescribable,
Rails::Dom::Testing::Assertions::DomAssertions,
Minitest::Assertions,
Object,
PP::ObjectMixin,
Delayed::MessageSending,
V8::Conversion::Object,
ActiveSupport::Dependencies::Loadable,
JSON::Ext::Generator::GeneratorMethods::Object,
Kernel,
BasicObject]

ancestorsのところは、バージョンによって異なるかもしれません。

これだけみてもわからないので、他の利用方法も見てみます。

app.getでリクエストを送る

app.getにパスを引数で渡すと、実際にリクエストを送ることができます

1
2
3
4
5
6
7
[1] pry(main)> app.get '/login'
Started GET "/login" for 127.0.0.1 at 2020-12-02 23:24:26 +0900
ActiveRecord::SchemaMigration Load (2.0ms) SELECT `schema_migrations`.* FROM `schema_migrations`
Processing by Users::SessionsController#new as HTML
(省略)
Completed 200 OK in 7125ms (Views: 7095.9ms | ActiveRecord: 11.5ms)
=> 200

なるほど、便利ですね!

ドキュメントにあるように、requestresponsecontrollerなどのメソッドもあり、最後のリクエストのそれぞれが取得できるようです。

まとめ

Railsは長い間使ってきましたが、まだまだ知らないことがいっぱいありそうです。

これからもなにか見つけたら紹介していきたいと思います。

hexoのテーマを決定する

前回までのまとめ

前回、hexoアプリケーションのテーマを選んで良さそうなものを利用しようとしたらうまく動かなかったところで終わりました。

今回は各ディレクトリの_config.ymlについて調べていきたいと思います。

テーマごとの_config.ymlの違いについて

デフォルトのテーマであるlandscapeは、theme/landscapeにある_config.ymlでテーマに依存した設定を行っていました。アプリケーションとしてはそうあるべきだと思います。

見た目が気に入って利用しようとしたhexo-theme-aomoriはアプリケーション直下の_config.ymlに設定してくれと書いてありました。違いは一体なんでしょうか。

hexo config

configを出力するコマンドnpx hexo configを試してみましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
$ npx hexo config
INFO Validating config
{
title: 'Hexo',
subtitle: '',
description: '',
author: 'John Doe',
language: 'en',
timezone: '',
url: 'http://example.com',
root: '/',
permalink: ':year/:month/:day/:title/',
permalink_defaults: null,
pretty_urls: { trailing_index: true, trailing_html: true },
source_dir: 'source',
public_dir: 'public',
tag_dir: 'tags',
archive_dir: 'archives',
category_dir: 'categories',
code_dir: 'downloads/code',
i18n_dir: ':lang',
skip_render: null,
new_post_name: ':title.md',
default_layout: 'post',
titlecase: false,
external_link: { enable: true, field: 'site', exclude: '' },
filename_case: 0,
render_drafts: false,
post_asset_folder: false,
relative_link: false,
future: true,
highlight: {
enable: true,
auto_detect: false,
line_number: true,
tab_replace: '',
wrap: true,
hljs: false
},
prismjs: {
enable: false,
preprocess: true,
line_number: true,
tab_replace: ''
},
default_category: 'uncategorized',
category_map: null,
tag_map: null,
date_format: 'YYYY-MM-DD',
time_format: 'HH:mm:ss',
updated_option: 'mtime',
per_page: 10,
pagination_dir: 'page',
theme: 'landscape',
server: {
port: 4000,
log: false,
ip: undefined,
compress: false,
header: true,
cache: false
},
deploy: { type: '' },
ignore: null,
meta_generator: true,
keywords: null,
index_generator: { per_page: 10, order_by: '-date', path: '' },
include: null,
exclude: null,
archive_generator: { per_page: 10, yearly: true, monthly: true, daily: false },
category_generator: { per_page: 10 },
tag_generator: { per_page: 10 },
marked: {
gfm: true,
pedantic: false,
breaks: true,
smartLists: true,
smartypants: true,
modifyAnchors: 0,
autolink: true,
mangle: true,
sanitizeUrl: false,
headerIds: true,
anchorAlias: false,
lazyload: false,
prependRoot: false,
postAsset: false,
external_link: { enable: false, exclude: [], nofollow: false }
}
}

表示された内容は、アプリケーション直下の_config.ymlの内容ですね。

しかし、ドキュメントには以下のように説明がありました。

_config.yml

1
2
3
4
5
theme: "my-theme"
theme_config:
bio: "My awesome bio"
foo:
bar: 'a'

themes/my-theme/_config.yml

1
2
3
4
bio: "Some generic bio"
logo: "a-cool-image.png"
foo:
baz: 'b'

Resulting in theme configuration:

1
2
3
4
5
6
7
8
{
bio: "My awesome bio",
logo: "a-cool-image.png",
foo: {
bar: "a",
baz: "b"
}
}

本来は各ディレクトリの設定内容が反映される、しかし、重複している場合はアプリケーショントップの_config.ymlを優先する、ということだと思います。

他のテーマは確かにそうなっていました。たまたま見た目が気に入ったテーマが他と動きが異なるだけのようです。

原因ははっきりわかりませんが、一旦ここで終わりにしたいと思います。自分でテーマを作るときにでもまた調査したいと思います。

利用するテーマを決定する

aomoriを諦めて、他のテーマを眺めていると、やはりTOPページがカードタイプのテーマがいいなと思いました。

するとなかなか良さそうなテーマが見つかりました。PHANTOMという名前です。

デモ https://www.codeblocq.com/assets/projects/hexo-theme-phantom/

github https://github.com/klugjo/hexo-theme-phantom

phantomのインストール

早速インストールします。READMEに書いてある通り実施します。

1
2
3
4
5
6
7
$ cd themes
$ git clone https://github.com/klugjo/hexo-theme-phantom.git
Cloning into 'hexo-theme-phantom'...
remote: Enumerating objects: 166, done.
remote: Total 166 (delta 0), reused 0 (delta 0), pack-reused 166
Receiving objects: 100% (166/166), 596.45 KiB | 753.00 KiB/s, done.
Resolving deltas: 100% (60/60), done.

次に必要なnpmパッケージをインストールします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ npm install --save hexo-renderer-scss
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported

> node-sass@4.14.1 install /Users/user/github/business-book-reviews/business_blog/node_modules/node-sass
> node scripts/install.js

Downloading binary from https://github.com/sass/node-sass/releases/download/v4.14.1/darwin-x64-83_binding.node
Download complete ⸩ ⠋ :
Binary saved to /Users/user/github/business-book-reviews/business_blog/node_modules/node-sass/vendor/darwin-x64-83/binding.node
Caching binary to /Users/user/.npm/node-sass/4.14.1/darwin-x64-83_binding.node

> node-sass@4.14.1 postinstall /Users/user/github/business-book-reviews/business_blog/node_modules/node-sass
> node scripts/build.js

Binary found at /Users/user/github/business-book-reviews/business_blog/node_modules/node-sass/vendor/darwin-x64-83/binding.node
Testing binary
Binary is fine
+ hexo-renderer-scss@1.2.0
added 353 packages from 201 contributors and audited 544 packages in 28.474s

18 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

動作確認

起動してみます

1
2
3
4
$ npx hexo server
INFO Validating config
INFO Start processing
INFO Hexo is running at http://localhost:4000 . Press Ctrl+C to stop.

ブラウザでlocalhost:4000にアクセスします。

hexoのテーマ phantom

なかなかいいのではないでしょうか。一旦このテーマで新しいアプリケーションを作っていきます。

まとめ

新しいアプリケーションのテーマを決めることができました。_config.ymlの謎が解けずに悔しいですが、またの機会にチャレンジしたいと思います。

次回は、同じサーバー上で2つのhexoアプリケーションを動作させるための設定を行っていきたいと思います。

hexoのテーマを変更する

前回までのまとめ

前回、ビジネス書の記事は別のドメイン(サブドメイン)にした方がよいだろうということで、新しいhexoアプリケーションのベースを作成するところまで行いました。

前回のまとめで、次回はnginxの設定を行いたいと書きましたが、今回はhexoのテーマを何にするか決めたいと思います。

hexoのテーマ

デフォルトのテーマ

hexoのテーマはデフォルトでlandscapeというテーマになっています。

https://hexojs.github.io/hexo-theme-landscape/

このサイトもlandscapeを使っています。せっかくなのでなにか新しいテーマにチャレンジしたいと思います。

テーマを探す

hexoのテーマはどういうものがあるのでしょうか。こちらにテーマの一覧がありました。たくさんあって目移りしてしまいます…

TOPの一覧がカードタイプになっているテーマがよかったので、Gradientというテーマにしました。

テーマを設定する

テーマを設定するには

  1. テーマをインストールする
  2. _config.ymlでテーマを指定する

でできそうです。

テーマをインストールする

先ほどのリンクのREADME.mdにインストールの方法が書かれています。

1
2
3
4
5
6
7
8
9
10
11
$ cd themes
$ git clone https://github.com/DeepSpaceHarbor/Gradient
Cloning into 'Gradient'...
remote: Enumerating objects: 127, done.
remote: Counting objects: 100% (127/127), done.
remote: Compressing objects: 100% (70/70), done.
remote: Total 653 (delta 64), reused 69 (delta 28), pack-reused 526
Receiving objects: 100% (653/653), 5.46 MiB | 1.62 MiB/s, done.
Resolving deltas: 100% (329/329), done.
$ ls
Gradient landscape

こちらで完了です。

_config.ymlでテーマを指定する

インストールしたテーマを利用するように設定します。

1
2
3
4
5
6
$ pwd
/business_blog/themes
$ cd ..
$ ls
_config.yml node_modules package.json source yarn.lock
db.json package-lock.json scaffolds themes

アプリケーショントップにある_config.ymlを修正します。

1
2
3
4
5
$ vi _config.yml
98 # Extensions
99 ## Plugins: https://hexo.io/plugins/
100 ## Themes: https://hexo.io/themes/
101 theme: landscape

こちらのthemeをGradientに変更して保存します。

以上で設定は完了です。

動作確認

テーマが正しく反映されたかどうか動作確認をします。

1
2
3
4
$ npx hexo server
INFO Validating config
INFO Start processing
INFO Hexo is running at http://localhost:4000 . Press Ctrl+C to stop.

ブラウザでhttp://localhost:4000にアクセスします。

hexoのテーマ Gradient

ポインタが変わったりするんですね…ちょっと他のも検討してみようと思います…

他のテーマを試す

Aomoriというテーマが見た目シンプルでよいなと思って試してみました。

動作確認でエラー

インストールと設定はいつも通り行なって動作確認をしてみると

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
ERROR {
err: TypeError: /Users/user/github/business-book-reviews/business_blog/themes/aomori/layout/layout.ejs:20
18| <aside class="sidebar">
19| <% } %>
>> 20| <%- partial('_partial/sidebar') %>
21| </aside>
22| </div>
23| </div>

/Users/user/github/business-book-reviews/business_blog/themes/aomori/layout/_partial/sidebar.ejs:7
5|
6| <div class="widget" id="widget">
>> 7| <% config.aomori_widgets.forEach(function(widget){ %>
8| <%- partial('_widget/' + widget) %>
9| <% }) %>
10| </div>

Cannot read property 'forEach' of undefined
at eval (/Users/user/github/business-book-reviews/business_blog/themes/aomori/layout/_partial/sidebar.ejs:21:30)
at sidebar (/Users/user/github/business-book-reviews/business_blog/node_modules/ejs/lib/ejs.js:682:17)
at _View._compiledSync (/Users/user/github/business-book-reviews/business_blog/node_modules/hexo/lib/theme/view.js:132:24)
at _View.renderSync (/Users/user/github/business-book-reviews/business_blog/node_modules/hexo/lib/theme/view.js:59:25)
at Object.partial (/Users/user/github/business-book-reviews/business_blog/node_modules/hexo/lib/plugins/helper/partial.js:34:15)
at eval (/Users/user/github/business-book-reviews/business_blog/themes/aomori/layout/layout.ejs:28:17)
at layout (/Users/user/github/business-book-reviews/business_blog/node_modules/ejs/lib/ejs.js:682:17)
at _View._compiled (/Users/user/github/business-book-reviews/business_blog/node_modules/hexo/lib/theme/view.js:136:50)
at _View.render (/Users/user/github/business-book-reviews/business_blog/node_modules/hexo/lib/theme/view.js:39:17)
at /Users/user/github/business-book-reviews/business_blog/node_modules/hexo/lib/theme/view.js:51:25
at tryCatcher (/Users/user/github/business-book-reviews/business_blog/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/Users/user/github/business-book-reviews/business_blog/node_modules/bluebird/js/release/promise.js:547:31)
at Promise._settlePromise (/Users/user/github/business-book-reviews/business_blog/node_modules/bluebird/js/release/promise.js:604:18)
at Promise._settlePromise0 (/Users/user/github/business-book-reviews/business_blog/node_modules/bluebird/js/release/promise.js:649:10)
at Promise._settlePromises (/Users/user/github/business-book-reviews/business_blog/node_modules/bluebird/js/release/promise.js:729:18)
at _drainQueueStep (/Users/user/github/business-book-reviews/business_blog/node_modules/bluebird/js/release/async.js:93:12) {
path: '/Users/user/github/business-book-reviews/business_blog/themes/aomori/layout/layout.ejs'
}
} Render HTML failed: index.html

となって表示できません。エラーの内容を確認すると、Cannot read property 'forEach' of undefinedとなっていて、config.aomori_widgetsがundefinedになっているのが原因のようです。

エラーの修正

README.mdにあるようにthemes/_config.ymlaomori_widgetsを設定してみました。

1
2
3
4
5
6
aomori_widgets:
- toc # Article navigation
- category # Article classification
- tag # Article tags
- recent_posts # latest articles
- archive # Article Archive

しかし、エラーは消えません。READMEをよくみると、Configuration in the Global _config.ymlとなっていて、アプリケーション下の_config.ymlに設定しないといけないようです。

アプリケーション下の_config.ymlに設定してエラーはなくなりました。

hexoのテーマ aomori

しかし、テーマの設定でアプリケーション下の_config.ymlに設定するのは、よくない設計だと思います。

まとめと次回予告

いろいろテーマを探してみて、いろんなものがあるのだなぁと思いました。また、テーマの変更方法を理解することができました。

次回は今回疑問に思った各ディレクトリの_config.ymlの設定の違いについて調べたいと思います。

新しくhexoアプリケーションを作成する

背景

GoogleSearchConsoleを見ていると、ビジネス書の記事でインデックスされなくなっていたり、ビジネス書の記事でほとんど検索上位に表示されないということがわかりました。

たまたま読んだ沈黙のWebマーケティングによると、ジャンル・カテゴリが違う内容はサブドメインを切った方が良いという風に書かれていました。(この本は見た目はアレですが、片手間でしかSearchConsoleを使ったことがないぼくにとってはとても勉強になりました)

なので、今回新しくサブドメインを作成し、ビジネス書の記事はそちらに集約しようと思います。

hexoアプリケーションの作成

このブログはhexoでできていますが、作り方を忘れてしまったので確認しながら記載していきます。

nodejsのインストール

nodejsは現在LTS最新版が14.15.1です。これをインストールします。

1
2
3
4
5
6
7
8
$ nodenv install 14.15.1
node-build: definition not found: 14.15.1

See all available versions with `nodenv install --list'.

If the version you need is missing, try upgrading node-build:

git -C /Users/user/.anyenv/envs/nodenv/plugins/node-build pull

nodenvを更新します。anyenvを利用しているので、 anyenv updateします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ anyenv update
Updating 'anyenv'...
| From https://github.com/riywo/anyenv
| e963a69..67d402f master -> origin/master
| * [new tag] v1.1.2 -> v1.1.2
Updating 'anyenv/anyenv-git'...
Updating 'anyenv/anyenv-update'...
Updating 'nodenv'...
Updating 'nodenv/node-build'...
| From https://github.com/nodenv/node-build
| ddc0daa4..bb925ce4 master -> origin/master
| * [new tag] v4.9.19 -> v4.9.19
| * [new tag] v4.9.16 -> v4.9.16
| * [new tag] v4.9.17 -> v4.9.17
| * [new tag] v4.9.18 -> v4.9.18
Updating 'nodenv/nodenv-vars'...
Updating 'pyenv'...
| From https://github.com/pyenv/pyenv
| 806b30d6..943015eb master -> origin/master
Skipping 'pyenv/python-build'; not git repo
Updating 'rbenv'...
| From https://github.com/rbenv/rbenv
| c879cb0..60c9339 master -> origin/master
Updating 'rbenv/ruby-build'...
| From https://github.com/rbenv/ruby-build
| 1642176..f85906e master -> origin/master
| * [new tag] v20201118 -> v20201118
| * [new tag] v20200722 -> v20200722
| * [new tag] v20200727 -> v20200727
| * [new tag] v20200819 -> v20200819
| * [new tag] v20200926 -> v20200926
| * [new tag] v20201005 -> v20201005
| * [new tag] v20201117 -> v20201117
Updating 'anyenv manifest directory'...

updateが終わったのでインストールします。

1
2
3
4
5
$ nodenv install 14.15.1
Downloading node-v14.15.1-darwin-x64.tar.gz...
-> https://nodejs.org/dist/v14.15.1/node-v14.15.1-darwin-x64.tar.gz
Installing node-v14.15.1-darwin-x64...
Installed node-v14.15.1-darwin-x64 to /Users/user/.anyenv/envs/nodenv/versions/14.15.1

インストールが終わったので、このバージョンを利用するようにします。

1
2
3
4
5
$ nodenv local 14.15.1
$ ls -a
. .. .node-version
$ cat .node-version
14.15.1

hexoのインストール

あとは9こちらに書かれている通り進めていきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ npm install -g hexo-cli
/Users/user/.anyenv/envs/nodenv/versions/14.15.1/bin/hexo -> /Users/user/.anyenv/envs/nodenv/versions/14.15.1/lib/node_modules/hexo-cli/bin/hexo
+ hexo-cli@4.2.0
added 64 packages from 338 contributors in 5.057s
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
<省略>
$ npm install hexo
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN business-book-reviews@1.0.0 No description

+ hexo@5.2.0
added 91 packages from 371 contributors and audited 91 packages in 4.774s

11 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

バージョン5.2.0がインストールされました。

インストール完了後は

1
$ npx hexo <command>

でコマンドが実行できます。

hexoのセットアップ

こちらを参考に進めていきます。

1
2
3
4
5
6
7
8
$ npx hexo init business_blog
INFO Cloning hexo-starter https://github.com/hexojs/hexo-starter.git
INFO Install dependencies
warning hexo-renderer-stylus > stylus > css-parse > css > urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
warning hexo-renderer-stylus > stylus > css-parse > css > source-map-resolve > urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
warning hexo-renderer-stylus > stylus > css-parse > css > source-map-resolve > resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
warning Your current version of Yarn is out of date. The latest version is "1.22.5", while you're on "1.22.4".
INFO Start blogging with Hexo!

これだけでセットアップは完了です。作成されたディレクトリに移動すると見慣れたファイルがインストールされています。

1
2
3
$ cd business_blog/
$ ls
_config.yml node_modules package.json scaffolds source themes yarn.lock

ここでnpm installします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ npm install
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN rm not removing /Users/user/github/business-book-reviews/business_blog/node_modules/.bin/stylus as it wasn't installed by /Users/user/github/business-book-reviews/business_blog/node_modules/stylus

> ejs@2.7.4 postinstall /Users/user/github/business-book-reviews/business_blog/node_modules/ejs
> node ./postinstall.js

Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)

npm notice created a lockfile as package-lock.json. You should commit this file.
added 25 packages from 48 contributors, removed 11 packages, updated 166 packages and audited 191 packages in 10.617s

14 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

これで必要なパッケージはインストールできました。

まとめと次回予告

このブログを開始したのは1年半前でした(時が経つのは早いものです。時間は大事にしたいですね)。そのときのhexoのバージョンは3.9でした。今回は5.2を新しくインストールするにあたって3.9のもメンテナンスしたいと思います。

次回は、セットアップしたhexoのconfig周りの設定と、nginxのバーチャルホストの設定をしていきたいと思います。

Google AdSenseを開始しました!

審査結果が届く

前回、Google AdSenseの審査のための準備という記事を書きました。申請をしたのは、この記事を書いた1日前(11月21日の深夜)です。

その後、Google AdSense(以下、AdSense)のホームページに

「審査には数日かかります、場合によっては2週間ほどかかります」

のようなメッセージが表示されていました。結果が出るのをリロードしながら待っていました。

審査の結果を心待ちにしていたら、AdSenseからメールが届きました!

お客様のサイトでAdSense広告を配信する準備が整いました

まず思ったのは審査が通って本当によかったということです!審査に通らず再審査になると、どんどん審査に通りづらくなるという話も聞いたことがあったので、1発で通ってよかったです!

そして審査結果が出るのも早かったです。申請してから1日半くらいで審査結果が出ました。

ads.txtの設定をする

AdSenseの設定をするのははじめてなので、まずメニューを見てみます。

ホーム、広告設定は広告などのメニューがあるのを確認していると、ホームを表示した時にいかにもアラートっぽいメッセージが表示されます。

ads.txtのアラート

なんだろうと思って今すぐ修正のリンクをクリックするとads.txtを作成してねというメッセージが表示されました。そのメッセージの下の方にダウンロードのリンクがあるので、自分用のads.txtをダウンロードします。

ads.txtを配置する

ads.txtはドキュメントルート直下に置くファイルなので、hexoのpublicディレクトリにおきます。

以下のURLで表示確認を行い完了です。

https://book-reviews.blog/ads.txt

アラートはなかなか消えない

設置してみたもののアラートは消えません…心配になりますが、ちゃんと設置できています。

ヘルプを見てみると以下の注意書きがありました。

注: 変更が AdSense に反映されるまでに数日かかる場合があります。サイトの広告リクエストが多くない場合は、最長で 1 か月ほどかかることがあります。

ん〜まぁまぁ時間がかかるみたいですね。PVが少ない=広告リクエストの数は多くないのでアラートが消えるのは気長に待つことにします。

広告を設置する

AdSenseが利用できるようになったのであれば早速広告を設置してみます!

広告掲載の自動化

メニューの広告をクリックすると、広告掲載の自動化というメッセージがまず目に飛び込んできます。仕事でGoogle AdManagerを使って広告の設置を行ったりしていたので、思ったのと違うな〜と思いながら、自動広告をONにしてみました。

編集アイコンをクリックすると広告設定のプレビューで実際にどのように広告が表示されるのかを確認することができます。確認してみると記事上に画面幅と同じ幅の大きな広告が表示されていました。こういう風にしか設定できないのかと思って一旦その設定を適用しました。

広告ユニットを作成する

広告設定が自動のみなわけがなく、やはり設定する箇所がありました。

メニューで広告を選んだ状態で上の方にスクロールすると、広告ユニットごとというタブがありました。それをクリックすると、新しい広告ユニットの作成というメニューが出てきました。

推奨されているディスプレイ広告を作成します。広告ユニットの名前を入力のところに適切な名前をいれて、形をスクエア・横長タイプ・縦長タイプから選んで作成ボタンをクリックします。(広告サイズはレスポンシブのままにしておきます)

するとコードが表示されます。
一番上の<script async src=>のコードは審査時に貼っているので、その下のHTMLを表示したい箇所に貼ります。(hexoでsidebarに広告を貼る方法はまた別の機会にご紹介します)

実際に表示された広告を見てみると、スクエアを選んだはずが縦長の広告が表示されてしまっています…

スクエアが縦長に

原因はわかりませんが、他にも気になる点があるので調整していきます。

marginの調整

記事のmarginの調整

広告の高さは記事とあっていると見た目がよくみえます(個人的に)。なので高さを合わせます。

まず記事の方の更新日時の上が思ったより空いているので、調整します。

記事の上のマージンはarticleというclassで当てられています。
hexoでの定義箇所を探すとthemes/landscape/source/css/_partial/article.stylにありました

1
2
3
1 .article
2 margin: block-margin 0
3

marginはblock-marginという変数を利用していました。この変数に値をいれているところを探します。するとthemes/landscape/source/css/_variables.stylというファイルで指定されていることがわかりました。

1
2
3
4
43 // Layout
44 block-margin = 50px
45 article-padding = 20px
46 mobile-nav-width = 280px

こちらの数字を30pxにしてみます。hexo generateで適用します。

広告のmarginの調整

先ほど追加した広告にmargin-top: 60pxを適用します

1
2
3
4
5
6
7
8
9
<ins class="adsbygoogle"
style="display:block;margin-top: 60px;"
data-ad-client="ca-pub-1078092739514795"
data-ad-slot="9239237218"
data-ad-format="auto"
data-full-width-responsive="true"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

調整後の確認

ページをリロードして確認してみます。

margin調整後

いい感じになりました!

まとめ

AdSenseの審査が通過したので、必要な設定(ads.txtの設置)を行い、広告タグを作成しました。広告を表示するにあたりレイアウトが気になったのでそちらを調整しました。

このまましばらく様子をみて、必要であればオーバーレイ広告を画面下に表示してみたいと思います。