べにやまぶろぐ

技術寄りの話を書くつもり

StaticPress で静的化した WordPress を S3 に置いてデザインが崩れた時は css の Content-Type を確認しよう

大学時代の研究をまとめたサイトを WordPress で構築して EC2 でホストしてたのですが、

  • ラトビアあたりからの不正ログイン試行のアラートが Wordfence から頻繁に送られてくるようになった
  • そもそも更新もしないし PV も少ないし micro インスタンスでも運用するコストが見合わない

という理由で静的化プラグインの StaticPress で静的化して S3 から配信することにしました。

今回作業したのはこちらのサイト。

beniyama.com

具体的な作業内容はまたどこかで書ければと思うのですが、諸々の設定が終わった後はまったのがデザイン崩れ。崩れというより css が当たっていない。

f:id:beniyama:20160104234324p:plain

テーマが対応していないとダメだ、という記事も見かけたのですが結論としては css のファイルが S3 アップロード時に Content-Type:text/plain になってしまっていたのが原因。Content-Type:text/css に変更することで問題なくデザインが適用されました。

/tmp/static 以下に StaticPress で静的 html を吐いたとして、

s3cmd put -r --acl-public /tmp/static/* s3://<バケット名>

などとするとバケットにファイルが転送されますが、そのままだと css ファイルのメタデータは下記のようになってしまいます。

f:id:beniyama:20160104235300p:plain

s3cmd でバケット内のファイルのメタデータを一括変更することが可能ですので、続けて

s3cmd modify --add-header='Content-Type':'text/css' s3://<バケット名>/*/*.css

などとすればバケット内の全 css の Content-Type が書き換わります。

f:id:beniyama:20160105002652p:plain

これで WordPress と同じデザインが再現されました。

ちなみに余談ですが、http://jushock.hateblo.jp/entry/2014/08/05/203840 に書かれている

記事のタイトルは 〜.html というリンクになっているがアクセスするとディレクトリになってしまうという事だった。

という問題にもはまり(ページ名.html というディレクトリができてしまう)、試行錯誤した結果、パーマリンク設定のカスタム構造は

http://beniyama.com/%category%/%postname%/

で落ち着きました(%postname%.html などとしなくて良かった)。

参考)

Runtastic で始める中年エンジニアのヘルスケア

遡ること7月、転職前に受けた健康診断でお医者様に「肝臓壊れてるね〜」と言われ、それから節酒&食事改善&運動の習慣化などを始めました。

せっかく運動するんだからヘルスケア系のサービスを使ってみようと思い、只今絶賛 Runtastic まみれになっています。

きっちり競合比較していませんが、Runtastic の特徴は最も知名度のあるであろうランニングアプリ「Runtastic」だけでなく実に多様な、というか多すぎるくらいのアプリの品揃えだと思います。

https://itunes.apple.com/jp/app/runtastic-pro-gps-ranningu/id366626332?mt=8&uo=4&at=1010l7Ba

2015/10/3 現在、App Store には iPhone アプリだけで29種(PRO / Lite 版含む)も上がっていました

例えば腹筋運動だけ見ても CG を活用した多彩なトレーニングを提供する「Runtastic Six Pack」と単純に腹筋のカウントだけする「Runtastic Sit Ups」の2つが提供されています。

https://itunes.apple.com/jp/app/runtastic-six-pack-fu-jinwo/id685857245?mt=8&uo=4&at=1010l7Ba

https://itunes.apple.com/jp/app/runtastic-sit-ups-pro-fu-jinkaunto/id570183057?mt=8&uo=4&at=1010l7Ba

他には腕立て専用やスクワット専用、歩数計、体重計…などなど割とそれぞれの機能に特化してアプリが作られています。ただ、先ほどの腹筋アプリのように若干機能・ジャンルが被っているところがあって紛らわしいです。

また Runtastic 社からはいくつかデバイスも提供されており、自分は腕につけて使用する活動量計 Runtastic Orbit を使っています。

[asin:B00M1UILU8:detail]

Orbit は歩数のカウントや消費カロリーの計算、また睡眠モニタリングなどを行うことができます。Fitbit のようにおしゃれでもなく心拍も取れませんが、この辺は Watch OS2 の登場で AppleWatch から心拍が取れるようになったりしているのでそれで代替できるようになるといいなと思っています。Orbit は Runtastic Me というアプリでデータを吸い上げ管理します。

https://itunes.apple.com/jp/app/runtastic-me-bu-shukauntotsuki/id893528604?mt=8&uo=4&at=1010l7Ba

