35歳からの中二病エンジニア

社寺・鉄道・アニメを愛でるウェブ技術者の呟き

OpenShift難民が自分用PaaSを作った話

個人ウェブサービスをOpenShift v2で無料運用していたのだが、残念ながら2017年9月でサービス終了の運びとなった。v3やHerokuではコスト的に複数サービスを回すのが辛いので、これを機会に自前のPaaSを構築することにした。

やりたいこと

  • 小規模な個人サービス4つを¥1,000/月以内で運用
  • うち1つはRails+MySQL、1つはPHP+MySQL、残りはPHPのみ
  • git push でデプロイ(OpenShift v2やHerokuと同様に)

IDCFクラウドでDokkuなら楽勝のはずが

条件に合う事例として、次の記事がすぐに見つかった。

muunyblue.github.io

IDCFクラウドの最小構成は¥500/月で安いし、DokkuはミニHerokuとして使えそうだ。この記事はIDCF公式のBlogでも紹介されていたこともあり、そのまま従っていけば楽勝だろうと高をくくっていた…のだが。

確かにDokkuの公式ドキュメントとこの記事を参考にしてスムーズにappを構築していけたのだが、3サービス目のappを立ち上げた所でストレージの空きが0%になってしまった。

何が問題だったのか

DokkuはHerokuと同様に、コンテナ管理にはDockerを使用している。そのベースイメージとしてherokuishを利用しているのだが、これが曲者で、なんとイメージサイズが1.35GBもあった。MySQLのイメージも400MB近いし、加えて色々な実験をするうちに15GBのストレージを全て食ったようだ。

なお、現状のherokuishはHerokuのイメージであるcedar-14をベースとしているが、最新のheroku-16では465 MBまでスリム化されているようだ。とはいえ、Dokkuでいつ採用されるかは不明であるし、採用されたとしてもDockerイメージとしてはまだ巨大なため、別のやり方を検討することにした。

どのように解決したか

Dokkuの公式ドキュメントにDockerfile Deploymentとあるように、自前のDockerfileもデプロイに使えるということで、試してみることにした。

今回はストレージを食わない事を優先したかったのと、複数コンテナの連携をうまくDokkuで実現できるのかという懸念があったため、邪道とは思いつつもPHP-FPMとnginxを同一コンテナで立ち上げる最小限のイメージを作ることにした。以下がそのDockerfileの内容である。

FROM php:7.1-fpm-alpine

RUN curl -sS https://getcomposer.org/installer | php \
    && mv composer.phar /usr/local/bin/composer \
    && docker-php-ext-install \
        mbstring \
        pdo_mysql \
    && apk add --update --no-cache \
        nginx \
    && mkdir -p /run/nginx \
    && echo -e "#!/bin/sh\nphp-fpm -D\nnginx -g 'daemon off;'" \
        > /usr/local/bin/php-nginx \
    && chmod +x /usr/local/bin/php-nginx

EXPOSE 80

CMD ["php-nginx"]

Alpine Linuxにしたこともあって、イメージサイズは70MBほどに収まった。なお、一応イメージはDocker Hubにも公開している。

このイメージをベースに(Railsのサービスについては既存イメージを使用)各appを構築したところ、特にハマる事も無くDokku上に展開できた。気になるストレージの使用率は35%程度で落ち着いている。メモリーの使用率が80%近くなってはいるが、こちらはswapを1GB確保しているのでひとまずは問題無いだろう。

おわりに

安価なクラウドやVPSで自前PaaSを構築する事例は多々あり、いずれもメモリーを確保する事に注意を促しているが、実際に複数サービスを運用するとなると、留意すべきはむしろストレージの方であった。

Dokkuの場合、自前のDockerfileも使えるため、スリムなイメージを用意すればストレージの小さい環境でも複数サービスを運用できそうである。小規模な個人サービスを複数運用しているのであれば検討しても良いかもしれない。