2015-01-20

Dokku Alternative触ってみる。

Dokku AlternativeというOSSを使うと、Dockerを利用して

herokuみたいなPaaSを作れるということなので試してみましたー。

Dokku Alternativeは本家のDokkuに色々と機能を追加したOSSみたいです。

 

参考URLはこちら↓

Dokku Alternative·個人用PaaSにどうぞ。Dokkuに便利な機能を追加 MOONGIFT

Herokuのように簡単に使えるDockerベースのPaaS | KRAY Inc

Dockerを使ったミニPaaSのdokkuをパワーアップさせた「Dokku Alternative」を試す - さくらのナレッジ

 

今回はまっさらなVMに入れてみます。

1. Ubuntuインスタンスを立ち上げる

今回はDigitalOceanで立ち上げました。

スペックはメモリ512MBの一番安いプランで、OSはUbuntu 14.04x64を選択。

Dokku-altはUbuntu 14.04 LTSにしか対応してないっぽいです。

dokku-ubuntu-digitalocean

立ち上げたら、セキュリティ系の諸々の初期設定をした後、スワップファイルの設定をしてください。

これをしないとメモリ不足でインストールがコケます。

$ sudo dd if=/dev/zero of=/swap bs=1M count=2048
$ sudo mkswap /swap
$ sudo swapon /swap

設定したら、以下のコマンドでswap領域が有効になっているかを確認

$ cat /proc/swap

/etc/fstabにも登録しておきます

/swap swap   swap    defaults   0 0

2. Dokkuのインストール

インストールは超簡単で以下のコマンドを実行するだけ。
$ sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/dokku-alt/dokku-alt/master/bootstrap.sh)"

インストールが成功すると初期設定用のサーバが立ち上がるので

http://{サーバーのIP or ホスト名}:2000にアクセスして設定を行います。

dokku-setup

IPアドレスだとアプリに対してサブドメイン形式のURLをアサインできません。

DNSレコードを設定するか、hostsファイル弄るかでホスト名でアクセスできるようにすれば

サブドメイン形式({アプリ名}.{サーバーのホスト名})が利用できます。

公開鍵は、git pushするときのsshの秘密鍵に対応する公開鍵を入力すればOK。

設定はこれだけ!

3. アプリをpushしてみる。

あと、テキトーなアプリをpushすればデプロイできちゃいます。
$ git clone https://github.com/heroku/node-js-sample
$ cd node-js-sample
$ git remote add dokku dokku@{2で指定したサーバのホスト名}:{アプリケーション名}
$ git push dokku master

デプロイすると、http://{アプリケーション名}.{2で指定したサーバのホスト名}のURLでアクセスできます。

 

アプリはdockerで動いているので、デプロイするとdockerのインスタンスが立ち上がっているのを確認できます。

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bd1faad04454 dokku/dev:deployed "/start" 4 days ago Up 4 days 5000/tcp app_dev_1421028899_25215

サーバにリモートログインしてdokkuコマンドを叩くと、アプリの作成や削除、DBインスタンスの作成等

dokkuのアプリ設定を色々と弄れます。

4. 管理用コンテナを作成する

このままでもgit pushだけでデプロイできる素晴らしい環境なんですが

DBコンテナ作って既存のアプリに紐付けたり、既存のアプリを削除したりするには

CUIでの操作になるため、ちょっと面倒です。

幸いdokku-altには管理画面用のコンテナがあり、以下のdokkuコマンドでインストールできます。

$ dokku manager:install

インストールがうまくいくと、http://dam.{ホスト名}のURLで管理画面UIにアクセスできます。

最初はUserが居ないとエラー画面が表示されるので

サイドメニューのUsersの[Add User]ボタンから、適当にユーザを作成して、ログインを行います。

dokku-manager-first

dokku-adduser

ダッシュボードを開くと、ホストサーバが表示されているので、設定マークをクリックします。

※Deploy New Appは押しても何も起こりませんでした…。

dokku-dashboard

Sync Appsを押すと、既にデプロイされているアプリと管理アプリ自体のコンテナが表示されます。

dokku-hosts

ここでアプリケーションの追加・削除したりできます。

Deploy Git Appで任意のgitリポジトリからデプロイ出来そうな雰囲気ですが

鍵の設定がよくわからず、断念orz

dokku-gitapp

よく見ると、Webhookはこれから対応するような文言が見当たるのでCIとかにも対応しそうな感じ。

 

今回は先ほど作成したnodeアプリのコンテナにMongoDBのコンテナをつなげてみます。

