werckerからnon-Dockerなclassicな方法を使ったアプリケーションを停止するよ、というメールが来ていて Dockerベースな方法への変更を促されました。
Dockerベースなアプリケーション自体はだいぶ前から利用出来るようになっていて、 猶予期間が終わったので古い方法は廃止しますよ、ということらしいです。
Dockerが使える様になったのは見た記憶がありましたが古いのが使えなくなるのは気づいてなかったので 今更ながら移行しました。
アプリのDockerベースへの移行
このブログはBitBucketに送ったものをwerckerでOctopressなビルドをしてhtml化していますが、 特に気にせず古い方法を使い続けていました。
取り敢えずこのままだと使えなくなる、ということで、メールに従って、 Classic app migrator のページに行き、ウェブ上でアプリケーションをDockerベースのものに変換します。
変換自体は上のページでワンクリックで出来ます。 ただ、これをしてしまうと古いビルドの情報が辿れなくなってしまうみたいです。
一応、ビルドが失敗したときの昔のメールからビルドページを開いてみると情報は残ってますが、 ページの上側にあるはずのアプリケーションへのリンクが消えていて、何にも結び付けられていないビルドみたいになっているので 直接辿り着かないと見れないようになってるみたいです。
ブログのビルドなので別に良いのですが場合によってはログが重要な場合もあると思うのでちょっと注意が必要かもしれません。
新しいアプリの特徴: Workfolows
ウェブのインターフェースが刷新されていますが、
機能的に大きく変わったのは
Workflows: http://devcenter.wercker.com/docs/workflows
という機能が加わったことです。

以前のアプリでは、buildとdeployという2つの段階を作って、
それぞれでテストやビルドを行ったり、
作ったものを最終目的地に送ったりしていました。
これが新しいアプリではpipelineという任意の段階を作ることが出来、 自由に繋げたり、さらに枝分かれさせて平行に進めたりすることが出来ます。
古いアプリから移行されたものだと上の絵の様に
buildとdeployというpipelineがあって、
buildはレポジトリにpushが来たら走る、
deployはbuild終わったら走る(ただしブランチがsouceのときだけ)、という状態になっています。
deployの方にはGitHubに送ることを解釈してか、GitHubという名前がついてます。
wercker.ymlで参照される値はdeployの方です。
以前のものに慣れてるとちょっと注意が必要なのは
以前は、build、deployの段階をwercker.ymlに書いておくとこれらが自動で実行されましたが、
新しいアプリではここのWorkflowsのページできちんと設定しておかないと
wercker.ymlに書いてあっても実行されません。
一応buildという名前のpipelineはアプリケーション作成時に自動で作られる様になっていますが、
deployに関しては無いので自分で作らないとwercker.ymlに書いておいても動きません。
pipelineを複数つなげると、そのpipeline毎にコンテナを使って
環境を組み立てるので、例えば毎回bundle installを行う必要があったりします。
なので小さな作業の場合なんかの場合はdeployの作業まで含めてbuildの中に入れてしまった方が
実行時間は短くて済みます。
分けておくメリットとしては、deployの段階で何らかエラーが起きてもう一度走らせれば上手く行く可能性がある場合などに
その作業だけをリトライすることが出来る、ということです。
buildの作業が長くかかる場合などにはありがたみが増します。
取り敢えず以前の状態のまま移行されたので
これらのレポジトリではbuildとdeployを分けたままにしておきます。
wercker.ymlの移行作業
box
取り敢えずウェブで変換して新しいビルドを送ってみると、
Error interacting with this repository: docker.io/wercker/rvm GET https://registry.hub.docker.com/v1/repositories/wercker/rvm/images returned 404
こんな感じのエラーがsetup environmentのステップで出ました。
Dockerへの移行時にboxの設定だけは最低限必要で、それもしてなかったためです。
これまで
box: wercker/rvm
というboxを使ってましたが、上のページにある様にDocker Hubのruby
のレポジトリを代わりに使えばOK。
特にバージョンとか気にする必要も無いので、
box: ruby
とするだけ。とりあえずこれでビルドが走る様になります。
submodulesを自分でアップデートしないといけない
このブログのレポジトリはOctopressのソースを管理していますが、 octogray というテーマを使っていて、このテーマがsubmoduleとして入っています。
さらに、管理上便利なので、レポジトリの中にこのsubmoduleの中にあるファイルへの シンボリックリンクが貼られています。
classicな方法だと何も考えずにwerckerを走らせても、 自動でsubmodulesまでrecursiveにcloneされていました。
これが新しいDockerを使ったアプリケーションではデフォルトでは submodulesは取ってこない様になったみたいです。
ということでここにあるとおり、buildの最初の方で、
- script:
name: Initialize git submodules
code: git submodule update --init --recursive
をしておきます。
classicな前のビルドログを見ると確かに最初のget codeのステップで
cloneして該当のバージョンをcheckoutした後にgit submodule update --init --recursiveを
していましたが、新しいログではcheckoutで終わっています。
ArgumentError: invalid byte sequence in US-ASCII
rake generateする段階で、
ArgumentError: invalid byte sequence in US-ASCII
と言ったエラーが出ました。
該当するRakefileの行は
jekyll_config.gsub!(/\n^.*OCTOPRESS_TEST$/, "")
こんな感じ。
同じ問題が起こって解決してた人が居たのでそのまま拝借。
wercker.ymlにrake generateを走らせるスクリプト設定の前に
- script:
name: set env
code: export RUBYOPT=-EUTF-8
を加えると解決できました。
Host key verification failed.
deployのステップで
## Pushing generated ./_deploy website
Host key verification failed.
fatal: Could not read from remote repository.
なエラーが出ました。
これはgithub.comにssh接続でpushしようとしている時にホストの確認が出来てないために置きています。
これはstep-add-to-known_host というstepを使うと簡単に解決できます。
GitHubへ作業を行いたいなら、
- add-to-known_hosts:
hostname: github.com
fingerprint: 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
を作業ステップの前に入れておけばOK。
このfingerprintの値はstep-add-to-known_host のREADMEにも書いてありますが、 GitHubの以下のページでも手に入ります。
rsaの鍵を使うのでrsaの方のfingerprintで。
このstepで~/.ssh/known_hostsにgithub.comが登録されます。
古いバージョンではなぜかこれをしなくても大丈夫でしたが、 古いバージョンではwerckerが用意したコンテナを使ってたこともあるので デフォルトでknown_hostsに値が入っていたとかだったんでしょうか。。。?
Permission denied (publickey).
再びpushする時にエラー。
今度は鍵認証に失敗している、とのことですが、
これは単にmigrationすると前に作っていた鍵が失われたためです。
ということで鍵を作り直し。
Dockerベースの新しいバージョンでは Envronmentタブか、もしくはWorkfolowsタブ内の各pipelineの中の設定で鍵を登録/作成することが出来ます。
Environmentだとそのアプリ全体で使えるものになり、 pipelineの中で作るとそのpipelineだけで使えるものになります。
以前と色々とインターフェースも変わっていますが、 それぞれの場所にgenerate SSH Keysと言うリンクがあるので そこからGITHUB_DEPLOY_KEYという名前で鍵を作ります。

