あんパン

こしあん派

AndroidではCSSの:activeが使いづらい話

割と一般的なのかもしれないけどつい最近知ったネタなので共有します。

CSSには:activeという擬似セレクタがあって、要素をクリックしている間だけ特定のスタイルを有効にすることができます。スマートフォンのブラウザにも当然この:activeは存在しており、タップすることでスタイルを有効にすることができます。

ところが、AndroidのChromeのみ若干挙動が異なっており、:activeが使いドコロの難しい機能になっています。というのも、タップではなく長押ししないと有効にならないのです。

stackoverflow.com

The :active pseduo works on Chrome for Android, but only after a long press (and cancel of the dialog), it doesn't work for any other element as far as I can tell. It looks like a bug, and I have just raised it with the team.

とのことで、この raise it は

173976 - :active pseudo class does not work on Chrome for Android - chromium - Monorail

を指しています。どうやら

<meta name="viewport" content="user-scalable=no, initial-scale=1">

をheadタグ内に記述するか、または

<body ontouchstart="">

とすると解決するらしいのですが、これはあまりにも汚いハックだと思います。(しかも前者はコードの有無で挙動が変わってしまう)

が、せざるを得ないという状況もあるため覚えておくと良さそうです。なお、JavaScriptでontouchstartontouchendontouchcancelを拾うとかをするのも良さそうです。

とはいえ、押下時にスタイル変更範囲がならユーザが気づかないということもあるため、そこまでコストをかけてやるべきことかという疑問は残ります。やる気と時間があるならやってもよさそうというスタンスでいるべきと思いました。

iOSのSafariはselection.removeAllRangesの挙動がおかしい

selectionwindow.getSelection()で取得することができます。

通常のウェブブラウザだとselection.removeAllRanges()を実行すると選択範囲が解除されます。iOSのSafariではこれが解除されずに残ります。

また、selectionrangeCountという選択範囲の数を保持するプロパティがあり、通常は選択が解除されるとこれが1から0になります。iOSのSafariではselection.removeAllRanges()を実行すると選択範囲は解除されないままrangeCountが0になります。.toString()の結果も空文字列となります。

同様に、addRangeでrangeを追加すると選択範囲が変更されないままrangeCountが1になります。

ざっと調べましたがどうも解除方法はない(結構前から質問は上がっているがまともに動く回答がない)ようなので、各位頑張っていきましょう。

jQueryでtext-overflow: ellipsisの中抜きみたいなことをする

CSSでボックスに収まりきらないテキストを三点リーダとかで省略するやつあって、文字列の先頭か末尾しか省略できない。真ん中を省略したかったのでjQueryのプラグインとして書いた。

github.com

割と雑で、なんとなくコード読んだら使えると思う。

f:id:masawada:20150824174225p:plain

f:id:masawada:20150824174223p:plain

こういう感じなのでうまくやってほしい。

dev.classmethod.jp

若干これ参考にしてて、なんかうまく動かなかったので自分で書いたという感じ。CSS使えばいいけど一応先頭と末尾もカットできるはず。

dokku環境を作ってStartSSLでhttps化するまで

Heroku使ってますか。Heroku便利なんですけど、最近無料版だとコンテナを24時間upし続けることができなくなりました。

まぁたいていの実験的なWebAppならなんとかなるんですけど、Twitterのupdate-name(なんかのツイートをトリガーに自分の名前変えるやつ)とかSlack用のHubotとか24時間監視系のアプリを常時立ち上げするのが難しくなりました。

7ドルくらい支払えよという気持ちもわかるのですが、何分金欠なので別のソリューションが欲しいところです。

dokkuというものを使うとHerokuとほぼ同様な感じでアプリケーションをデプロイできて便利なのでその話をします。

dokku

dokkuは200行くらいのBashで書かれている(実際は依存ファイルとかツール群があってそれに助けられてる)PaaS環境みたいなやつです。Dockerをベースにしていて、gitでpushするとよしなにデプロイしてくれます。中でheroku-buildpackというのを使っていい感じにビルドしてくれます。なので、デプロイするときもHerokuみたいな出力がでてきます。

dokkuの環境を作るにはここの指示に従えば良いです。 Dokku - The smallest PaaS implementation you've ever seen

Nginxの設定とかを豪快に吹っ飛ばすのでまっさらな状態のUbuntu 14.04にインストールする必要があります。まああとはよしなにやるととりあえずデプロイできるようになります。ドメインが1つ必要で、サブドメインごとワイルドカードでdokkuホストに向ける必要があります。

StartSSL

Let's Encryptとかいう無償のSSL証明書発行サービスが11月くらいにでるのですが、ワイルドカード証明書は取れないのでStartSSLでワイルドカード証明書をとります。Let's Encryptは取得も自動化できるのでpushをhookして証明書を取得すればなんとかなるという気もしますが、Nginxのconfを動的に書き換えてリロードする必要があり、やはり面倒なのでワイルドカード証明書をとることをオススメします。

