はじめに
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をインストール
環境構築
プロジェクトのディレクトリ下に以下ファイルを作成します。
$ mkdir app
$ cd app
source 'https://rubygems.org'
gem 'hanami', '~> 0.9'
Dockerfile
APP_HOMEに指定したディレクトリ名がhanami new .
でプロジェクト作成するときのプロジェクト名になります。
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を作るほうが良いかなと思うのですが、どうやるのか分かってません...
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の設定が上書きされてしまうので削除します。
# 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です。
マイグレーションやテスト実行など
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を使っています。
Port, User, Password, Databaseはdocker-compose.ymlの設定に従って入力します。
以上でデフォルトのトップページ表示とDBを用意するところまでできたので開発作業に入れると思います。
参考
Hanami公式ドキュメント
Hanami(旧:Lotus) - MicroservicesのためのRubyフレームワーク