しかしながら先に挙げたように歩数計が Runtastic Pedometer、睡眠モニタリングは Runtastic Sleep Better というそれぞれのアプリ単体で動作するものが別にあってまたややこしいです。

https://itunes.apple.com/jp/app/runtastic-pedometer-pro-bu/id442894126?mt=8&uo=4&at=1010l7Ba

https://itunes.apple.com/jp/app/runtastic-sleep-better-mu/id922541792?mt=8&uo=4&at=1010l7Ba

なんとなくアプリに Orbit を足すとより精緻なデータが取れるようになると思ってしまいますが、そうではなくあくまで別アプリの別データとして管理されます。

Runtastic の各種アプリで記録されたデータはポータルサイトから確認することができます。

f:id:beniyama:20151003163445p:plain

走行距離や消費カロリーの記録、また体重・体脂肪率の変遷を可視化したりもできます。

f:id:beniyama:20151003163501p:plain

ちなみにこれは自分の実際のログです。体重・体脂肪率は記録するタイミングによって結構ぶれるのであまり綺麗なグラフではないですが、とはいえ運動開始時より着実に落ちてきている実感はあります。

この体重・体脂肪は体重管理アプリ Runtastic Libra で記録できるのですが、ワイヤレス体重計 Runtastic Libra(同じ名前です)を使うと体重計に乗るだけで自動的にデータを飛ばしてくれ、かつ筋肉量や骨質量といった値も取れるようです。

https://itunes.apple.com/jp/app/runtastic-libra-ti-zhonggurafu/id694034625?mt=8&uo=4&at=1010l7Ba

しかしながらこの体重計、日本語の案内はあるものの公式ストアに行くと日本からの購入に対応していないらしく購入することができません。他のサイトで取り扱っているところもあるようなのですがだいぶ高い気がするので、自分は体重・体脂肪率を手打ちで入力しています。

現状、連携したアプリのデータをまとめて見られます程度でデザインだったりデータの見せ方だったりはまだ改善の余地があるものの、そもそも運動や体の状況の可視化をしたことがない人にとっては十分生活習慣の改善のきっかけになりうるサービスだと思います。

もう少し効果が出始めてきたら個別アプリのレビューを書いていきたいです。

OS X El Capitan にアップデートして App Store などに繋がらなくなった時の対処法

App Store からカジュアルに OS アプデできるようになったのは良いのですが、Apple のアプデは危険ということを忘れうっかりポチッとすると人柱真っ逆さまだよというお話です。

仕事を終えてふと愛機を El Capitan に更新した直後から挙動がおかしくなり、

  • CPU 使用率が異常に高くなりファンが止まらない
  • Office 365 のログインページなど特定のサイトに繋がらない(その後はブラウザを再起動しないと他のサイトにも繋げなくなる)
  • 挙げ句の果てには App Store に繋がらない(= 修正版リリースされてもアプデできない!\(^o^)/)

となってちょっと途方に暮れていたのですが色々調べていくと SSL 周りの不具合だということがわかり、結論としてはキーチェーンで証明書の使用ポリシーを変更することで解消できました。

「キーチェーンアクセス」を立ち上げ、左上の項目(キーチェーン)で「システムルート」を選択。VeriSign を検索します。

f:id:beniyama:20151002233740p:plain

ここで表示された証明書を片っ端からダブルクリックで開き、「▶︎信頼」を展開して「この証明書を使用するとき」を「システムデフォルトを使用」に変えます。

f:id:beniyama:20151002234125p:plain

これで App Store などにつないでみて正常に表示されれば、ひとまず危機的状況は脱出したっぽいです。

参考になったのはこれらのポストでした。

forums.developer.apple.com

forums.developer.apple.com

ちなみに Safari や Chrome では上記のサイトも見られなくなってしまうのですが、自前で証明書を管理している Firefox だと今回の問題の影響を受けません。

症状も改善したのでスクショとって意気揚々と記事あげようとした間際、すでに昨夜のうちにえふしんさんがさらっと書かれていたことに気づいたのですが、せっかくなのでこのまま公開しちゃいます。

f-shin.net

自分の場合は VeriSign の証明書を変更するだけで App Store につながったので、このケースより楽でした。

Mac でコーディングする人は「スマート引用符とスマートダッシュ」を OFF にしようという話

突然ですが問題です。

下記の一見同じに見える二つのクエリ、実は意味が異なるのですがその違いがわかりますでしょうか?

-- クエリ1
SELECT * FROM customers
WHERE customer_id IN ('0001', '0002', '0003', '0004');

-- クエリ2
SELECT * FROM customers
WHERE customer_id IN ('0001’, ’0002', '0003', '0004');

これでわかったらかなりの選球眼の持ち主です。

