ConoHa VPSのDokkuアプリケーションイメージを使ってRailsアプリを運用する


## はじめに

授業や研究、業務の合間にアプリを作る個人開発者にとって重要なのは、言い方は悪いかもしれないけど出来るだけ"サボる"ことだと思う。

どこをどうサボるかはその人のやりたいことやスキルによって様々だと思うけど、Webアプリケーション開発者がインフラをサボるための選択肢として最高なのがHerokuだ。インフラの管理をHerokuに任せることで、我々はアプリケーションの開発そのものに集中することが出来る。

> Heroku プラットフォームはフルマネージドのサービスであり、お客様の側でサーバー、ハードウェア、インフラストラクチャを管理する必要がないため、アプリ開発に集中できます。
> [開発者のための Heroku \| Heroku](https://jp.heroku.com/developers)

しかしながら、あまりユーザ数のいない出来たてのアプリや仲間内で使うくらいのアプリをたくさん運用するのに、7ドル×アプリ数を毎月払うのはお財布事情的にキツい。

## Dokku

そこで登場するのがDokkuだ。 `"Docker powered mini-Heroku. The smallest PaaS implementation you've ever seen."` と書いてあるとおり、自分のサーバ上にまさしくミニHerokuと呼べるPaaS環境を構築することが出来る。

[dokku/dokku: A docker-powered PaaS that helps you build and manage the lifecycle of applications](https://github.com/dokku/dokku)

Dockerベースではあるが、Dockerについてあまりよく知らなくても使える印象だ。


## Dokkuアプリケーションイメージ

Dokkuは自分でインストールして使うことも出来るが、さらに便利なのが各VPSホスティング業者が用意しているアプリケーションイメージを利用することだ。

今回は、ConoHa VPSが提供しているDokkuアプリケーションイメージを利用することにする。
[Dokkuアプリケーションイメージの使い方｜ConoHa VPSサポート](https://support.conoha.jp/v/dokku/)

## 手順

### 前提

コマンドラインの説明では、macOSをクライアント側、ConoHa VPSのDokkuアプリケーションイメージを利用したインスタンスをサーバ側と表記している。

クライアント側の環境は以下の通り。

```
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.1
BuildVersion:	18B75
```

また、Dokkuまわりのバージョンは2018年12月6日時点での最新版を利用している。

- Dokku 0.12.13
- dokku-cli (0.4.0) (gem)


### OSのインストールと初期設定

OSのインストールと初期設定は、公式のドキュメントに書いてあるのでそこを参照してほしい。独自ドメインの設定も忘れずに。

[Dokkuアプリケーションイメージの使い方｜ConoHa VPSサポート](https://support.conoha.jp/v/dokku/)


### Dokku CLIのインストール

クライアント側でDokkuを操作するため、Dokku CLIをインストールする。ちょうど、Heroku CLI（旧Heroku Toolbelt）のようなものだ。Node版やPython版などもあるが、今回はRuby版を利用する。

```shell-session
$ gem install dokku-cli
```


### Railsアプリを動かしてみる

サンプル用のRailsアプリは何でも良い [^1] のだけど、先日書いた記事 [Rails 5 APIモード + Grape + Grape::Entityで作るWeb API - Qiita](https://qiita.com/mktakuya/items/117f1563c2b7e8a6e69c) で作成した [mktakuya/grape-on-rails-api](https://github.com/mktakuya/grape-on-rails-api) を使用する。

Dokkuでのアプリ名は、 `grape-on-rails-api` とし、 `grape-on-rails-api.example.com` というドメインで運用するとする。

まずはサーバ側の作業。先程設定したVPSにSSHログイン [^2] して、アプリケーションを作成する。

```shell-session
# サーバ側
$ ssh root@example.com
$ dokku apps:create grape-on-rails-api
```

PostgreSQLプラグインの導入とDBの作成・リンクを済ませる。

```shell-session
# サーバ側
$ dokku plugin:install https://github.com/dokku/dokku-postgres
$ dokku postgres:create grape-on-rails-api_production
$ dokku postgres:link grape-on-rails-api_production grape-on-rails-api
# 現状ではまだ最初のデプロイをしていないので
# !     App grape-on-rails-api has not been deployed
# と出力される。
```

次はクライアント側でgit clone。

```shell-session
# クライアント側
$ git clone https://github.com/mktakuya/grape-on-rails-api
$ cd grape-on-rails-api
```

クライアント側でgitの設定とリモートへのpush。

```shell-session
# クライアント側
$ git remote add dokku dokku@example.com:grape-on-rails-api
$ git push dokku master
```

あとは、Herokuのようにビルドが走り、しばらくすると `http://grape-on-rails-api.example.com` でアプリケーションが動作する。

クライアントのアプリケーションのディレクトリで `dokku run` するとコマンドを実行できる。

```
# クライアント側
$ dokku run rails db:migrate
```

適当にサンプルデータを流し込む。

```shell-session
# クライアント側
$ dokku run rails c
# コンソールにコピペしてデータを流し込む↓
nozaki_mado = Author.create(name: '野崎まど')
Book.create(title: 'know', price: 720, author: nozaki_mado)
Book.create(title: '野崎まど劇場', price: 610, author: nozaki_mado)

jason_fried = Author.create(name: 'ジェイソン・フリード')
Book.create(title: '小さなチーム、大きな仕事', price: 640, author: jason_fried)
Book.create(title: '強いチームはオフィスを捨てる', price: 1500, author: jason_fried)
```

クライアントからcurlコマンドで確認してみる。

```shell-session
# クライアント側
$ curl http://grape-oon-rails-api.apps.m6a.jp/v1/books
[
  {
    "id": 1,
    "title": "know",
    "price": 720,
    "tax_included_price": 777.6,
    "author": {
      "id": 1,
      "name": "野崎まど"
    }
  },
  {
    "id": 2,
    "title": "野崎まど劇場",
    "price": 610,
    "tax_included_price": 658.8000000000001,
    "author": {
      "id": 1,
      "name": "野崎まど"
    }
  },
  {
    "id": 3,
    "title": "小さなチーム、大きな仕事",
    "price": 640,
    "tax_included_price": 691.2,
    "author": {
      "id": 2,
      "name": "ジェイソン・フリード"
    }
  },
  {
    "id": 4,
    "title": "強いチームはオフィスを捨てる",
    "price": 1500,
    "tax_included_price": 1620,
    "author": {
      "id": 2,
      "name": "ジェイソン・フリード"
    }
  }
]
```


## その他

### dokku-letsencryptプラグインの導入

iOSアプリのサーバサイドとする場合などは、https運用が必須だろう。SSLまわりの設定は、Dokku公式のdokku-letsencryptプラグインを利用すればかんたんだ。

```shell-session
# クライアント側
$ dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
$ dokku config:set --global DOKKU_LETSENCRYPT_EMAIL=yourname@example.com
$ dokku letsencrypt grape-on-rails-api
```

これだけで、証明書の発行からnginxの設定変更まで勝手にやってくれる。


### タスクの定期実行

Heroku Schedulerでやっていたようなタスクの定期実行について、自分はcrontabを利用してやっている。

```
# サーバ側
$ crontab -e
```

```shell
# crontab
# 毎月1日の朝7時にコマンド実行する例
0 7 1 * * dokku run grape-on-rails-api rails hogenamespace:hogetask
```

crontab以外に何か良い方法があれば誰か教えてほしい。


## おわりに

以上がDokkuの紹介とConoHa VPSのDokkuアプリケーションイメージを利用して実際に使ってみるサンプルだ。本気で使うならHerokuより物足りない所は多々あると思うけど、趣味程度のアプリや個人開発アプリの立ち上げ段階ではなかなか良い選択肢になってくれるんじゃないかと思う。また、本番環境はHerokuやAWSでちゃんと運用しつつ、DokkuをHeroku Review Apps的な使い方をしてみても良いかもしれない。

この記事は [グロービス Advent Calendar 2018](https://qiita.com/advent-calendar/2018/globis) 4日目の記事でした。
グロービスでは、エンジニア・デザイナーを積極採用中です！興味があればWantedlyからコンタクトよろしくお願いします！
[株式会社グロービスの会社情報 - Wantedly](https://www.wantedly.com/companies/globis)

[^1]: Dokku公式のチュートリアルに載っている [heroku/ruby-rails-sample](https://github.com/heroku/ruby-rails-sample) はRubyのバージョンが古めのせいか動かすのが大変だった。
[^2]: ConoHa VPSのDokkuアプリケーションイメージでは、初期設定だとSSHでリモートからrootユーザにログインすることになるが、あとから一般ユーザを作ってそこからsudoでdokkuコマンドを実行するようにして、リモートからのrootログインは禁止にする方が安全な気もする。