作ると名前+_PUBLIC/_PRIVATEという2つの鍵が出来てるので、
PUBLICの方のvalueの欄にあるssh-rsaという文字の所をクリックすると
公開鍵の内容が表示されるのでこれをGitHubの方に登録すればOK。
GitHub (deploy)の中で鍵を作成してGitHubの該当のレポジトリのSettingDeploy keysで Add deploy keyから Allow write accessにチェックを入れた状態でGITHUB_DEPLOY_KEY_PUBLICの値を登録します。
wercker.ymlの中では
- add-ssh-key:
keyname: GITHUB_DEPLOY_KEY
host: github.com
みたいな感じで
step-add-ssh-key
を使うと簡単に鍵の登録が出来ます。
ここでkeynameには_PRIVATEなどを除いた最初に作った時に入れた名前を指定します。
また、gitのユーザーも指定しておきます。
- script:
name: Prepare gitconfig
code: |
git config --global user.email "[email protected]"
git config --global user.name "rcmdnk"
ちなみにソースのBitbucketはプライベートレポジトリを使ってるので こちらも鍵がないと外から取ってこれないわけですが、 こちらの認証鍵は以前のまま使える様です。
もし上手く行かない場合はOptionsタブから Repository accessのConfigureボタンを押して始まるページで Configure accessというステップでAdd the deploy key to the selected repository for meという 項目を選んで置くと鍵が生成されBitbucket側には自動で公開鍵が登録されます。
LoadError: cannot load such file – xmlrpc/client
接続の問題が解消された後にこんなエラーが。
rake aborted!
LoadError: cannot load such file -- xmlrpc/client
/pipeline/source/Rakefile:872:in `require'
/pipeline/source/Rakefile:872:in `block in <top (required)>'
/pipeline/source/Rakefile:457:in `block in <top (required)>'
/usr/local/bundle/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
Tasks: TOP => deploy
(See full trace by running task with --trace)
xmlrpcがないと。
こんなdiscussionが見つかりましたが、ruby 2.4からこのモジュールが デフォルトでは無くなったということで、 これをロードするために
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
gem 'xmlrpc', '~> 0.2'
end
をGemfileの中に追加しておきます。
ローカル環境でアップデートが必要なら追記してからbundle updateを実行。
新しいDockerのrubyなコンテナは最新の2.4のものになっています。
以前の古いコンテナは古いrubyを使っていた様でこのエラーには会わなかったみたいです。
xmlrpcはping
というタスクの中で
使われていて、これはdeploy終了時に
Searchエンジンなどにpingを送るためのタスクで
ローカルでのテスト時には普段使ってなかったこともあって気づいてませんでした。
逆に2.3以前のものだと
installError: xmlrpc requires Ruby version >= 2.4.0dev.
An error occurred while installing xmlrpc (0.2.1), and Bundler
みたいなエラーが出るので上の様にRubyのバージョンをチェックして必要なときだけ入れるようにしています。