作成したrails pluginを公開する方法

Gakuです。

昨日に引き続き、作成したrails plaginについて、今回は公開する方法を備忘録として残します。

公開手順

会員登録

gemの場合、RubyGem.orgに公開するのが一般的なようですので、以下のサイトに新規登録を行います。
[blogcard url=”https://rubygems.org/”][/blogcard]

公開方法

あとはめっちゃ簡単です。
作成したプラグインに以下コマンドを実行し、パッケージを生成します。

gem build <Gem名>.gemspec

ここで依存関係についてwarning出る可能性があるので、その場合は適宜.gemspecファイルを修正してください。
パッケージの生成が完了したら、以下コマンドで公開します。

gem push <生成したパッケージを指定>

これだけで公開完了です。
この際にエラーが出ることがあります。既に誰かが公開しているGemと名前が被っていたり、一度UPしたバージョンのままで公開すると発生するようなので、適宜修正します。

良きRailsLifeを✨

おわりに

ひさしぶりに楽しいプログミングをしている気がします。
「誰かに使ってもらうために作る!」
っていうのはエンジニアの醍醐味な気がしています。

あと、多く使ってもらおうと思うと、英語でのREADME記述は必須な気がしたので、その点も修正しました。
[blogcard url=”https://github.com/gaku3601/SortIndexTable”][/blogcard]
拙い英語だけど、こういった形で英語勉強していくのが一番な気がしている今日この頃です。。。

railsのプラグインを作成する[helperプラグインの作成]

Gakuです。
今回はrailsで使用するhelperを外だしして、プラグインを作成していきたいと思います。
以下にソースコードを格納しています。よかったらどうぞ。
[blogcard url=”https://bitbucket.org/gakussolution/sortindex/overview”][/blogcard]

プラグインの作成

サンプルアプリの準備

rails new sample -d postgresql

railsの初期設定を行なったのちに、テスト用にscaffoldでscoreなるものを生成します。

rails g scaffold score name:string title:string result:integer

プラグインの生成

上で作成したsampleアプリフォルダ内で以下のコマンドを実行し、プラグインを生成します。

rails plugin new sort_index --mountable

この状態でsampleアプリ上でbundle installを実施しても、「gemspecの設定をしてね!」とエラーで怒られるので、plugin内のgemspecファイルを編集します。

$:.push File.expand_path("../lib", __FILE__)

# Maintain your gem's version:
require "sort_index/version"

# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
  s.name        = "sort_index"
  s.version     = SortIndex::VERSION
  s.authors     = ["gaku"]
  s.email       = ["pro.gaku@gmail.com"]
  s.homepage    = "https://www.gakusmemo.com/"
  s.summary     = "sort plugin"
  s.description = "rails sort plugin"
  s.license     = "MIT"

  s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]

  s.add_dependency "rails", "~> 5.1.4"

  s.add_development_dependency "sqlite3"
end

今回はこんな感じで作成しました。
再度、sampleアプリ内でbundle installすると、

このように使用できる状態になったことがわかります。

プラグインの作成

今回は簡単に、scaffoldで生成したindex.htmlにソート機能を付与するプラグインを作成してみたいと思います。
プラグインフォルダのlib配下にsort_view_helper.rbというファイルを作成します。

で、こんな感じで作成しました。

module SortIndex
  module SortViewHelper
    # ソート結果を(△ ▽ で表現し、リンクを作成する)
    def sort_item(item_name,sort_name)
      if sort_name == @sort && @method == "asc"
        return link_to("#{item_name}",:sort =>sort_name,:method =>"desc") + "▲".html_safe
      elsif sort_name == @sort && @method == "desc"
        return link_to("#{item_name}",:sort =>sort_name,:method =>"asc") + "▼".html_safe
      else
        return link_to("#{item_name}",:sort =>sort_name,:method =>"desc")
      end
    end
  end
end

これでview上で呼び出せるhelperを作成することができました。

次にcontrollerのhelperも必要なので、新たにsort_controller_helper.rbというファイルも作成します。

で、こんな感じに記述。

module SortIndex
  module SortControllerHelper
    def order_model(model_name,sort_param,method_param)
      @sort = sort_param.nil? ? 'id' : sort_param
      @method = method_param.nil? ? 'desc' : method_param
      model_name.constantize.order("#{@sort} #{@method}")
    end
  end
end

これで具体的なプラグイン内容は作成完了なのですが、プラグインを組み込める設定を行わないと使用できないため、その設定を行います。
今回の場合ですと、lib/sort_index/配下にengine.rbというファイルが自動的に作成されており、以下のように編集します。

require 'sort_index/sort_view_helper'
module SortIndex
  class Engine < ::Rails::Engine
    isolate_namespace SortIndex
    initializer 'sort_index.action_view_helpers' do
      ActiveSupport.on_load :action_view do
        include SortIndex::SortViewHelper
      end
    end
  end
end

require 'sort_index/sort_controller_helper'
module SortIndex
  class Engine < ::Rails::Engine
    isolate_namespace SortIndex
    initializer 'sort_index.action_controller_helpers' do
      ActiveSupport.on_load :action_controller do
        include SortIndex::SortControllerHelper
      end
    end
  end
end

この設定はもうちょっと良い書き方あると思います。とりあえず、動いたのでひとまず。。。

プラグインを使用してみる

作成したプラグインを反映していきます。
sampleアプリ内でbundle updateを実行し、railsアプリを再起動します。
その後、scaffoldで作成したindex.html.erbとscore_controllerを以下のように修正。

<p id="notice"><%= notice %></p>

<h1>Scores</h1>

<table>
  <thead>
    <tr>
      <th><%= sort_item "#","id" %></th>
      <th><%= sort_item "Name","name" %></th>
      <th><%= sort_item "Title","title" %></th>
      <th><%= sort_item "Result","result" %></th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @scores.each do |score| %>
      <tr>
        <td><%= score.id %></td>
        <td><%= score.name %></td>
        <td><%= score.title %></td>
        <td><%= score.result %></td>
        <td><%= link_to 'Show', score %></td>
        <td><%= link_to 'Edit', edit_score_path(score) %></td>
        <td><%= link_to 'Destroy', score, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Score', new_score_path %>

また、controllerのindexも以下のように編集

def index
  @scores = order_model("Score",params[:sort],params[:method])
end

これで完了です。できあがったものは以下になります。

おわりに

これでhelper周りはDRY原則に乗っ取って書いていけそうです。非常に気持ち良いです。
作成したプラグインの公開まで頑張りたかったけど、力尽きました。。。その辺は後日UPします。

railsでバイナリー画像データの表示メソッドを共通化する方法

railsはやっぱ楽しい!
最近、ようやくrails wayに乗れるようになって来たなと実感しているGakuです。

今回は、よく実装することがあるバイナリー画像データの表示メソッドについて、良いなと思った書き方を見つけたのでご紹介します。

良く紹介されている画像表示

railsでDBに格納している画像をWebページ上に表示しようと思うと、少々めんどくさいです。
良く他の方のブログページを漁っていると見つかるコードは以下のようなものです。

<%= image_tag(avatar_for_user_path, alt: @user.name, :size => '40x40') %>
Rails.application.routes.draw do
  resources :users do
    member do
      get 'avatar_for'
    end
  end
end
def avatar_for
  @user = User.find(params[:id])
  send_data(@user.avatar)
end

こんな感じです。アバター画像を表示するのはいいのですが、コントローラー部分でModelと表示する画像データが入っているcolumnを決め打ちで実装しているので、これ以外の画像データを表示しようと思うと、routingのコードとcontrollerのコードに新たにコードを追加しなければいけません。
これは太っちょコントローラーパターンに陥る危険性もあるため、何としてでも共通化しておきたいところです。

バイナリ画像データ表示メソッドの共通化

ってことで今回は以下のようなコードを書いて共通化してみました。

<%= image_tag(url_for(:controller => 'application', :action => 'show_image', :id => @user.id,:model => "User", :column => "avatar"))%>
Rails.application.routes.draw do
  get '/show_image', to: 'application#show_image'
end
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def show_image
    @model = params[:model].constantize.find(params[:id])
    send_data @model[params[:column]], :type => 'image/jpg,image/jpeg,image/png,image/gif', :disposition => 'inline'
  end
end

applicationコントローラへshow_imageというメソッドを作成し、そこにモデル名とカラム名とidを渡し、send_dataで返却するというコードです。
こうすることでview部分は従来コードより肥大化しますが、コントローラとルーティングコードはどれだけ表示する画像カラムが増えても追記する必要はありません。
共通化万歳です( ^∀^)b

おわりに

railsは早いし、書き方覚えると気持ちよく書ける非常に楽しいフレームワークだなと再実感しています。
逆にrails wayに乗れないと途端に気持ち悪いコードになるので、すぐに「対処しよう!」という気にもなります。

本当最速で書けるので、PJなんて一人で回せばいいんじゃね?納期なければ。。。と考える今日この頃です。

docker-composeを使用し、最速でrails5+postgresqlを導入する

Gakuです。

ひっっさしぶりのrailsです!
会社でrails5を使用したWebシステムの構築を検討しているため、ひっさしぶりにrailsを触ることになりました。
以前のようにvagrantで開発環境を構築してもいいのですが、めんどうです。
また、他の開発者にも速攻で開発環境を導入できるということからdockerを使用して開発環境を構築してみました。

前提

これはdockerとdocker-composeが既に導入されていることを前提に進めていきます。
まだ入れていないよ〜という方は、こちらの記事を参考にして導入してみて下さい。
[blogcard url=”https://www.gakusmemo.com/?p=812″][/blogcard]

構築

ファイル構成

./
|-docker-compose.yml
|-web/
|  |-Dockerfile
|-app/    //共有フォルダ

以上です。

docker-compose.ymlの編集

docker-compose.ymlを以下のように編集します。

version: "3"

services:
  web:
    build: web
    ports:
      - "3000:3000"
    links:
      - db
    volumes:
      - "./app:/app" #共有フォルダの設定(ホストdir:クライアントdir)
    stdin_open: true
  db:
    image: postgres
    expose:
      - "5432"

volumesの部分はホストとクライアントのフォルダを共有する設定になっています。
このフォルダ以下にrailsappを作成していくため、適宜お好きなところに変更して下さい。

Dockerfileの編集

次にrailsを導入するdockerコンテナのDockerfileを編集します。

FROM ruby:2.4

RUN apt-get update && apt-get install -y build-essential libpq-dev postgresql-client
RUN gem install rails
RUN mkdir /app
WORKDIR /app

railsとpostgresの接続系ライブラリを導入しています。
また、ここでホストフォルダと共有するappフォルダも作成しておきます。

設定は終わりです( ´Д`)y━・~~

railsappを作成してみる

とりあえず、おきまりの以下のコマンドで各コンテナを起動します。

docker-compose build
docker-compose up -d

これでコンテナが立ち上がったはずです。
立ち上がったrailsコンテナに以下コマンドでログインします。

docker-compose exec web bash

ここまでくればrailsのいつもの作法です。
あとはrailsのアプリケーションを作成し、そのままではGemのエラーが出るので修正、bundle installしてrails起動!

rails new app -d postgresql
source 'https://rubygems.org'

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
  "https://github.com/#{repo_name}.git"
end


# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.1.2'
# Use postgresql as the database for Active Record
gem 'pg', '~> 0.18'
# Use Puma as the app server
gem 'puma', '~> 3.7'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
gem 'therubyracer', platforms: :ruby #ここのコメントを外す!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '~> 2.13'
  gem 'selenium-webdriver'
end

group :development do
  # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end
bundle install
rails s -b 0.0.0.0

そしたら、ホストPCのブラウザでlocalhost:3000にアクセスして

Yay!!!!!( ^ω^ )b

おわりに

dockerの設定は多少めんどくさいかもしれませんが、一度作成しておけば以後設定する必要はありません。
docker関連のファイルを共有しておけば、他の開発者が開発環境を構築する際、最速で構築可能です。

dockerは難しく、勉強コストも結構かかるとは思います。
ただ、一度勉強してしまえば「最速」でいろいろな環境が構築できるので、お得感の高いツールだなと思うこの頃。

docker使ってredmineプラグイン作り

Gakuです。

最近、業務でredmineを使用しており、かんばんを使用するのにbacklogsプラグインでは使い勝手が悪いため、redmineプラグインを自作してみようと考えました。
(※開発業務ではなく、一般の業務をタスク管理する上でsprintは不要ですし、sprint組まないとかんばん出ないのは使い勝手悪い。)
dockerで環境構築を行い、ホストOSからpluginを新規作成するところまでの備忘録を掲載します。

docker-compose.yml,Dockerfile

docker-compose.ymlとredmineのDockerfileは以下のように作成しました。

version: '2'

services:
  redmine:
    build: redmine
    ports:
      - 8080:3000
    environment:
      REDMINE_DB_POSTGRES: postgres
    links:
      - postgres:postgres
    volumes:
      - ./redmine/plugins:/usr/src/redmine/plugins
  postgres:
    restart: always
    image: postgres
FROM redmine

Dockerfileいらないですね。( ´Д`)
まぁ、今後の拡張性考えて作っておきます。

volumeの設定

上記docker-compose.yml内でvolumeを設定していますので、それに合わせて、/redmine/pluginsフォルダを作成します。
これで一旦

docker-compose up -d


余裕のredmine起動( ^∀^)b

redmineプラグインの新規作成

redmineプラグインを作成するのも簡単です。
以下コマンド1発です。

docker-compose exec redmine bundle exec rails generate redmine_plugin Sample

これでホストOSの/redmine/pluginsフォルダにSampleプラグインが作成されたと思います。
あとは、これをredmineに反映させるため、

docker-compose stop && docker-compose up -d

でリスタートかけて、redmineのplugin一覧を確認して表示されてればOKです。

イージーゲーム( ´Д`)y━・~~

おわりに

ちょっとずつ育てていきますw
いい感じに作れたらフリーミアムな感じで販売も考えています。

それにしても、docker便利っすね〜。vagrantで一から環境作ろうと思ったんですが、めんどくさくてdockerに切り替えたらものの30分でここまで完了。。。
なんて素晴らしき世界。。。( ´Д`)y━・~~

rails5+puma+nginxで本番環境を構築してみる

本番環境でのrailsアプリケーションはunicorn+nginxで構成していました。
herokuがunicornではなくpumaを今後推奨していく流れや、rails5でpumaが標準搭載になった流れから、今回本番環境をpuma+nginxで構築しました。
その備忘録を記述したいと思います。

pumaって何よ?

ここ参照
[blogcard url=”http://qiita.com/kompiro/items/223bb04c2f009787eea8″][/blogcard]

http://puma.io/ で公開されているconcurrentなWebサーバー。thinやunicornはワーカー毎にプロセスを立ち上げるが、pumaはワーカー毎にスレッドを立ち上げる。production環境ではサイトのパフォーマンスを上げるため、複数のワーカーを立ち上げるが、thinやunicornはワーカー毎にプロセスが異なるため、排他処理ができない。しかし、pumaはスレッドで動作するため、Mutexでsynchronizeブロックを記述すれば、排他処理を行える。

なんか良さげですね。スレッドベースで立ち上がるってことは並列処理してくれる感じでしょうか。
まぁ、今回は一旦構築するというだけで、細かな設定などは行いません。

構成

今回は下記構成上で本番環境を構築します。

Ubuntu
rails5
postgreSQL

構築する

pumaの設定

rails5アプリケーションを作成すると、configフォルダ配下にpuma.rbというファイルが作成される。
そのファイルを下記のように追記編集する。

#ここから
#_homeは各自環境で設定してください。
_proj_path = "#{File.expand_path("../..", __FILE__)}"
_proj_name = File.basename(_proj_path)
_home = ENV.fetch("HOME") { "/home/gaku" }

pidfile "#{_home}/run/#{_proj_name}.pid"
bind "unix://#{_home}/run/#{_proj_name}.sock"
directory _proj_path
#ここまで追記
# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum, this matches the default thread size of Active Record.
#
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count

# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
#
port        ENV.fetch("PORT") { 3000 }

# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }

# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked webserver processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }

# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory. If you use this option
# you need to make sure to reconnect any threads in the `on_worker_boot`
# block.
#
# preload_app!

# The code in the `on_worker_boot` will be called if you are using
# clustered mode by specifying a number of `workers`. After each worker
# process is booted this block will be run, if you are using `preload_app!`
# option you will want to use this block to reconnect to any threads
# or connections that may have been created at application boot, Ruby
# cannot share connections between processes.
#
# on_worker_boot do
#   ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
# end

# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart

pumaの設定はこれだけです。

nginxの設定

nginxを設定していきます。まだインストールしていない場合は下記コマンドでインストールします。

sudo apt-get install -y nginx

設定ファイルを/etc/nginx/conf.d/の配下に作成します。
ファイル名は何でも良いです。わかりやすいようにアプリケーション名で作成してあげれば良いかと思います。

upstream TranslateEroticVideoSite_Rails {
    # railsのアプリケーション名とhome/gakuを各自編集してください。
    server unix:/home/gaku/run/TranslateEroticVideoSite_Rails.sock fail_timeout=0; 
}

server {
    listen 80;
    server_name 127.0.0.1; # 本番環境のipアドレスもしくはホスト名を記述

    root /path/to/TranslateEroticVideoSite_Rails/public; # アプリケーション名を記述

    try_files $uri/index.html $uri @TranslateEroticVideoSite_Rails; # アプリケーション名を記述

    location / {
        proxy_pass http://TranslateEroticVideoSite_Rails; # アプリケーション名を記述
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

上記設定ファイルを記述しましたら、nginxを再起動しておきましょう。

sudo service nginx restart

起動してみる

この状態だと、sockファイルを格納するフォルダが存在しないと怒られるため、今回の場合/home/gaku配下にrunフォルダを作成します。

cd /home/gaku
mkdir run

これで準備完了です。
pumaをdevelop環境で起動する場合は下記コマンドを

puma -w 4

pumaをproduction環境で起動する場合は下記コマンドを記述し実行する。

rails assets:precompile RAILS_ENV=production
SECRET_KEY_BASE=$(rake secret) RAILS_SERVE_STATIC_FILES=true RAILS_ENV=production puma -w 4

(※4はスレッドの数です。)

おわり(‘◇’)ゞ

おわりに

比較的簡単にpuma+nginx環境を構築することが可能でした。
unicorn+nginxの場合はいろいろ設定しないといけませんでしたが、rails5になって各段に簡単になりましたね。
今後、railsアプリケーションを本番環境で構築する場合はpuma+nginxで決まりです!( ゚Д゚)

docker-composeを使って複数コンテナの管理を簡易化する

Gakuです。

前回はdockerを使用し、railsコンテナとpostgreSQLコンテナを立ち上げ連携する方法を掲載しました。
[blogcard url=”http://160.16.72.126/?p=569″][/blogcard]

今回はdocker-composeなるものを導入し、複数コンテナの管理を簡易化したいと思います。

docker-composeとは何ぞ?

ここらへんの記事をみると幸せになれるかもしれません。
[blogcard url=”http://qiita.com/y_hokkey/items/d51e69c6ff4015e85fce”][/blogcard]

複数コンテナを1コマンドで立ち上げたり、docker run時のめんどうなオプションを記述して管理できる仕組みです。

ファイル構成

ファイル構成は下記のような感じで構成します。

.
├── docker-compose.yml
└── rails
    └── Dockerfile

Dockerfileは前回と同様のDockerfileを使用しております。

docker-compose.ymlの編集

postgreSQLとrailsコンテナを管理するため、docker-compose.ymlを下記のように編集します。

postgres0:
  image: postgres:9.5.4
  ports:
    - 5432:5432
rails:
  build: rails
  ports:
    - 3000:3000
  volumes:
    - /Users/gaku/Documents/develop/projects:/usr/src/docker-rails-test
  links:
    - postgres0:postgres0
  tty: true

設定内容はdocker run時のオプションと似ているのでとっつきやすいかと思います。

これで準備完了です( ^ω^ )

実行してみる

実行はすごく簡単です。

docker-compose build //イメージの作成
docker-compose pull  //イメージのダウンロード
docker-compose up -d //コンテナの生成

たったこれだけです。
3コマンドで全てのコンテナのイメージ作成からコンテナ生成までやってくれます。
こ。。。これがdockerの強さか。。。

後片付けのコマンド

コンテナの後片付けもすごく簡単です。

docker-compose stop //全てのコンテナの停止
docker-compose rm   //全てのコンテナの削除

今まで一つ一つコンテナを削除していたのですが、これで一気に削除できます。
う〜ん。きもちぃε-(´∀`; )

/bin/bashが起動できない

今までdocker run -it コマンドでbashを立ち上げる設定をしていたのですが、docker-composeには-i相当の機能がないらしい。
(-tはdocker-composeのtty:trueの記述が該当している。)

なので、docker-composeで/bin/bashを立ち上げる場合、下記コマンドで実行してあげる必要がある。

docker exec -it <コンテナID> bash

おわりに

docker-composeを知るまで、

「dockerめんどくせぇな〜。vagrant+virtualBOXのが良いんじゃね(´q` )」
って思っていましたが、今回composeやってみて世界が変わりました。

dockerで設定すれば、もう環境構築ほとんどやらんでええやん!すばらしき世界!

2日間dockerを触ってきて、だいたいのことはできるようになりました。
今度はheroku上のdocker-herokuなるもので、herokuへのUPを試みたいと思います( *`ω´)

DockerでpostgreSQLを導入しrailsと連携する

Gakuです。

前回までで、Dockerfileからrails環境を構築する方法を掲載してきました。
[blogcard url=”http://160.16.72.126/?p=562″][/blogcard]

今回はpostgreSQLコンテナを作成し、railsコンテナと連携する方法を掲載したいと思います。

postgreSQLコンテナの準備

下記コマンドを実行することで、postgreSQLコンテナを作成できます。

docker pull postgres:9.5.4
docker run --name pos-con -p 5432:5432 -d postgres

簡単すぎる( ^ω^ )

railsコンテナの準備

下記コマンドを実行しrailsコンテナを作成します。

docker run -it -p 3000:3000 -v "$PWD":/usr/src/docker-rails-test --name railstest --link pos-con:pos-con  gaku/rails

(※–linkオプションが今回の肝です。)

で、仮想環境へアクセスされると思うので、対象のフォルダでrails newします。

rails new postgretest -d postgresql

これで準備完了です。

database.ymlを編集しpostgreSQLとコネクトする

railsのdatabase.ymlのdefault部分を下記のように編集し、postgreSQLコンテナとドッキングします。

default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: pos-con
  username: postgres

下記コマンドでエラーが出ずdatabaseが作成されれば完了です。

rails db:create

おわりに

案外簡単にpostgreSQLとrailsの連携が可能でした。
今までは単体で起動していた各コンテナを、まとめて立ち上げることが可能なdocker-composeなるものを触ってみようと思います。( ^ω^ )

Dockerでrails環境を構築する

Gakuです。

前回の記事で、Dockerfileを作成しrubyコマンドを実行するところまで備忘録として残しました。
[blogcard url=”http://160.16.72.126/?p=557″][/blogcard]

今回はそのDockerfileを編集し、rails環境を構築します。

Dockerfileを編集

Dockerfileを以下のように編集し、rails環境構築用Dockerfileを作成します。

vi Dockerfile
FROM ruby:2.3.1

ENV APP_ROOT /usr/src/docker-rails-test

#Workディレクトリの設定
WORKDIR $APP_ROOT

#apt-getでtoolのインストール
RUN apt-get update && \
        apt-get install -y nodejs && \
        apt-get install -y vim

#rails導入
RUN gem install --no-ri --no-rdoc rails -v 5.0.0.1

#docker runの-pのヒント これでポート解放されるわけではない
#あくまで道しるべ
EXPOSE 3000:3000

#bashの立ち上げ
CMD ["/bin/bash"]

これで準備完了です( ^ω^ )

railsコンテナを立ててみる

作成したDockerファイルをビルドしてイメージを作成します。

docker build -t gaku/rails .

作成したイメージからコンテナを作成する。

docker run -it -p 3000:3000 -v "$PWD":/usr/src/docker-rails-test gaku/rails

そしたら仮想環境へアクセスする形となるので、いつもどおりrailsアプリケーションを作成してアプリケーションを立ち上げる

rails new test1
cd test1
rails s -b 0.0.0.0

docker-machineのipを確認しておき、そのipでホストPCのブラウザよりアクセスする。
スクリーンショット 2016-08-16 10.21.42

おつかれさまでした〜( ^ω^ )

作成したコンテナを操作する

一旦exitコマンドでコンテナを抜けるとコンテナが終了してしまう。
その際はコンテナを起こしてあげて、アクセスする必要がある。
下記コマンドで上記操作は可能です。

docker start コンテナID
docker attach コンテナID

おわりに

完全にDockerfileのCMDコマンドではまりました。。。つらかった。
CMDでbashを立ち上げるように設定するのがミソですね。
また、docker run時にいろいろなオプションを付けるのですが、その点をミスらなければすんなりrailsの導入は可能です。
次回はDBをpostgreSQLへ変更した場合の対処法などを掲載したいと思ってます。

railsでvideoタグを使って複数動画を永遠再生する方法

Gakuです。

Railsでvideoタグを使う際、少しはまったので備忘録として残します。
やりたいこととしては、2つの動画があって自動的に順次再生されるような実装を行います。

とりあえず、erb部分はこんな感じで実装。

<%= video_tag 'top.mov',:id=>'video1',:class=>'img-responsive',:muted=>true %>
<%= video_tag 'top2.mov',:id=>'video2',:class=>'img-responsive',:muted=>true %>

videoタグのヘルパーを使用し、2つの動画をセットします。
これら動画はassets/imagesへ格納しておきます。

次にjsの実装を行います。
実装内容はこんな感じです。

//topビデオ再生ロジック
$(function () {
  var video1 = $('#video1');
  var video2 = $('#video2');

  video1.get(0).play();

  $(video1.get(0)).on('ended',function() {
    video1.hide();
    video2.show();
    video2.get(0).play();
  });

  $(video2.get(0)).on('ended',function() {
    video2.hide();
    video1.show();
    video1.get(0).play();
  });
});

“ended”は動画再生後に発火するイベントです。
これで永遠ループし動画が再生してくれます。

このままでは動画が2つ並んで表示されてしまうため、cssを下記のように指定し完成です。

//topvideoを隠す
#video2{
  display: none;
}

2つの動画をループで再生させる方法をご紹介させて頂きました。
コードとしては少し複雑になってしまうため、動画を編集し1つの動画としてvideoタグを使った方が良さげですね笑