それでは試しにシンタックスハイライトをかけてみましょう。

-- クエリ1
SELECT * FROM customers
WHERE customer_id IN ('0001', '0002', '0003', '0004');

-- クエリ2
SELECT * FROM customers
WHERE customer_id IN ('0001’, ’0002', '0003', '0004');

いかがでしょうか?これでもよく見ないとわからないと思います。

正解は、クエリ1の customer_id の一致条件が 00010002000300044パターンなのに対し、クエリ2は 0001’, ’0002000300043パターンだということです。よく見るとクエリ2の IN 句内の最初のカンマが文字列の一部になっているのがわかると思います。

明らかに意図したクエリになっていないのですが、なぜそもそもこんなことが起きるかというと問題は Mac 標準の入力サポート機能にありました。

「システム環境設定」から「キーボード」を開くと「ユーザ辞書」のタブ内に「スマート引用符とスマートダッシュを使用」という項目があります。

f:id:beniyama:20150924232105p:plain

これが ON になっているとテキストエディタなどで SQL を編集した際に勝手にシングルクォーテーションや二重引用符を変換されてしまい、予期せぬ意味のクエリになってしまう可能性があります。

https://support.apple.com/kb/PH14294?locale=ja_JP&viewlocale=ja_JP によれば

まっすぐな引用符を体裁上適切な(「丸い」)引用符に自動的に置き換えます。

とあります。体裁上は適切かもしれませんがコーディング上は不適切なわけです。

自分のケースでは軽く Evernote 上でコピペと編集を繰り返しているうちに、上述のようなエラーにはならないんだけど意味が違うクエリが生まれてしまいました。検算して初めて問題と原因に気づいたので軽く冷や汗かきました。

ちょっとしたクエリなどは手元のエディタで編集して〜とやりたくなりますが、Mac を使われる場合はその前に一度キーボードの設定を見直そうというお話でした。

参考)

「学習ビッグデータ分析(LA:Learning Analytics)最前線 - グローバルな最新情報と学習理論からの考察 -」聴講メモ

先日、教育分野におけるビッグデータ分析の最先端トピックの紹介があるということで、表題にあります Asuka Academy 様主催のセミナーに参加してきました。

講演資料や動画は全て下記のサイトにて公開されています。

www.asuka-academy.com

放送大学の山田恒夫先生上智大学の田村恭久先生より講演がありましたが、両セッションを通して個人的に学びになったポイントおよび追加調査した事項を下記にメモしておこうと思います。

学習とは
  • 個体発生における環境への適応過程 (Adaptation)
    • 系統発生における適応は進化
Learning Analytics (LA) について
  • 定義 : Learning analytics is the measurement, collection, analysis and reporting of data about learners and their contexts, for purposes of understanding and optimizing learning and the environments in which it occurs.
  • 上流は配信、中流が LMS を使った学習ときて、下流が解析(= LA のフォーカス)
    • LMS (Learning Management System) : 学習教材の配信や成績の管理などを行うための学習管理システムのこと
  • フィードバックは学習者だけでなく指導者に対しても行われる
  • 認知の観点からみた学習スタイルの違い
    • Holist : 全体の構成の理解から入る(トップダウン)
    • Serialist : 逐次的に詳細を処理していく(ボトムアップ)
  • LA のアウトプット(一部抜粋)
    • Recommendation : 単元を戻って再学習を促すなど
    • Adaptation : 個々の特徴に応じた教材の組み替え
    • E-Portfolio : 学習者がどんなことができるようになったのかという証明
    • Prediction : 単位を落とした学生が留年・退学する確率の算出(大学運営の観点からも重要)
  • クライアントサイドのデバイス普及・技術進化により LMS では取得できなかったユーザの行動を記録できるようになった
    • ページめくりや心拍などの生体情報
  • 学習過程を記述し、再利用性を高めることで実験計画法による仮説検証の限界を超えられる可能性がある
    • ビッグデータ解析によるアプローチ
  • LA のデータ項目に関する規格
    • xAPI (Experience Application Programming Interface) : LMS ありきの学習に縛られずに多種多様な学習活動の履歴を記録・検索・抽出するための技術仕様。従来の e-learning システムの相互運用性を高めるために規定されていた SCORM (Sharable Content Object Reference Model) ではカバーできないユースケースを補完するために定義されている。
    • IMS Caliper : LA のフレームワーク。69 + 23 項目の例
    • 文科省・電通(非公開)
    • EDUPUB LA : 44 項目
情報源
参考

オレゴンに作ってしまった EC2 インスタンスを東京に移した話

自己紹介用のサイトをオレゴンに作ってしまった

