DockerでHanami(旧名Lotus)の開発環境構築

### はじめに

RubyのフレームワークといえばRailsという感じですが、他のフレームワークも使ってみたいのとDocker環境の構築に関する記事ではほとんどRails前提なので今回Hanamiで環境構築してみました。
Dockerfile,docker-compose.ymlの内容や作業はRailsのときとそれほど変わらないと思います。

#### Hanamiの特徴

* 以前はLotusという名前だったWebフレームワーク
* GithubのStar数は3500弱(2016年12月時点)

apps以下がアプリケーション単位で分かれていて管理画面やAPIなど独立して作ることができます(プロジェクト作成時はwebが1つの状態)

```
$ tree apps
apps
└── web
    ├── application.rb
    ├── assets
    │   ├── favicon.ico
    │   ├── images
    │   ├── javascripts
    │   └── stylesheets
    ├── config
    │   └── routes.rb
    ├── controllers
    ├── templates
    │   └── application.html.erb
    └── views
        └── application_layout.rb
```

1つのアプリケーション内は以下のような構成
コントローラはディレクトリ名でアクションごとにファイルが分かれています。

```
├── application.rb
├── assets
│   ├── favicon.ico
│   ├── images
│   ├── javascripts
│   └── stylesheets
├── config
│   └── routes.rb
├── controllers
│   ├── books
│   │   └── index.rb
│   └── home
│       └── index.rb
├── templates
│   ├── application.html.erb
│   ├── books
│   │   └── index.html.erb
│   └── home
│       └── index.html.erb
└── views
    ├── application_layout.rb
    ├── books
    │   └── index.rb
    └── home
        └── index.rb
```


### 環境

* Mac OSX 10.12.1

### 作成する開発環境

* Ruby 2.3.1
* Hanami(Rubyフレームワーク)
* PostgreSQL 9.6

### 準備

[Docker for Mac](https://docs.docker.com/docker-for-mac)をインストール

### 環境構築

プロジェクトのディレクトリ下に以下ファイルを作成します。

```
$ mkdir app
$ cd app
```

```:Gemfile
source 'https://rubygems.org'

gem 'hanami', '~> 0.9'
```

#### Dockerfile
APP_HOMEに指定したディレクトリ名が```hanami new .```でプロジェクト作成するときのプロジェクト名になります。

```:Dockerfile
FROM ruby:2.3.1
ENV LANG C.UTF-8

RUN gem install bundler

ENV APP_HOME /app
RUN mkdir $APP_HOME
WORKDIR $APP_HOME

ADD Gemfile* $APP_HOME/
RUN echo 'gem: --no-document' > ~/.gemrc \
    && bundle install
ADD . $APP_HOME
```

#### docker-compose.yml

Hanamiでプロジェクト作成するとdevelopmentとtest(自動テスト用)で2つDBを作るように.envが作成されるので、それに合わせてDBコンテナを2つ作りdevelopmentだけ永続化しました。
1コンテナ内に2つDBを作るほうが良いかなと思うのですが、どうやるのか分かってません...

```YAML:docker-compose.yml
version: '2'
services:
  web:
    build: .
    command: 'bundle exec hanami server --host 0.0.0.0 -p 2300'
    ports:
      - 2300:2300
    volumes:
　　　　　　　　　　　　#DockerfileのAPP_NAMEに指定したもの
      - .:/app
    links:
      - db
      - db2
    environment:
      - DATABASE_URL=postgres://dev:dev@db:5432/dev
  db:
    image: 'postgres:9.6'
    volumes:
      - ./db/postgres_data:/var/lib/postgresql/data
    # PG CommanderなどのクライアントからDB接続するためのポート設定
    ports:
      - 5432:5432
    environment:
      - POSTGRES_USER=dev
      - POSTGRES_PASSWORD=dev
  db2:
    image: 'postgres:9.6'
    environment:
      - POSTGRES_USER=test
      - POSTGRES_PASSWORD=test
```

#### プロジェクト作成

```
$ docker-compose run web bundle exec hanami new . --database=postgresql
```
Gemfileを上書きされるか聞かれるのでYで上書きします。

プロジェクト作成後は以下の状態

```
$ tree -L 1
.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── apps
├── config
├── config.ru
├── db
├── docker-compose.yml
├── lib
├── public
└── spec
```

#### DB設定を変更


`.env.development`と`.env.test`に使用するDBの設定が書かれてますがdocker-compose.ymlの設定が上書きされてしまうので削除します。


```:.env.development
# Define ENV variables for development environment
DATABASE_URL="postgres://localhost/app_development" # この行を削除
SERVE_STATIC_ASSETS="true"
WEB_SESSIONS_SECRET="xxxx"
```

#### コンテナ起動、画面表示を確認

```
$ docker-compose build web
$ docker-compose up web
```
localhost:2300にアクセスしてデフォルトの画面が表示されるのを確認できればOKです。

![スクリーンショット 2016-12-09 4.09.37.png](https://qiita-image-store.s3.amazonaws.com/0/100903/15555036-020d-73a6-71de-c851193f6adc.png)


### マイグレーションやテスト実行など

rakeタスクやHanamiのコマンド実行もプロジェクト作成と同様にdocker-compose runを利用します。

```
$ docker-compose run web bundle exec hanami generate migration create_books
$ docker-compose run web bundle exec hanami db migrate
```

### DBの内容を確認する

RailsのdbconsoleのようにhanamiでもコマンドラインからDB接続ができるのですが、webコンテナにはPostgreSQLをインストールしていないのでエラーで接続できません。

```
$ docker-compose run web bundle exec hanami db console
bundler: failed to load command: hanami (/usr/local/bundle/bin/hanami)
Errno::ENOENT: No such file or directory - psql
```

docker-composeを使ってDBのコンテナを分けて管理しているのにwebにも入れるというのはしたくなかったのでクライアントで接続することにしました。

ここでは[PG Commander](https://eggerapps.at/pgcommander/)を使っています。
Port, User, Password, Databaseはdocker-compose.ymlの設定に従って入力します。
![スクリーンショット 2016-12-09 4.44.33.png](https://qiita-image-store.s3.amazonaws.com/0/100903/ddf59aae-8b14-e163-6722-29cdea26e20a.png)


以上でデフォルトのトップページ表示とDBを用意するところまでできたので開発作業に入れると思います。


### 参考

[Hanami公式ドキュメント](http://hanamirb.org/guides/)
[Hanami(旧:Lotus) - MicroservicesのためのRubyフレームワーク](http://qiita.com/takamario/items/d2eb6f43246c39145583)