さくっとできるかなと思っていたが、Herokuは基本的にストレージへの書き込みができないため、全然さくっとできなかったので、その方法をまとめておく。
やりたいこと
Herokuで運用中のWebサービスにsitemap.xmlを設置したい。
結論
fog-awsを使って、sitemap.xmlをS3にアップロードする
Herokuはtmp以外にファイルの書き込みができないので、外部にsitemap.xmlを置くしかない。tmpは一定時間で削除されるので、今回のケースには利用できない。
環境情報
すでにCarrierwaveとfog-awsを利用してS3にアップロードしている。
Rails 5.2.2
carrierwave 1.3.1
mini_magick 4.9.2
fog-aws 3.3.0
対応方法
sitemap_generatorというGemを追加する。公式リポジトリの手順を参考に進める。
gem 'sitemap_generator'
gemをインストール
$ bundle install
Herokuのようなシステムの場合の対応方法がリポジトリのWikiにあるので、そちらを参考に進めていく。
Using Fog と Using CarrierWave が存在しているが、すでにfog-awsを利用している場合、Using CarrierWaveの方法だと上手くいかないので、Using Fogを利用する。
config/sitemap.rb を下記のように記述。一部、例の通りだが、だいたいそのまま。今回のアプリでは、ENVでAWSの鍵やバケット名などを管理している。
SitemapGenerator::Sitemap.default_host = "https://example.com"
SitemapGenerator::Sitemap.sitemaps_host = "https://s3-ap-northeast-1.amazonaws.com/#{ENV['AWS_S3_BUCKET']}/"
SitemapGenerator::Sitemap.public_path = 'tmp/'
SitemapGenerator::Sitemap.sitemaps_path = 'sitemaps/'
SitemapGenerator::Sitemap.adapter = SitemapGenerator::S3Adapter.new(fog_provider: 'AWS',
aws_access_key_id: ENV['AWS_ACCESS_KEY'],
aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
fog_directory: ENV['AWS_S3_BUCKET'],
fog_region: 'ap-northeast-1')
sitemapの実際の中身は、config/sitemap.rbの下部に下記のように記述する。例) /articles/:id などを記述
SitemapGenerator::Sitemap.create do
add root_path, changefreq: 'daily'
add '/category1'
add '/category2'
Article.published.find_each do |article|
add article_path(article), priority: 0.8, lastmod: article.updated_at
end
end
クローラーにsitemapの場所を知らせる
public/robots.txt にsitemap.xmlの場所を記述する。ENVはrobots.txtで使えないはずなので、バケット名は直接書く。
Sitemap: https://s3-ap-northeast-1.amazonaws.com/[S3のバケット名]/sitemaps/sitemap.xml.gz
sitemapを定期的に作成する
rails sitemap:refresh(sitemap.xml.gzを作成し、検索エンジンに通知するコマンド)をHerokuのスケジューラに登録
Herokuダッシュボード > Resourcesタブ > Add-ons > Heroku Scheduler > Add Job をクリック

TIPS
・Using CarrierWave で上手くいかなかったのは、CarrierWave側のバグのせいっぽい。

・デフォルトではpublic以下にsitemap.xml.gzが作成されるのをtmp/に変更している。
・Rubyのコードで検索エンジンにsitemapをマニュアルで知らせる方法もある。
SitemapGenerator::Sitemap.ping_search_engines("https://s3-ap-northeast-1.amazonaws.com/#{ENV['AWS_S3_BUCKET']}/sitemaps/sitemap.xml.gz")
・sitemap.rbのSitemapGenerator::Sitemap.sitemaps_host = “https://s3-ap-northeast-1.amazonaws.com/#{ENV[‘AWS_S3_BUCKET’]}/”の最後の’/’は必須。ping(検索エンジンへの通知)の実行時にバケット名が認識されなくなり、通知されなくなってしまう。
試してみた時のログ
Pinging with URL 'https://s3-ap-northeast-1.amazonaws.com/sitemaps/sitemap.xml.gz':
Successful ping of Google
Successful ping of Bing
・rails sitemap:refresh:no_ping とすると、sitemapを作成するだけで検索エンジンへの通知は行わない。
感想
さくっとできなかったと冒頭に述べたが、その理由は、ローカルでガリガリ進めていたためHerokuの書き込みできない仕様を忘れていたことと、Using CarrierWaveで進めていて全然できなかったことである。
これを読んだ方が、私ががはまったポイントにハマらないといいなと思います。もちろん未来の自分も。
コメント