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

自分でHerokuライクなシステムを立ち上げられるdokkuというソフトウェアがありますが、そこにさらに機能追加することで実用性を増したDokku Alternativeを試してみました。
Dokku Alternativeの主な特徴としては、
- Git対応
- データベース対応
- Dockerfile/Procfile対応
- Web画面なしのアプリが作成可能
- サブドメインおよびポート指定のアプリ作成
- TLSおよびワイルドカード証明書対応
- 永続的ボリューム作成
- ダウンタイムゼロデプロイ
- 動作中コンテナへの接続
- Basic認証サポート
- SPDY/HSTS対応
などとなっています。Herokuほどクライアントから全て操作できるという訳ではありませんが、自分でサーバを立てていますのでサーバにつなぎつつちょっとした操作を行っていくだけで十分なWebアプリケーション動作環境(PaaS)を作り上げられるようになっています。
では早速試していきます。
さくらのクラウドでサーバを立てる
Dokku Alternativeは現時点ではUbuntuにのみ対応しています。ということでアーカイブ選択時にUbuntu Server 14.04 LTS 64bitを選択してサーバを立ち上げます。

サーバが立ち上がったら、
$ ssh ubuntu@server_ip_address
にて接続します(server_ip_addressは読み替えてください)。
Dokku Alternativeのインストール
サーバに接続したら以下のコマンドでDokku Alternativeをインストールします。Dokku AlternativeはGitコマンドでサーバにつなぐので、Shellshock対策を忘れず行っておきましょう。といってもapt-getでupgradeするだけです。
$ sudo apt-get update $ sudo apt-get -y upgrade $ sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/dokku-alt/dokku-alt/master/bootstrap.sh)" : cat: /root/.ssh/authorized_keys: No such file or directory [2014-09-30 15:19:26] INFO WEBrick 1.3.1 [2014-09-30 15:19:26] INFO ruby 1.9.3 (2013-11-22) [x86_64-linux] == Sinatra/1.4.3 has taken the stage on 2000 for production with backup from WEBrick [2014-09-30 15:19:26] INFO WEBrick::HTTPServer#start: pid=7419 port=2000
Dokku Alternativeのインストールが終わると、そのままセットアップサーバが立ち上がります。ちなみに今回は openservice.jp というドメインを割り当てたという想定になっています。


これで Finish Setup ボタンを押すと、セットアップ処理が実行されて、その後GitHubにあるサンプルアプリケーションの立ち上げ説明画面になります。

基本的にはこの流れのままに実行すればOKです。ドメイン名は読み替えてください。これはクライアントのデスクトップ側からの実行です。
$ git clone https://github.com/heroku/node-js-sample $ cd node-js-sample $ git remote add dokku dokku@openservice.jp:dev $ git push dokku master Counting objects: 378, done. Delta compression using up to 8 threads. Compressing objects: 100% (304/304), done. Writing objects: 100% (378/378), 209.95 KiB | 0 bytes/s, done. Total 378 (delta 45), reused 378 (delta 45) remote: Cloning into '/tmp/tmp.DafPiIAfix'... remote: warning: You appear to have cloned an empty repository. : remote: remote: =====> Application deployed: remote: http://dev.openservice.jp remote: -----> Cleaning up ... To dokku@openservice.jp:dev * [new branch] master -> master