まずは、Add DBからDBコンテナを作成します。

dokku-adddb

初回はDBコンテナのイメージを取得するせいか、Ajaxのタイムアウトエラーが出たんですが

その場合でもちゃんとコンテナが作成されていました。

DB用のコンテナ作成後は対象のアプリのリンクをクリックします。

dokku-dev1

Add DB Linkをクリックして先ほど作成したMongoDBのコンテナとリンクさせます。

dokku-addlink

これでNode.jsのアプリからMongoDBに接続することが可能になりました。

接続情報はサーバ側で以下のコマンドを叩くことで確認することが可能です。

(もしかしたらGUIでの方法もあるのかも)

$ dokku config {アプリ名}
=== dev config vars ===
MONGODB_URL: mongodb://dev:U8zy3nCOdgRGObei@mongodb:27017/mongo-test

接続情報をソースにベタ書きするのはアレなので、コンテナ内の環境変数にセットします。

Add Configからキーバリューで値をセットします。

dokku-setdbconfig

こんな感じになります。

dokku-aftersetdbconfig

あとはソースコードの修正をします。

まずはNode.jsからmongo叩くためにパッケージをインストール

$ npm install --save mongodb

こんな感じでindex.jsを修正

var express = require('express')
var app = express();
var mongo = require('mongodb');
var db = new mongo.Db(process.env.MONGODB_DATABASE, new mongo.Server(process.env.MONGODB_HOST, mongo.Connection.DEFAULT_PORT, {}), {});

app.set('port', (process.env.PORT || 5000))
app.use(express.static(__dirname + '/public'))

app.get('/', function(request, response) {
  db.open(function() {
    db.authenticate(process.env.MONGODB_USERNAME, process.env.MONGODB_PASSWORD, function(err, result) {
      db.collection('robots', function(err, collection) {
        doc = {
          "Name" : "Rapiro"
        };
        collection.insert(doc, function() {
          console.log("insert success");
          db.close();
          response.send('Mongo instance created!!');
        });
      });
    });
  });

});

app.listen(app.get('port'), function() {
  console.log("Node app is running at localhost:" + app.get('port'))
})

あとはgit pushすると新しいアプリが立ち上がって

WebアプリにアクセスするとMongoDBにレコードが差し込まれます。

コマンドラインからMongoDBにアクセスするには

$ docker ps

でMongoDBの対象コンテナ(イメージ=ayufan/dokku-alt-mongodb)のIDを確認して

$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' {コンテナID}

でコンテナのプライベートIPアドレスを取得。

あとはプライベートIPを使って、MongoDBに接続すればOK。

$ mongo -u {ユーザ名} -p {パスワード} {取得したIPアドレス}/{データベース名}

こんな感じでドキュメントを取得できます↓

> db.robots.find()
{ "Name" : "Rapiro", "_id" : ObjectId("54b3dbce23cb651800ad53b4") }

5. SSLの設定

Dokku-altの管理画面ですが、デフォルトのままだと非SSLで

クレデンシャル晒している状態なのでSSL対応します。

今回は検証用ということで、オレオレ証明書で。

$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt

キー、証明書を作ったら dokkuコマンドで、管理用Webアプリに登録します。

$ cat server.crt | dokku ssl:certificate dam
$ cat server.key | dokku ssl:key dam

keyを登録した時点でコンテナが再起動してSSLが有効になります。

その他注意点

以下のようにdokkuコマンドを使ってアプリ再起動したときには

dockerのコンテナは起動しているものの

フォワーディング(ホストOSのnginxで受け取ってコンテナにフォワーディング)の設定が

されないようで、アクセスしようとすると500エラーが返って来てしまいます。

$ dokku stop app
$ dokku start app

この場合は、以下のコマンドでリビルドすれば、適切にフォワーディングされるようになりました。

$ dokku rebuild:all

 感想

dokkuはシングルホストなのでスケールしないし、可用性的に問題が有ったりするので

商用には厳しい感じですが、アプリを検証したりプロトタイプ作ったりするような

簡単な用途には有用な気がします。

DigitalOceanの$5/monthのプランでもそれなりに動いていますし。

herokuとかのPaaSに移行するとしてもremoteリポジトリ変えるだけなので楽ちんです。

ただしherokuと違ってスケジューラやone-offなコンテナはありません。

ホスト側自由にいじれるんで、どうしても使いたい場合はcronとかシェルで対応しちゃえばOKですw

このエントリーをはてなブックマークに追加