大学で研究していた頃にいろいろな作品を製作していたのでそのポートフォリオサイトを作っておこうと思ったのですが、AWS の使い方をよく調べずにうっかり米国西部(オレゴン)リージョンにインスタンスを立ててしまいました。

f:id:beniyama:20150707181131p:plain

メニューは一緒でもまずリージョンを切り替えてから操作をしなければならないことに気づいたのは一通り起動し終わった後でした \(^o^)/

ちなみにオレゴンの場所はここだそうです。

流石に太平洋の距離は馬鹿にできなかったようで、日本からサイトを表示しようとすると画像の読み込みは目に見えて遅いですし、コンソールで操作しようとするとコマンド打って帰ってくるまでに明らかな遅延を感じていました。

英語コンテンツだから良い気もしていたのですが、日本からのアクセスの方が多いこともありましたので今回東京リージョンに移行することにしました。

移行対象となったサイトはこちらです。

beniyama.com

ほとんど静的&コンテンツの重要性も低いので冗長構成もとらず Web/DB/PHP (Wordpress) が1インスタンス (t2.micro) に収まっています。

リージョンをまたいだインスタンスの移行を試みる

インスタンス移行について調べてみると存外簡単にできそうな感じでした。

特に参考にさせていただいたのはこちらのサイト。

http://shakezoomer.com/?p=317shakezoomer.com

大まかな流れはこんな感じ。

  1. オレゴンでスナップショットをとる
  2. オレゴンから東京へスナップショットをコピー
  3. 東京でスナップショットからイメージを作成
  4. 東京でイメージからインスタンスを作成

とくにカーネル ID が大事!と書かれていたので移行元のインスタンス情報に目を凝らして見ますが

f:id:beniyama:20150707192112p:plain

ない!わからない!

疑問に思いつつもとりあえずデフォルトカーネルのまま立ち上げてみますが、上記サイト中でも言及されているカーネルパニックを起こして死んでしまいます。

ec2 Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block

この後 Amazon EC2 CLI Tools をセットアップして カーネル ID を調べよう と試みましたが

$ ec2-describe-instance-attribute INSTANCE_ID --region us-west-2 --kernel

kernel INSTANCE_ID

とかなってやっぱりカーネル ID がわかりませんでした。そもそも CLI でわかるものはコンパネからもわかる様子。

そもそも仮想化タイプが違っていた

詰まってしまったので再度調べまわっていると同じように困っている人に遭遇。

stackoverflow.com

上記のようにカーネル ID を調査する方法を薦めていた人のコメントに追記があり、

edit: Just noticed this is an HVM; Not sure why you would want to make an image from a snapshot. If you create an image directly from the ec2 it will also create snapshots for you and then you can go to AMIs and make a new ec2 from the image you created and it will not ask for a kernel ID.

そもそも仮想化のタイプが HVM の場合はカーネル ID は関係なさそうな様子のことを言っています。もっと言うとスナップショット経由の必要はないとも。

そこで先ほどのインスタンス情報を確認してみると確かに HVM となっています。

f:id:beniyama:20150707192116p:plain

そして参考にさせていただいたサイトをよく読むと

SnapshotからAMIをつくって、ということをせずに、AMIをそのままコピーしてやればもっとすんなりいけました。

という追記を発見。

確かに手順を振り返ってみると、スナップショットからイメージを作成する際にカーネル ID に加えて仮想化タイプを指定する項目があります。

f:id:beniyama:20150707194502p:plain

ここで「準仮想化」ではなく「ハードウェアアシストの仮想化」を選んでカーネルはデフォルトのままで立ち上げたところ、少し時間はかかりましたが無事インスタンスを作成することができました。

スナップショットからイメージを作るべきではない

改めて手順を振り返ってみると、上述のコメントや追記にもあったように

  1. オレゴンでイメージを作成
  2. オレゴンから東京へイメージをコピー
  3. 東京でイメージからインスタンスを作成

とした方が上述の仮想化タイプの選択とか気にしなくて良いので確実です(イメージ作成時に自動的にスナップショットも作成されます)。

下記の「Amazon Machine Image (AMI) とスナップショットの違い」にもスナップショットからイメージ (AMI) を作成した場合、

アーキテクチャやカーネルの選択を誤ると正しく起動してこなかったり、動作が不安定な AMI が出来る可能性がある

とあります。

aws.typepad.com

仮想化タイプを問わず、インスタンス移行はイメージのコピーで実施した方が良さそうです。

HVM とはなんだったのか

余談になりますが準仮想化 (para-virtual VM) とハードウェアアシストの仮想化 (hardware-assisted VM) についてはこちらに詳しく書かれています。