初回はDockerでコンテナイメージをダウンロードしてきますので若干時間がかかります。2回目以降はすぐにデプロイが終わります。 openservice.jp:dev で dev と指定されている部分がアプリケーション名で、サブドメインとして使われます。
Herokuと違って予めアプリケーションを作成しておく必要はありません。初回のプッシュのタイミングで自動的に作成されます。
アプリに接続する
Dokku Alternativeが立ち上がっているサーバではアプリに接続してコマンドが実行できます。例えばこんな感じです。
$ dokku run dev ls -alh total 56K drwxr-xr-x 8 root root 4.0K Sep 30 06:24 . drwxr-xr-x 89 root root 4.0K Sep 30 06:33 .. -rw-r--r-- 1 root root 0 Sep 30 06:24 .env -rw-r--r-- 1 root root 13 Sep 30 06:24 .gitignore drwxr-xr-x 2 root root 4.0K Sep 30 06:24 .heroku drwxr-xr-x 2 root root 4.0K Sep 30 06:24 .profile.d -rw-r--r-- 1 root root 37 Sep 30 06:24 .release -rw-r--r-- 1 root root 15 Sep 30 06:24 Procfile -rw-r--r-- 1 root root 1.3K Sep 30 06:24 README.md -rw-r--r-- 1 root root 254 Sep 30 06:24 app.json -rw-r--r-- 1 root root 339 Sep 30 06:24 index.js drwxr-xr-x 3 root root 4.0K Sep 30 06:24 node_modules -rw-r--r-- 1 root root 575 Sep 30 06:24 package.json drwxr-xr-x 2 root root 4.0K Sep 30 06:24 public drwxr-xr-x 3 root root 4.0K Sep 30 06:24 vendor
devというのがアプリケーション名です。これはコマンドを実行して完了ですが、以下のようにすれば普通にシェルが使えます。/bin/bash なども使えます。
$ dokku run dev /bin/sh # ls Procfile README.md app.json index.js node_modules package.json public vendor
データベースをつなぐ
Dokku Alternativeは以下の4つのデータベースが利用できます。
- MariaDB(MySQL)
- PostgreSQL
- MongoDB
- Redis
例えばMariaDBの場合、以下のように操作します。
$ dokku mariadb:create test-db
-----> MariaDB database created: test-db
$ dokku mariadb:link dev test-db
-----> Releasing dev ...
  :       
=====> Application deployed:
       http://dev.openservice.jp
適当な名前でデータベースを作成し、既存のアプリとリンクさせます。そうすると一旦アプリは立ち上げ直しになります。リンクした後、configコマンドでデータベースの接続情報が確認できます。
$ dokku config dev === dev config vars === DATABASE_URL: mysql2://dev:dAHqRdqvahzONP8G@mariadb:3306/test-db
この情報を使ってデータベースに接続を行うという仕組みになります。
データの永続化
アプリを立ち上げ直すとローカルのデータは消えてしまいます。それを防ぐためにボリュームを設定します。
$ dokku volume:create shared-test-volume /app/logs /app/tmp /app/uploads
-----> Volume created: volume_data_shared-test-volume
$ dokku volume:link dev shared-test-volume
-----> Volume shared-test-volume linked to an aplication: dev
  :
=====> Application deployed:
       http://dev.openservice.jp
この場合も一旦アプリがデプロイし直しになります。作成したボリュームは /home/dokku/.volumes 以下に作成されます。Herokuではアップロードしたファイルなどを保存できませんが、Dokku Alternativeでは手軽に保存できるようです。
Basic認証
作成したアプリに簡単にBasic認証をかけられます。
$ dokku htpasswd:add dev myuser New password: Re-type new password: Adding password for user myuser
devはアプリ名です。これだけでBasic認証を追加できますので手軽ですね。

