ホームページの私的ミラーを Heroku で認証付きホスティングする

「[５人タクティクスオウガ](http://homepage1.nifty.com/~yu/t_ogre/)」というページがあり、大好きでよく読んでいるのだが、ここは（おそらく）ニフティの `@homepage` というサービスでホスティングされており、近いうちにサービス終了とともに消えて無くなってしまうかもしれない。

それは悲しいので、私的バックアップを作った。その際、いくつかクリアしたい条件があった。

- （できれば）無料であること
- アクセス制限がかけられること（他人の著作物を無断で不特定多数の人に再配布するわけにはいかないので）
- フルマネージドなホスティング環境であること（ホスティングサーバを管理したくないので）

これらの条件を満たせる Heroku にデプロイした。同じようなことをやりたい人の参考になるかもと思い、手順とハマったところを公開する。

1. `wget` でサイトを丸ごとダウンロードする
----------------------------------------

```
$ wget \
  --recursive \
  --no-clobber \
  --page-requisites \
  --html-extension \
  --convert-links \
  --no-parent \
  http://homepage1.nifty.com/~yu/index.html
```

2. GitHub のプライベートリポジトリに保管する
------------------------------------------

必須ではないが、バックアップのために。 Bitbucket でも構わない。

```
$ cd homepage1.nifty.com
$ git init
$ git add .
$ git commit -m 'init'
$ git push origin master
```

3. Heroku アプリケーションを作る
-------------------------------

アプリ名に `_` は使えない。

4. `Procfile` 他、必要なファイルを用意して Heroku にデプロイする
-------------------------------------------------------------

画像ファイルが一個のディレクトリ内にまとまっておらず `Rack::Static` で配信しづらかったので、 webrick に任せたい。

Procfile を置くことで `config.ru` と Rack の作法での webrick 起動コードを書かずに済ませる。

```
web: ruby server.rb
```

```server.rb
require 'webrick'

include WEBrick

port = ENV['PORT']
user = ENV['USER']
pass = ENV['PASS']

server = HTTPServer.new(
  :Port => port,
  :DocumentRoot => './~yu',
  :RequestCallback => lambda do |req, res|
    HTTPAuth.basic_auth(req, res, "my realm") do |username, password|
      username == user && password == pass
    end
  end
)

trap("INT"){ server.shutdown }
server.start
```

Heroku に Ruby ビルドパックを使わせるために `Gemfile` と `Gemfile.lock` が必要。
Gem は一個も使わないので、中身は `bundle init` で作ったそのままでよい（webrick は Ruby の標準添付ライブラリ）

```Gemfile
# frozen_string_literal: true
# A sample Gemfile
source "https://rubygems.org"

# gem "rails"
```

```Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:

PLATFORMS
  ruby

DEPENDENCIES

BUNDLED WITH
   1.12.5
```

ファイル数が多い・容量が大きいせいか、 git push できなかった。

```
remote: Build stream timed out, reverting to polling........................................................................................
....................................................................................................................................
remote:
remote: Build output:
remote:
remote: !       Push rejected to xxxxxx-xxxxxx-xxxxxx.
remote:
```

サイズが大きく、ウェブから配信しなくても構わなそうなファイルを見つけて、 `.slugignore` に書いたところ、うまく push できた。

```.slugignore
./~yu/ocs/playsheets/HubesScn1SovPlaysheets-d.ppt
./~yu/panzerf/pf_real.zip
```

除外対象ファイルはこんなコマンドで探す。

```
$ ls -la $(find . -type f) | sort -nr -k5 | grep -v .git/ | head -n 10
```

5. ベーシック認証をかける
------------------------

GitHub Pages ではなくわざわざ Heroku を使うのは、ベーシック認証をかけたいから。環境変数で user/pass を指定する。

```
$ heroku config:set USER=XXX PASS=XXX
```

おわりに
------

- バックアップした HTML ファイルだけどこかのストレージに置いておいても、ブラウザから直接（ブックマーク経由とかで）アクセスできないと存在を忘れそう
- ブラウザでブックマークとかするには URL が必要だろうから、どこかのウェブサーバでホスティングしないと

という発想が発端となってこういうことをしたのだが、 file:// スキームというものをすっかり忘れていた。単なる私的なバックアップなら Dropbox に放り込んでローカルファイルの URI をブックマークしとくのが一番楽だと思う。三時間早く気づきたかった。

追記: URL が欲しかった理由をもう一つ思い出した。移動中とか外出中にスマートフォンのブラウザから読むことも多いので、（デスクトップマシンの）ローカルファイルをブックマークしたのではちょっと都合が悪いのだった。