docs.aws.amazon.com

HVM AMI は、完全に仮想化された一連のハードウェアを備えており、イメージのルートブロックデバイスのマスターブートレコードを実行することによって起動します。

PV AMI は、PV-GRUB と呼ばれる特別なブートローダーを使用して起動します。

HVM でカーネル ID が必要なかった理由は PV-GRUB というブートローダの仕組みに関係がありそうです。

Enabling User Provided Kernels in Amazon EC2 の「PVGRUB: A New Amazon Kernel Image (AKI)  」によれば、

To enable user provided kernels, Amazon has published AKIs that use a system called PVGRUB.  PVGRUB is a para‐virtual “mini‐OS” that runs a version of GNU GRUB, the standard Linux boot loader. PVGRUB selects the kernel to boot by reading /boot/grub/menu.lst from your image. It will load the kernel specified by your image and then shut down the “mini‐OS”, so that it no longer consumes any resources.  One of the advantages of this solution is that PVGRUB understands standard grub.conf or menu.lst commands, allowing it to work with most existing Linux distributions.   

とあり、 AKI に PV-GRUB 対応のものを指定することでそこから grub.conf / menu.list を読んでユーザが指定したカーネルを読ませることができるようになる、とあります。AWS 初期ではそもそもユーザがカーネルを改変することができなかった(AKI として別に管理されていた)という背景があるようです。

HVM はそもそも AKI を使わない = PV-GRUB AKI のカーネル ID が要らない という理解で良いのかなと思います。

docs.aws.amazon.com

Cluster AMI は PV-GRUB をサポートせず、また、必要としません。完全ハードウェア仮想化(HVM)が使用されるためです。準仮想インスタンスは PV-GRUB を使用して起動します。一方、HVM インスタンスボリュームは実際のディスクのように扱われ、その起動プロセスはパーティション分割ディスクとブートローダーを備えるベアメタルオペレーティングシステムの起動プロセスに似ています。

と書かれているように、物理マシンの直上に Linux をインストールしたときのようにイメージ内のブートローダから直接上がってくるとのことです。

詳しくは下記のサイトが参考になります。

kanny.hateblo.jp

まとめ
  • インスタンス移行はスナップショットから起こさずイメージで。
  • 仮想化タイプを確認する。HVM の場合はカーネル ID を気にしなくて良い。
  • システムログが真っ黒なときはまだ起動中。しばらく SSH できなくても辛抱強く待つ。

と書いていて、準仮想化のイメージをリージョンをまたいで移した際に、PV-GRUB AKI のカーネル ID の変換は誰がやってくれるのか疑問に思いました(同じカーネルでもリージョン間で ID は変わるため)。

転職します

3年3ヶ月働かせていただいたGMO インターネット株式会社を退職し、また別の事業ドメイン x エンジニアとしての役割にチャレンジすることにいたしました。

思えば元々 Nokia で組み込み系の研究職に従事した後一度大学に戻り、今度は何の経験もない Web の業界で働きたいと宣う奇特なミドルエイジを躊躇いもなく採用し、今日に至るまで育て上げてくれた次世代システム研究室には大変感謝しております。

個人的には今年のデブサミでの登壇発表が一つの節目であり、また手広く遊んでとっちらかりっぱなしの自分のスキルセットと今後の方向性を考えるきっかけの場でもありました。

beniyama.hatenablog.jp

これまでは初学者として良くも悪くも何の技術を触っても面白かったのですが、その結果どれだけの価値を社会にもたらすことができていたのか?と自問したとき、そろそろアプローチを変えなければいけないという思いを強くしました。

その結果が今回の転職なのですが、ポイントは教育というドメインに集中(フルコミット)することの一点に尽きます。組織横断の部署で様々な事業に携わった経験は間違いなくスキルの底上げになったのですが、一方でドメイン・体制・制度・取り組みを含めた没入感の限界も感じていました。技術とはまた違うレイヤーからの本質的なものづくりをしていくとき、この没入感は必須であると考えています。

ちなみに7月一杯はお休みして、8月から次の職場で働き出す予定です。昨日は色々な方にご挨拶させていただいたのですが、GMO のスタッフの方達は本当に気持ちの良い人がとても多い、という思いを新たにしました。また勉強会や金夜のバータイムなどで遊びに行けたらと思います。

3年前に採用面接受けた際に RoR でオンライン麻雀作りたいですって言って全然作ってなかったことを思い出したので、もしかしたらこの機会に着手してみるかもしれません。今後ともブログ共々どうぞ宜しくお願い致します。

f:id:beniyama:20150630232610j:plain