その他のオプション
Dokku Alternativeには他にも色々な機能があります。コマンドオプションは次の通りです。
$ dokku help
    access:add                                      Add admin user
    access:info <fingeprint>                        Show information about the key
    access:list                                     List all SSH keys: admins and deployments
    access:remove <fingerprint>                     Revoke all permissions for specific SSH key
    apps:disable <app>                              Disable specific app
    apps:enable <app>                               Re-enable specific app
    apps:list                                       List app
    apps:restart <app>                              Restart specific app (not-redeploy)
    apps:start <app>                                Stop specific app
    apps:status <app>                               Status of specific app
    apps:stop <app>                                 Stop specific app
    apps:top <app> [args...]                        Show running processes
    backup:export [file]                            Export dokku configuration files
    backup:import [file]                            Import dokku configuration files
    config <app>                                    display the config vars for an app
    config:get <app> KEY                            display a config value for an app
    config:set <app> KEY1=VALUE1 [KEY2=VALUE2 ...]  set one or more config vars
    config:unset <app> KEY1 [KEY2 ...]              unset one or more config vars
    create <app>                                    Create shallow app
    delete <app>                                    Delete an application
    deploy:allow <app>                              Allow push-access (aka. deployment) to an app
    deploy:list <app>                               List all push-acccesses for an application
    deploy:revoke <app> <fingerprint>               Revoke push-access for an application
    domains:get <app>                               Get domains for an app
    domains:redirect:get <app>                      Get redirect domains for an app
    domains:redirect:set <app> <domains...>         Set redirect app domains
    domains:set <app> <domains...>                  Set app domains
    enter <app>                                     Enter into currently running container
    exec <app> <cmd>                                Execute command in currently running container
    help                                            Print the list of commands
    htpasswd:add <app> <user>                       Add http-basic auth user
    htpasswd:disable <app>                          Remove http-basic Auth
    htpasswd:remove <app> <user>                    Remove user
    logs <app> [-t] [-f]                            Show the last logs for an application (-t or -f follows)
    mariadb:console <app> <db>                      Launch console for MariaDB container
    mariadb:create <db>                             Create a MariaDB database
    mariadb:delete <db>                             Delete specified MariaDB database
    mariadb:dump <app> <db>                         Dump database for an app
    mariadb:info <app> <db>                         Display application informations
    mariadb:link <app> <db>                         Link database to app
    mariadb:list <app>                              List linked databases
    mariadb:unlink <app> <db>                       Unlink database from app
    mongodb:console <app> <db>                      Launch console for MongoDB container
    mongodb:create <db>                             Create a MongoDB database
    mongodb:delete <db>                             Delete specified MongoDB database
    mongodb:dump <app> <db> <collection>            Dump database collection in bson for an app
    mongodb:export <app> <db> <collection>          Export database collection for an app
    mongodb:import <app> <db> <collection>          Import database collection for an app
    mongodb:info <app> <db>                         Display application informations
    mongodb:link <app> <db>                         Link database to app
    mongodb:list <app>                              List linked databases
    mongodb:unlink <app> <db>                       Unlink database from app
    plugins-install                                 Install active plugins
    plugins                                         Print active plugins
    postgresql:console <app> <db>                   Launch console for PostgreSQL container
    postgresql:create <db>                          Create a PostgreSQL database
    postgresql:delete <db>                          Delete specified PostgreSQL database
    postgresql:dump <app> <db>                      Dump database for an app
    postgresql:info <app> <db>                      Display application informations
    postgresql:link <app> <db>                      Link database to app
    postgresql:list <app>                           List linked databases
    postgresql:unlink <app> <db>                    Unlink database from app
    preboot:cooldown:time <app> <secs>              Re-enable specific app
    preboot:disable <app>                           Stop specific app
    preboot:enable <app>                            Stop specific app
    preboot:status <app>                            Status of specific app
    preboot:wait:time <app> <secs>                  Restart specific app (not-redeploy)
    rebuild:all                                     Rebuild all apps
    rebuild <app>                                   Rebuild an app
    redis:create <app>                              Create a Redis database
    redis:delete <app>                              Delete specified Redis database
    redis:info <app>                                Display application information
    run <app> <cmd>                                 Run a command in the environment of an application
    ssl:certificate <app>                           Pipe signed certifcate with all intermediates for an APP
    ssl:forget <app>                                Wipes certificate for an APP
    ssl:generate <app>                              Generate certificate signing request for an APP
    ssl:info <app>                                  Show info about certifcate and certificate request
    ssl:key <app>                                   Pipe private key for an APP
    tag:add <app> <tag>                             Tag latest running image using specified name
    tag:list <app>                                  List all image tags
    tag:rm <app> <tag>                              Tag latest running image using specified name
    url <app>                                       Show the URL for an application
    version                                         Print dokku's version
    volume:create <name> <paths...>                 Create a data volume for specified paths
    volume:delete <name>                            Delete a data volume
    volume:info <name>                              Display volume information
    volume:link <app> <name>                        Link volume to app
    volume:list:apps <name>                         Display apps linked to volume
    volume:list                                     List volumes
    volume:unlink <app> <name>                      Unlink volume from app
Herokuのようにクライアントサイドから全ての操作ができるという訳でもありませんし、Webベースの管理画面が整っているという訳でもありません。しかしサーバサイドの自由度が高いので自分で管理しているサーバの状態を把握しながら使っていけるというのは面白そうです。
ベースになっているdokkuはDockerを使うことでわずか100行程度のBashスクリプトで小さなPaaSを実現していますが、そこに機能追加することでより可用性を増し、個人用途であれば十分な機能を備えています。PaaSをサービス提供するという訳ではなく、自社や個人で使っているアプリをより手軽にデプロイできる場所としては面白いと思います。
ぜひさくらのクラウドとともにお試しください!