StartSSLは基本的に無料でSSL証明書を取得できますが、ワイルドカード証明書をとるにはPersonal Identity Verificationというものを受ける必要があります。これを受けるには59.90ドル/2年かかり、かつ個人を証明するための書類(顔写真/誕生日/住所が記入されている)が2セット、携帯または固定電話の請求書(氏名/住所/電話番号が記入されている)が必要になります。最初の書類はアップローダでアップロードしますが、以後はメールでやりとりする必要があります。当然英語です。

電話の請求書を送ると、その番号に電話が来ます。相手はちゃんと人間で、名前の確認と誕生日、住所を質問されます。うまく答えられると3時間くらいでapproveされるという話を聞かされます。

英語が苦手な人は請求書がないみたいな話をすると国際特殊通常書留でverification codeが送られてきて、Webで入力するとなんとかなるという噂です。が、これを選択すると全プロセスを終えるのに15日前後かかるため受け答えができるのであれば電話の請求書を送ったほうが早いです。

あと、StartComの人は国際電話に慣れてないらしく、電話をかけられないというメールを送ってくることがあります。

www.howtocallabroad.com

ここのURLを投げつけてexit codeとか確認して電話してくれみたいな話をするとうまく電話がきました。

approveされると通常のSSL証明書取得プロセスと同様の手順でワイルドカード証明書(サブドメインが*の証明書)を取得できるようになります。

これを

ここらへんを参考によしなにやるとdokkuをhttps化できます。

まとめ

以上の手順でさくらのVPS 2Gプランにdokkuをインストールしました。普通にupdate-nameをデプロイしただけだとメモリ使用量が5%くらいでとても快適です。

dokku自体、WebUIがない、スケールができない、マルチテナント/マルチユーザ(アクセス制御)ができないなどいろいろな不便な点はありますが、単純に個人的に使うのであればProcfileを書けばシュッとデプロイできるので、これ以上ない環境だと思います。興味のあるかたはぜひ構築してみてください。

GitLabをOmnibusからmanual installに移行する

サーバまるごと移行する話です。

社のサーバでGitLabを運用しているのですが、GitLabとGitLab CI以外にもSlackのロガーやwiki等のサービスが走りまくっており常にスワップが発生する状態でした。加えてGitLab CIの機能の少なさ、障害が発生した時にGitLab Omnibusではどこに問題があるのかわかりづらい(ログが追いづらい)などの問題があったため

  • サーバを新調
  • GitLabをインストール
  • GitLab CIを廃止してJenkinsに移行

という作業を行いました。幸いなことにGitLab CIは使いづらいためあまり使われておらず、CIについては単純に新たにJenkinsを導入するだけで済みました。

基本的には以下の2つのページを参考にすると移行することができます。

http://blog.innobase.co.jp/entry/2014/09/15/174228blog.innobase.co.jp

gitlab.com

手順としては

  1. 移行元のGitLabを最新版にする
  2. 移行先にGitLabの最新版をインストールする
  3. 移行元で全データをバックアップする
  4. 移行先にバックアップを移動してリストアする

になります。バックアップファイルがどこに出現するか、リストア時にどこに置くかなどは自分で調べてください。リストア時に置く場所はその環境(Omnibus or manual install)でバックアップファイルが作成される場所です。

この作業中に少し躓いたのでメモしておきます。

rbenvを使わない方が良い

移行にあたってItamaeで1コマンドでデプロイされるようにしました(かなり雑に書いたので整理する余裕ができるまで公開はしないつもりです)。最初はrbenvを使ってRubyをインストールしていましたが、いろんなところで躓く上にsudoersを書き換えるなどして環境変数を引き継ぐ必要が発生するなどお世辞にも綺麗とはいえないデプロイになるためrbenvを諦めました。そもそもGitLabのためにRubyを入れるので、今後バージョンを上げたいなどの欲求があれば今回と同様にサーバをまるごと移行した上でRubyのバージョンを挙げてしまえば問題ないと考えています。

各レポジトリにhooksへのsymlinkが含まれていてこれが壊れていることがある

この問題はOmnibus→manual installまたはmanual install→Omnibusで発生するものです。各リポジトリにpush時のhookスクリプトを格納するディレクトリへのsymlinkがあります。この実態はgitlab-shell/hooksであり、そのパスはOmnibusの場合とmanual installの場合で異なります。バックアップをとったリポジトリ内には移行元の環境のsymlinkが含まれているため、移行先によってこのsymlinkを作り直す必要があります。手動でやってもスクリプトを作っても問題ないと思います。今回はリポジトリの数が少なかったため手動でsymlinkを貼り直しました。

壊れているかどうかを確認するのは簡単で、sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=productionを実行したときにErrno::ENOENT: No such file or directory @ realpath_rec - /opt/gitlabというようなエラーを吐いていたら壊れています。


以上2点が主な躓いた点です。rbenvに関してはもはや常識といえるのかもしれませんが、結構扱いに慣れていたつもりでも面倒だったので少々残念でした。

今回のサーバ移行でGitLabがかなり快適になったので今後の開発にも力が入りそうです。