- 投稿日:2020-01-10T22:02:52+09:00
Dockerで環境構築する際、ソースコードの変更が即時反映されない場合の対処法
記事の目的
docker-composeで環境構築する際に起こったRailsのソースコードを修正しても即時反映されない問題に対しての対処法を共有すること。
対処法
1.development.rbを編集
開発環境用の設定ファイルである
config/environments/development.rbを編集。
「 ~ 」は元々の記述を省略しているものとする。
この中にconfig.reload_classes_only_on_change = falseという記述を追加する。development.rbRails.application.configure do ~ config.reload_classes_only_on_change = false end2.railsコンテナを再起動
設定を記載しただけでは反映されないので、最後にRailsを再起動する。
ターミナル上で、
$ docker-compose restartと入力する。
以上でソースコードの変更が即時反映される。
終わりに
Dockerで環境構築をした際に、もう設定しておくと良い。
- 投稿日:2020-01-10T21:58:18+09:00
はじめてAWSでデプロイする方法③(AWSセキュリティグループの設定)
これまでの記事
はじめてAWSでデプロイする方法①(インスタンスの作成)
はじめてAWSでデプロイする方法②(Elastic IPの作成と紐付け)前回までの流れ
作成したEC2インスタンスとElastic IPを紐付けして、パブリックIPを固定にした。
今回の流れ
現状
現時点において、HTTP(www.サイトURL)で接続することはできない。
(ターミナルでEC2とSSH接続は可能。)つまり、一般ユーザーは閲覧することはできない状態である。
なので、今回はHTTP接続(www.)を解放して、URLでサイトを閲覧できるようにしていく。ポート(入り口)の解放
このHTTP接続(www.)の入り口となるのが、「ポート」(扉)と呼ばれます。IPアドレスが住所「家」であれば、ポートは外に出る・外から入る「扉(ドア)」に該当します。
ポートの設定をするためには、「セキュリティグループ」という設定を変更していきましょう
本題、セキュリティグループの設定
セキュリティグループとは、AWSのファイアウォール機能の一つ。
プロトコル、ポート範囲、送信元/送信先IPアドレスによるパケットフィルターが可能。
インスタンス単位に適用することができる。手順
- AWSのEC2ダッシュボードを開く
![]()
- 『実行中のインスタンス』をクリック
![]()
セキュリティグループの『launch-wizard-3』をクリック
補足: インバウンドルール(この後追加します)
そのセキュリティグループに関連付けられたインスタンスにアクセスできるトラフィックを規制する。『インバウンドルールの表示』をクリックすると下記が表示される。
補足: アウトバウンドルール(この後追加します)
そのセキュリティグループに関連付けられたインスタンスからどの送信先にトラフィックを送信できるか(トラフィックの送信先と送信先ポート)を制御するルール
『アウトバウンドルールの表示』をクリックすると下記が表示される。
(ここから、セキュリティグループの『launch-wizard-3』をクリック後に続く)
5. 下記の画面が表示される
6.『 インバウンド 』を選択
7. 『 編集 』をクリック
8. 左下の『ルールの追加』をクリック
9. タイプ:『 HTTP 』を選択
10. 画面左下の『 保存 』をクリック
11. 完了
これでIPアドレス、WWW.やドメインでのWEB閲覧が可能となります。次はEC2にSSHログインしていきましょう!
ここまで、お疲れ様でした。
なかなか慣れない作業で疲れたのではないでしょうか?セキュリティグループについては、下記記載のAWSのセキュリティグループリファレンスを参照してみるといいかもしれません。
次回は自身で作成したWEBアプリとEC2サーバーを紐づけていくために、SSHログインしましょう
次回の記事はこちら!
はじめてAWSでデプロイする方法④(EC2にSSHログイン)参考
- 投稿日:2020-01-10T17:09:11+09:00
bundle installするときに "can't find gem bundler (>= 0.a) with executable bundler (Gem::GemNotFoundException)" とErrorが出る
問題が起きたらググれって偉い人が言ってた
対象のディレクトリ下でbundle installするときに起った現象のメモ
※初学者なので細かめに記載git cloneしたアプリのgemを入れようとしたら以下のエラーが出た。
consoleTraceback (most recent call last): 2: from /Users/mac/.rbenv/versions/2.5.3/bin/bundler:23:in `<main>' 1: from /Users/mac/.rbenv/versions/2.5.3/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path' /Users/mac/.rbenv/versions/2.5.3/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundler (Gem::GemNotFoundException)結局原因ってなんなの?
どうやらbundlerとGemfile.lockのversionが異なっていたので、
『bundlerのgemが見つからないよ!!!!!』って怒られていたらしい。
version違うだけで見つからないのは、当たり前とはいえ
ぶち当たるとちょっとテンション落ちる。
ドジっ子と思えばそうでもないかもしれない。どうやって解決したの?
方法は2つ
・bundlerのダウングレードをする
・Gemfile.lockにある 'BUNDLED WITH' をbunderのversionに対応させるbunderのダウングレードはいっぱい記事があるので、
検索してみてください。そもそものbundlerのversionチェック
ルートディレクトリで以下のコマンドを叩く
bundlercheck$ bundle -vGemfile.lockにある 'BUNDLED WITH' をbunderのversionに対応させるの方法
bundler$ cd ~/[対象のディレクトリ]bundler$ vim Gemfile.lockファイルの中身が見れるようになるので、
G(Shift+g)で最終行へ
x.x.xを対応のversionに書き換えます。Gemfile.lockBUNDLED WITH x.x.x書き換え方
i → インサートモードへ(書き換えができるようになる)
esc → インサートモードの終了
:wq!を入力 → 保存して強制終了これでbundle -v したり bundle install して、
問題なければヨシッ!まとめ
いろんな記事を読んで模索した結果なので、これが最善の解説策かはわかりません。
なのでこれだけでなくいろんな記事を読んで、
ここは一つの参考にしていただければと思います。
- 投稿日:2020-01-10T16:19:44+09:00
Railsでカンマ区切り+小数点以下表示で数値を出力する方法
目的
整数部をカンマ区切りで表示し、小数点以下を表示したい
コード
number_with_precision(123456789, precision: 2, delimiter: ',') #=> "123,456,789.00"参考リンク
ruby-on-rails — 大きな数字にカンマを追加するためのRailsトリックはありますか?
ActionView::Helpers::NumberHelper
- 投稿日:2020-01-10T15:51:48+09:00
はじめてAWSでデプロイする方法②(Elastic IPの作成と紐付け)
前回の記事
はじめてAWSでデプロイする方法①(インスタンスの作成)の続きになります。
インスタンスの作成などを知りたい場合は、この記事を参照してください。今回実施していくこと
作成したEC2インスタンスには、作成時にIPアドレスが""自動""で割り振られています。
これをパブリックIP(一般公開用のID)と言います。
しかし、""サーバーを再起動させるたびにこのパブリックIPが変わってしまうという欠点""を持っています。そのため、パブリックIDを固定して、いちいち更新しないようにします。
この固定化したパブリックIDを『 Elastic IP 』と呼びます。今回はその欠点を改善するために、『 EC2インスンタンスとElastic IP紐付け 』をしていきましょう。
Elastic IPの作成
EC2インスタンスのパブリックIPアドレスをElastic IPに固定する。
Elastic IPとは、AWSから割り振られた固定したパブリックIPアドレス。
このパブリックIPアドレスをEC2インスタンスに紐付けることで、インスタンスの起動、停止に関わらず常に同じIPアドレスで通信をすることが可能になります手順
AWSのサイドナビにある、『Elastic IP』をクリック。こちらからでも進めます
Elastic IPアドレスは、パブリック IPv4 アドレスの項目にも記載されています(公開するわけにはいかないので伏せています)
Elastic IPアドレスとEC2インスタンスと紐付け
ここからEC2インスタンスとElastic IPアドレスを紐付けします。
紐付けが完了すれば、EC2インスタンスのパブリックIPは、Elastic IPアドレスで固定されます手順
- Elastic IPアドレスを選択✅
作成したEC2インスタンスを選択
補足:上の画像のようにインスタンスを選択すると、その下にあるプライベートIPアドレスが自動で選択されます。なのでプライベートIPアドレスは空白で大丈夫です無事に関連づけられたインスタンスに『i- (EC2インスタンスID)』が表示されています
次は AWS セキュリティグループの設定
みなさん、ここまでお疲れ様です。
慣れていないとここまででも大変かと思います。立ち上げたばかりのEC2インスタンスはSSHでアクセスすることはできますが、HTTPなどの他の接続は一切つながらないようになっています。そのため、WEBサーバとして利用するEC2インスタンスは事前にHTTPがつながるように「ポート」を開放する必要があります
次回はポート解放の操作をお伝えしていきたいと思います。
長くなってきたので、次の記事で案内したいと思います。
はじめてAWSでデプロイする方法③(AWSセキュリティグループの設定)いいね!とフォローをして、有料級記事を見逃すな
- 投稿日:2020-01-10T15:43:15+09:00
【Rails】has_secure_passwordメソッド
has_secure_passwordメソッドについてのメモです。
準備
usersテーブルにpassword_digestカラムを追加しておく。
bcryptをインストールする。
Gemfilegem 'bcrypt'ターミナル$ bundle installモデルに
has_secure_passwordを記載する。app/models/user.rbclass User < ApplicationRecord has_secure_password end機能
- 暗号化されたパスワードがpassword_digestカラムに保存される。
- 仮想属性
password_confirmationを使用して、入力ミスを減らすためにパスワードの確認入力をさせることができる。- authenticateメソッドを使用して、メールアドレスとパスワードに基いてユーザー認証を行うことができる。
- 投稿日:2020-01-10T15:05:28+09:00
Railsアプリケーションのメモリが膨れ上がる問題
次のグラフは、Herokuで運用している、とあるRailsアプリケーションのMemory Usageです。1日1回再起動がかかったあと、スワップが発生するまでメモリ使用量が増え続けます。特に大きなデータをメモリ上に置き続けているわけではありません。
Passengerの作者Hongli Lai氏が、Rubyのメモリが膨れ上がる問題について研究して記事を書いています(2019年3月)。
日本語での概略は、次の記事の真ん中あたりで読めます。
Hongli Lai氏が見つけたのは、Rubyはメモリを正しく解放しているが、Cのライブラリ(glibc)のmalloc周りがなかなかメモリを回収してくれない、ということです。メモリ使用量よりパフォーマンスを優先しているせい、との見立てです。
メモリ使用量が膨れ上がるのを防ぐ方法は、3つあります。1と2は以前から知られた方法で、3はHongli Lai氏が発見した方法です。Hongli Lai氏の説が正しければ、3が本質的な解決方法ということになります。
- mallocの代わりにjemallocを使ってRubyをコンパイルする。
- 環境変数 MALLOC_ARENA_MAX=2 を指定する。
- ガベージコレクションの後でmalloc_trimを呼ぶ。
Hongli Lai氏は、この件について一緒に研究してくれるよう呼びかけています。
RubyのBug trackerでも報告されていますが、話は進んでいないもよう。
Rubyに上記の3のパッチを当てるプロジェクトが公開されています。残念ながらHeroku用は開発が進んでいないようです。
Herokuでは、上記の2の環境変数MALLOC_ARENA_MAX=2はデフォルトになりました。ただし、2019年9月24日より前に作られたアプリケーションでは自分で設定する必要があります。
MALLOC_ARENA_MAXを指定すると、レスポンスタイムが若干増えるという実験結果があります。
以上です。私自身は上記1-3のどれも実際には試していません、すいません。?♂️
- 投稿日:2020-01-10T14:55:59+09:00
はじめてAWSでデプロイする方法①(インスタンスの作成)
AWSアカウントのリージョン設定をしよう
リージョンとは、AWSの物理的なサーバの場所を指定するものです。リージョンは世界各地に10箇所以上存在し、そのうちの一つは東京にあります。
リージョンを東京に設定していきましょう手順
EC2インスタンスを作成
「サーバーを生成する」といっても、AWSが全てのサーバを物理的に用意しているわけではなく、実際には「仮想マシン」と呼ばれるソフトウェアを利用しています。
この「仮想マシン」のことをAWSでは「EC2インスタンス」と呼んでいます。手順
AWSにアクセス
「 Amazon Linux2 AMI 」ではなく、「 Amazon Linux AMI 」を選択してください。
(上から2番目にあります)
無料枠で利用できる「t2.micro」を選択し、画面右下の 『確認と作成』 をクリック
( EC2インスタンスのタイプを選択します。EC2ではさまざまなインスタンスタイプが用意されており、CPUやメモリなどのスペックを柔軟に指定することができます。)キーペア名を入力(空白NG)
キーペアのダウンロード(ファイル名.pem)
?注意:こちらはインスタンスにSSHでログインする際に必要となる「秘密鍵」です。これがないとEC2インスタンスにログインできないので、必ずダウンロードしてパソコンに保存しておきましょう。また、間違って他人に渡さないよう気をつけてください。
ダウンロードしたpemキー(ファイル名.pem)のsshフォルダに移行する$ cd ~ #ターミナルをスタート地点に戻す $ mkdir ~/.ssh #.sshというディレクトリを作成 # エラー『 mkdir: /Users/owner/.ssh: File exists 』と表示の場合、すでに存在します $ mv Downloads/ファイル名.pem .ssh/ # mvコマンドで、移動させたい対象(ファイル名.pem) → .sshディレクトリに移動します。 $ cd .ssh/ $ ls # pemファイルが存在するか確認します12.画面右下の『インスタンスの作成』をクリック
13. 作成完了(反映に時間がかかる場合があります)
14.次のインスタンスの作成がされました: 『 i- 』のインスタンスIDをクリック
15. 作成したインスタンスがrunningと表示されて、稼働している
完了
次は『 Elastic IPの作成と紐付け 』をしよう
ここまで、お疲れ様です。
初めてだとかなり、疲れたと思います。先ほど作成したEC2インスタンスには、作成時にIPアドレスが自動で割り振られています。これをパブリックIPと言います。しかし、サーバーを再起動させるたびにこのパブリックIPが変わってしまうという欠点を持っています。
次回はその欠点を改善するために、『 Elastic IPの作成と紐付け 』をしていきましょう。
長くなったので、次の記事で続きを記載します
はじめてAWSでデプロイする方法②(Elastic IPの作成と紐付け)
- 投稿日:2020-01-10T14:25:28+09:00
rails usersテーブルの値をpasswordなしで更新する
はじめに
Userテーブルのカラムをpasswordなしで更新しようと思ったときに、更新ができずに手間取ってしまったのでその備忘録として記載する。
概要
usersテーブルにprofileというカラムを持たせていたのだが、ユーザー登録後にユーザーページからユーザー情報を更新したい。
ぶつかった課題
controllerで以下のように定義して実行した際にRollbackが起こり、値が更新されなかった。
mypage_controller.rbclass MypageController < ApplicationController # 途中略 def update user=User.find(current_user.id) #パスワードなしでのプロフィールの変更 user.update_without_password(nickname:params[:mypage][:nickname],profile: params[:mypage][:profile]) redirect_to root_path,notice: 'プロフィールが変更されました' end # 途中略 end
- エラー内容
[2] pry(#<MypageController>)> user.update_without_password(nickname:params[:mypage][:nickname],profile: params[:mypage][:profile]) (0.3ms) BEGIN ↳ (pry):2 User Exists (3.4ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'ytest@gmail.com' AND `users`.`id` != 21 LIMIT 1 ↳ (pry):2 (0.2ms) ROLLBACK ↳ (pry):2 => false [3] pry(#<MypageController>)> user.errors => #<ActiveModel::Errors:0x00007f8b3304a270 @base= #<User id: 21, email: "ytest@gmail.com", last_name: "test", first_name: "test", last_name_kana: "test", first_name_kana: "test", nickname: "test", profile_image: nil, birthday: "1990-12-04", telephone: "12345678", created_at: "2020-01-10 04:36:29", updated_at: "2020-01-10 04:36:29", provider: nil, uid: nil, profile: "test">, @details={:password=>[{:error=>:too_short, :count=>6}, {:error=>:blank}], :password_confirmation=>[{:error=>:blank}]}, @messages={:password=>["は6文字以上で入力してください", "を入力してください"], :password_confirmation=>["を入力してください"]}>解決策
modelファイルのバリデーションいじった。
詳細は以下
- 変更前
user.rbclass User < ApplicationRecord # 途中略 validates :password, length: { minimum: 6 } validates :password_confirmation, presence: true validates :password, presence: true, unless: :uid? end
- 変更後
passwordのバリデーションに対して、on create を追加することで、 userの新規登録するときにのみバリデーションによる入力チェックがかかるように変更した。コード内容は以下
user.rbclass User < ApplicationRecord # 途中略 # create のみバリーデーションをかける validates :password, length: { minimum: 6 }, on: :create validates :password_confirmation, presence: true, on: :create validates :password, presence: true, unless: :uid?, on: :create endとりあえずバリデーションを状況によって、かけたい場合には、オプションとしてon< xxx >を指定すればよいらしい。
ちなみに参考資料はこちらもっと勉強しないとなぁ〜
- 投稿日:2020-01-10T13:59:38+09:00
Railsで開発した個人アプリにDockerを導入する手順と最低限の知識
Railsで開発した個人アプリに、後からDockerを導入しました。
その時知識不足なせいでハマってしまった場面があったので、自分の中で整理してアウトプットすることを目的にこの記事を書き残します。ちなみに、以下の記事を主に参考にさせていただきました。
DockerをMacにインストールする
Docker + Rails + Puma + Nginx + MySQLRailsアプリにDockerを導入する手順+事前知識
まずは事前知識として、これは知っておいたほうがいいというものを簡単に書いていきます。
事前知識 - Docker関係
Docker(ドッカー)
※1.軽量な仮想化環境を実現するためのツール。
OS やアプリケーションを設定したものを丸ごと実行イメージとして保存できるので、Docker が導入されている別のマシンにそのまま持って行くことができる。
実行環境をテキストファイルとして共有できるのでとても便利。
※1.仮想化環境とは、コンピュータ上にソフトウェアによって仮想的に構築されたコンピュータ(仮想マシン)が備える仕様や機能の総体のこと。
Dockerイメージ
Dockerイメージは、コンテナを起動させるためのベースとなるもの(オブジェクト指向でいうと「クラス」にあたる)
テキストファイル(Dockerfile)からビルドされる。(後に記述)
DockerHub(Docker向けのコンテナ共有サービス)では、既に多くのイメージが公開されている。
Dockerコンテナ
Dockerのコンテナは、 Dockerイメージを元に作成される仮想環境の実行部分(オブジェクト指向でいうと「インスタンス」にあたる)
原則1コンテナ1アプリ。
Dockerfile(ドッカーファイル)
指定したベースのDockerイメージに加える変更を記述するファイル。
Dockerfileを使うことでオリジナルのDockerイメージを作成することができる。
docker-compose(ドッカーコンポーズ)
複数のコンテナから構成されるアプリケーションで、Dockerイメージのビルドや各コンテナの起動・停止などをより簡単に行えるようにするツール。
docker-composeを使用する際は「docker-compose.yml」が必要になる。
事前知識 - サーバ関係
ミドルウェア
OSとアプリケーションの間に入り、中間的な処理を行うソフトウェアのこと。
ー 例 ー
- Webサーバ
- Apache、NginXなど
- APサーバ
- Puma
- Unicornなど
- DBサーバ
- MySQL
- PostgreSQLなど
Nginx(エンジンエックス)
webサーバの一つ。
Apacheよりも処理能力が高い。
puma(プーマ)
※1.Rackという機能を提供するためのアプリケーションサーバ。
webサーバの1つでもある。
※1.RackとはWeb サーバと Rubyやフレームワークをつなぐ最小のインタフェースを提供するもの。
Docker導入手順
① Docker for Macを公式サイトからインストール、そして起動
公式サイトで会員登録を済ませた後、Docker for Macをダウンロードしインストール。
インストールが終わったら、Dockerを起動しておく。
(MACの画面上部にDockerのマークが出れば起動できてる証拠)②作成済みのアプリケーションフォルダの直下に「Dockerfile」、「docker-compose.yml」ファイルを新しく作成する。
フォルダ構成
- 既存のRailsアプリフォルダ
- app
- bin
- config
- db
- ・・・
- Dockerfile
- docker-compose.yml
③Dockerfileに記述する(アプリケーションフォルダ直下)
DockerfileFROM ruby:2.5.1 RUN apt-get update && \ apt-get install -y mysql-client nodejs vim --no-install-recommends && \ rm -rf /var/lib/apt/lists/* RUN mkdir /myproject WORKDIR /myproject ADD Gemfile /myproject/Gemfile ADD Gemfile.lock /myproject/Gemfile.lock RUN gem install bundler RUN bundle install ADD . /myproject RUN mkdir -p tmp/sockets④docker-compose.ymlに記述する(アプリケーションフォルダ直下)
docker-compose.ymlversion: '2' services: db: image: mysql:5.6 environment: - ./environments/db.env volumes: - mysql-data:/var/lib/mysql ports: - "4306:3306" app: build: . command: bundle exec puma -C config/puma.rb volumes: - .:/myproject - public-data:/myproject/public - tmp-data:/myproject/tmp - log-data:/myproject/log web: build: context: containers/nginx volumes: - public-data:/myproject/public - tmp-data:/myproject/tmp ports: - 80:80 volumes: mysql-data: public-data: tmp-data: log-data:⑤アプリケーションフォルダ直下に「environments」フォルダを作成、さらにenvironmentsフォルダ直下に「db.env」ファイルを作成する。
- 既存のRailsアプリフォルダ
- app
- bin
- config
- db
- environments
- db.env
- ・・・
- Dockerfile
- docker-compose.yml
⑥db.envを編集
environments/db.envMYSQL_ROOT_PASSWORD=password MYSQL_USER=user MYSQL_PASSWORD=password⑦database.ymlを編集
config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: <%= ENV.fetch('MYSQL_USER') { 'root' } %> password: <%= ENV.fetch('MYSQL_PASSWORD') { 'root' } %> host: db⑧アプリケーションフォルダ直下に「containers」フォルダを作成、さらにcontainersフォルダ直下に「nginx」フォルダを作成する。
フォルダ構成
- 既存のRailsアプリフォルダ
- app
- bin
- config
- containers
- nginx
- db
- environments
- db.env
- ・・・
- Dockerfile
- docker-compose.yml
⑨作成したnginxフォルダ直下に「Dockerfile」、「nginx.conf」ファイルを作成する。
- 既存のRailsアプリフォルダ
- app
- bin
- config
- containers
- nginx
- Dockerfile
- nginx.conf
- db
- environments
- db.env
- ・・・
- Dockerfile
- docker-compose.yml
⑩Dockerfileに記述する(containers/nginxフォルダ直下)
containers/nginx/DockerfileFROM nginx:1.15.8 RUN rm -f /etc/nginx/conf.d/* ADD nginx.conf /etc/nginx/conf.d/myproject.conf CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf⑪nginx.confに記述する(containers/nginxフォルダ直下)
containers/nginx/nginx.confupstream myproject { server unix:///myproject/tmp/sockets/puma.sock; } server { listen 80; server_name 13.112.60.229; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; root /myproject/public; client_max_body_size 100m; error_page 404 /404.html; error_page 505 502 503 504 /500.html; try_files $uri/index.html $uri @myproject; keepalive_timeout 5; location @myproject { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_pass http://myproject; } }⑫puma.rbを編集
puma.rbapp_root = File.expand_path("../..", __FILE__) bind "unix://#{app_root}/tmp/sockets/puma.sock" stdout_redirect "#{app_root}/log/puma.stdout.log", "#{app_root}/log/puma.stderr.log", true⑬ターミナルでコマンドを実行
ファイルの準備が整ったら、最後にターミナル上でコマンドを実行。
(railsアプリケーションフォルダ内で実行する)イメージを構築する
ターミナル$ docker-compose buildrailsのコンテナを作成し、データベースの作成処理を行う
ターミナル$ docker-compose run --rm app rake db:create db:migrate全てのコンテナを構築・起動する
ターミナル$ docker-compose up上記の流れが終わったあとlocalhostにアクセスすると、しっかり確認することができました。
ちなみに今回書きまとめたものは、DBもDockerで管理することになりますが、DBはローカルのものを参照したいという場合、以下の記事が参考になるかと思います。
既存のRailsアプリをDocker化し、ローカルのDBに接続する方法(おまけ)
Dockerfileに記述できるコマンド一覧
コマンド 意味 FROM ベースとなるイメージ RUN docker build 時に実行するコマンド CMD docker run 時に実行するコマンド ENTRYPOINT docker run 時に実行するコマンド MAINTAINER 作者情報 LABEL ラベル情報(メタデータ) EXPOSE 公開ポート番号 ENV 環境変数 ARG 一時変数 COPY ホストからコンテナへのファイルコピー ADD ファイル/ディレクトリの追加 VOLUME ボリュームのマウント USER 実行ユーザ SHELL シェル指定 WORKDIR ワークディレクトリ ONBUILD ビルド時に実行するコマンド STOPSIGNAL コンテナ終了時に送信されるシグナル HEALTHCHECK ヘルスチェック ターミナル上で実行できるdocker-composeコマンド一覧
コマンド 意味 build サービスの構築または再構築 config compose ファイルの確認と表示 create サービスの作成 down コンテナ・ネットワーク・イメージ・ボリュームの停止と削除 events コンテナからリアルタイムにイベントを受信 help コマンド上でヘルプを表示 kill コンテナを kill (強制停止) logs コンテナの出力を表示 pause サービスを一時停止 port ポートに割り当てる公開用ポートを表示 ps コンテナ一覧 pull サービス用イメージの取得 restart サービスの再起動 rm 停止中のコンテナを削除 run 1度だけコマンドを実行 scale サービス用コンテナの数を指定ド start サービスの開始 stop サービスの停止 up コンテナの作成と開始 version Docker Compose のバージョン情報を表示
- 投稿日:2020-01-10T13:55:28+09:00
bundle install時に"[DEPRECATED] The `--path` flag is deprecated"という警告が発生した場合の対応手順
はじめに
Bundler 2.1ではBundler 3で使えなくなる機能に対して警告が表示されるようになりました。
参考:【翻訳】Bundler 3アップグレードガイド - Qiita
この関係でBundler 2.1では
bundle installに--pathオプションを付けると以下のような警告が発生します。$ bundle install --path vendor/bundle [DEPRECATED] The `--path` flag is deprecated because it relies on being remembered across bundler invocations, which bundler will no longer do in future versions. Instead please use `bundle config set path 'vendor/bundle'`, and stop using this flagこの記事ではこの警告に対する対応手順を説明します。
なお、「今日初めてBundlerを使った」というRuby初心者さんは、必ずこの記事を最後まで読んでください!(大事な話が書いてあります)
対応手順
すでにbundle installを実行した場合
警告は出るものの、
bundle install実行後も--path vendor/bundleのオプションは記憶されます。
ですので、それ以上の操作は必要ありません。bundle installをまだ実行していない場合
bundle installをまだ実行していない場合は、bundle installを実行する前にbundle configコマンドで明示的にpathを設定してください。
それから--pathオプションなしでbundle installを実行すると警告は発生しません。なお、pathの設定方法はglobalとlocalの2種類があります。
従来のbundle install --path vendor/bundleと同じ動きになるのはlocalの方です。# マシン全体でbundle install実行時のインストール先を # vendor/bundleに設定する場合(global) bundle config set path 'vendor/bundle' # そのプロジェクト内でのみ、bundle install実行時の # インストール先をvendor/bundleに設定する場合(local) bundle config set --local path 'vendor/bundle' # --pathオプションなしでインストールを実行する bundle install最後に:でもちょっと待って!!本当にpathの指定は必要?
もしあなたが今までBundlerを使ったことがなく、「ネットで見つけたBundlerの紹介記事を見ながら
bundle installをしようとしたら警告が出たので、警告メッセージでググってこのページにやってきた」という人であれば、きっと--path vendor/bundleを付ける必要はありません。
--path vendor/bundleのオプションを付けることを推奨している多くのWeb記事は、その必要性を十分に理解していないものが多いです。pathオプションは特殊な条件下でしか必要になりません。
ですので、「今日初めてBundlerを使います」というような初心者さんは、 pathを指定せずにシンプルにbundle installを実行してください。(すでに
bundle install --path vendor/bundleを実行した人は、次回からpathオプションなしでbundle installしてください)この件に関する詳しい話は以下の記事にまとめているので、こちらも読んでもらえると幸いです。
bundle install時に--path vendor/bundleを付ける必要性は本当にあるのか、もう一度よく考えてみよう - Qiita
- 投稿日:2020-01-10T13:49:18+09:00
既存のRailsアプリをDocker上で環境構築する方法+sequel proによるDBコンテナ可視化
はじめに
新規アプリをDocker環境で開発するやり方はたくさんあるけど、既存アプリをDocker環境で構築するやり方は全然見当たらず、わりと苦労しました。
振り返ってみると新規アプリでの構築の仕方とあまり変わらないはずなのですが、色々エラー出て苦労したのでまとめておきます。個々のコマンドの意味もできるだけ記載しました。
単なる環境構築だけでなく、DBコンテナのsequel proによる可視化やAPPコンテナでのbinding.pryの仕方、bundle install後にbuildし直さなくてもよい設定にする方法などもまとめました。同じく既存のRailsアプリをDocker上で構築したい人の参考になれば幸いです。
内容について間違っていたら教えていただけると嬉しいです。
開発環境
- Ruby: 2.5.1
- Rails: 5.2.4
- MySQL: 5.6
- MacOS
前提
- Docker for Macはインストール済み
- Dockerについての基礎知識
- 今回は開発環境のみ
対象読者
作成した既存のアプリをDocker上で構築したい人
目次
- コンテナ起動までの大まかな流れ
- 実際の作業
- 番外編:sequel proによるDBコンテナの可視化
- 開発する上でのDockerコマンド
- おまけ
- railsコンテナ上でbinding.pryをする方法
- railsコンテナ上でbundle installした時に、変更内容をコンテナ上に反映させる方法
コンテナ起動までの大まかな流れ
DockerfileにてRubyのベースイメージをもとにイメージを作成する
↓
作成したイメージをもとにdocker-compose.ymlでappコンテナを作成すると同時に、DBのコンテナのイメージを作成し、これらのコンテナを連携させる
↓
database.ymlを修正してappコンテナからdbコンテナへ接続できるように設定する実際の作業
- Dockerfileとdocker-compose.ymlの作成
- Dockerfileの記載
- docker-compose.ymlの記載
- database.ymlの変更
1. Dockerfileとdocker-compose.ymlの作成
まず、開発しているアプリで、Dockerfileとdocker-compose.ymlを以下のように作成します。
アプリ名 |- app |- bin |- config #略 |- vendor - .gitignore - config.rb - Dockerfile #追加 - docker-compose.yml #追加 - Gemfile - Gemfile.lock #略2. Dockerfileの記載
続いてDockerfileの中身を書いていきます。
myprojectのところはコンテナ起動の際に作成するディレクトリ名なので、何でも大丈夫です
ただし、それ以降の記述でも随時書き換えてくださいDockerfileFROM ruby:2.5.1 RUN apt-get update && \ apt-get install -y mysql-client nodejs vim --no-install-recommends && \ rm -rf /var/lib/apt/lists/* RUN mkdir /myproject WORKDIR /myproject ADD Gemfile /myproject/Gemfile ADD Gemfile.lock /myproject/Gemfile.lock RUN gem install bundler RUN bundle install ADD . /myproject詳細な説明は省きますが、ざっと説明すると
- ruby2.5.1をベースイメージとする
- コンテナ内で必要なコマンドをインストール
- myprojectというディレクトリを作成して基点にする
- Gemfileをコンテナ上にコピーした後、bundle install
- ローカルのディレクトリ、ファイルをコンテナ上にコピー
という感じかと思います。
3. docker-compose.ymlの記載
Rubyのコンテナは作成できるようになりました。
続いてこれをもとにアプリケーションのコンテナとデータベースのコンテナを作成し、それらのコンテナをリンクさせるための作業をしていきます。
docker-compose.ymlを以下のように記載します。
*mysqlは8.0以上だと認証方法が異なるようなので注意
https://qiita.com/yensaki/items/9e453b7320ca2d0461c7docker-compose.ymlversion: '2' services: db: image: mysql:5.6 volumes: - mysql-data:/var/lib/mysql #データの永続化のために必要 ports: - "4306:3306" #両方3306でもok。詳細は下の「番外編:DBをsequel proで可視化したい」へ app: tty: true #コンテナ上でbinding.pryするために必要 stdin_open: true #コンテナ上でbinding.pryするために必要 build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myproject #ローカルのディレクトリをコンテナ上にマウント - bundle:/usr/local/bundle #bundle installした後buildし直さなくてよくなる links: - db volumes: mysql-data: bundle: #bundle installした後buildし直さなくてよくなる要点は以下
- versionは2でも3でもいいと思いますが、使えるコマンドが違ってくるみたいです。
- servicesのところにdbとappがありますが、これらがそれぞれコンテナになります。
- appのコンテナのlinksにdbがあり、これによってappコンテナとdbコンテナが連携できるようになります
- 一番下のvolumesには永続化させたいデータを記載
- appコンテナ上でvolumes: - .:/myprojectとすることで、ローカルのディレクトリをマウントしている。
- dbコンテナ上でvolumes: -mysql-data:/var/lib/mysqlとすることでデータベースで変更されたデータを永続化。この記述がないと、コンテナを壊した時に変更したデータが消えてしまいます。
- bundle installとbinding.pryのための記述は本記事、最後のおまけを参照
4. database.ymlの変更
これまでの作業でappコンテナとdbコンテナを連携させる設定をしました。
最後にappコンテナからdbコンテナに接続するために、接続設定をします。
database.ymlの中身はおそらく初期設定のままだとこんな感じの記述になってるかと思います。config/database.yml変更前default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: socket: /tmp/mysql.sockこのままだとsocket通信でDB接続をするので、せっかく作成したdbコンテナが意味なくなってしまいます。
作成したdbコンテナに接続するために以下のように変更します。config/database.yml変更後default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password:password host: db #変更(docker-compose.ymlのservice名を記載)usernameやpasswordは環境変数で設定している記事もいくつか見ますが、開発環境なら気にしなくてもいいかなと思いました。
本番環境ではちゃんと環境変数を設定します。以上で準備ができました。
あとはターミナルで該当アプリのディレクトリまで移動して、docker-compose upと入力するだけです
(Gemfile.lockの中身を削除して空にしないとエラーになるかもしれません)
localhost:3000で接続確認して終了です!今回はMySQLを使いましたが、他のDBでも可能なはずです(未検証)
*ポート番号は変わるはずなのでご注意ください番外編:DBをsequel proで可視化したい
今まで開発していた時、DBをsequel proで可視化していて便利だったのですが、docker上のDBも可視化したい!
という方に向けて以下に方法を記載しますdocker-compose.ymlで以下のように記載していました
Ruby:docker-compose.yml
db:
ports:
- "4306:3306"
これはホストが4306で接続した時にコンテナ上では3306に置き換えますという意味です。
準備はこれでokなのでsequel proで接続します。
sequel proを開いて、標準タブに切り替えます。
そこで以下の内容を入力します名前: 任意、変えなくてもok ホスト: 127.0.0.1 ユーザー名: root (database.ymlに記載のユーザー名) パスワード: password (database.ymlにパスワード) データベース: 空でok ポート: 4306(docker-compose.ymlのportsに記載した左側)ホストの127.0.0.1は自分自身を表すIPアドレス
これで見れるようになるはず!
その他開発する上で必要なコマンド
docker上でrails g controllerやrails db:migrateなどを行う時は以下のようにコンテナを通して入力します
appの部分はdocker-compose.ymlで作成したコンテナ名のappのことですdocker-compose run --rm app 入力したいコマンド(例: rails db:migrate)その他必要なコマンドは以下の記事参照
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1
全てのコンテナやイメージを削除する場合はこちら#全てのコンテナ停止 docker stop $(docker ps -q) #全てのコンテナ削除 docker rm $(docker ps -q -a) #全てのイメージ削除 docker rmi $(docker images -q)おまけ
bundle installしたい時
開発していく中で、gemを追加してbundle installしたい場面が出てくると思います
そのままやってもできるんですが、追加したgem内容がコンテナ内に反映されないため、イメージをbuildし直さなくてはなりません。
いくつか解決方法はあるみたいですが、今回はvolumeでマウントするという方法で解決しました。docker-compose.ymlapp: volumes: - bundle:/usr/local/bundle #中略 volumes: bundle:参考記事
https://qiita.com/neko-neko/items/abe912eba9c113fd527ebindin.pryしたい時
binding.pryをするためには以下の記述を追加します
docker-compose.ymlapp: tty: true stdin_open: trueおわりに
dockerについて全くわからないところから環境構築するのはかなり大変でした
自分なりにまとめられて良かった
同じような状況の人の参考になれば幸いです間違ってる場所があれば指摘していただけると幸いです
本番環境でDockerを使うのも苦労したので、そのうち開発環境との違いなどもまとめようかなと思います
参考記事
Dockerについての概要と色々なTIPSを知りたい場合は下記リンクがおすすめ
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1実際の作業で参考にした記事
https://qiita.com/azul915/items/5b7063cbc80192343fc0
https://qiita.com/Nishi53454367/items/aee4cf0c346bc115be99
- 投稿日:2020-01-10T13:49:18+09:00
既存のRailsアプリをDockerコンテナで動かす方法+sequel proによるDBコンテナ可視化
はじめに
新規アプリをDocker環境で開発するやり方はたくさんあるけど、既存アプリをDocker環境で構築するやり方は全然見当たらず、わりと苦労しました。
振り返ってみると新規アプリでの構築の仕方とあまり変わらないはずなのですが、色々エラー出て苦労したのでまとめておきます。個々のコマンドの意味もできるだけ記載しました。
単なる環境構築だけでなく、DBコンテナのsequel proによる可視化やAPPコンテナでのbinding.pryの仕方、bundle install後にbuildし直さなくてもよい設定にする方法などもまとめました。同じく既存のRailsアプリをDocker上で構築したい人の参考になれば幸いです。
内容について間違っていたら教えていただけると嬉しいです。
開発環境
- Ruby: 2.5.1
- Rails: 5.2.4
- MySQL: 5.6
- MacOS
前提
- Docker for Macはインストール済み
- Dockerについての基礎知識
- 今回は開発環境のみ
対象読者
作成した既存のアプリをDocker上で構築したい人
目次
- コンテナ起動までの大まかな流れ
- 実際の作業
- 番外編:sequel proによるDBコンテナの可視化
- 開発する上でのDockerコマンド
- おまけ
- railsコンテナ上でbinding.pryをする方法
- railsコンテナ上でbundle installした時に、変更内容をコンテナ上に反映させる方法
コンテナ起動までの大まかな流れ
DockerfileにてRubyのベースイメージをもとにイメージを作成する
↓
作成したイメージをもとにdocker-compose.ymlでappコンテナを作成すると同時に、DBのコンテナのイメージを作成し、これらのコンテナを連携させる
↓
database.ymlを修正してappコンテナからdbコンテナへ接続できるように設定する実際の作業
- Dockerfileとdocker-compose.ymlの作成
- Dockerfileの記載
- docker-compose.ymlの記載
- database.ymlの変更
1. Dockerfileとdocker-compose.ymlの作成
まず、開発しているアプリで、Dockerfileとdocker-compose.ymlを以下のように作成します。
アプリ名 |- app |- bin |- config #略 |- vendor - .gitignore - config.rb - Dockerfile #追加 - docker-compose.yml #追加 - Gemfile - Gemfile.lock #略2. Dockerfileの記載
続いてDockerfileの中身を書いていきます。
myprojectのところはコンテナ起動の際に作成するディレクトリ名なので、何でも大丈夫です
ただし、それ以降の記述でも随時書き換えてくださいDockerfileFROM ruby:2.5.1 RUN apt-get update && \ apt-get install -y mysql-client nodejs vim --no-install-recommends && \ rm -rf /var/lib/apt/lists/* RUN mkdir /myproject WORKDIR /myproject ADD Gemfile /myproject/Gemfile ADD Gemfile.lock /myproject/Gemfile.lock RUN gem install bundler RUN bundle install ADD . /myproject詳細な説明は省きますが、ざっと説明すると
- ruby2.5.1をベースイメージとする
- コンテナ内で必要なコマンドをインストール
- myprojectというディレクトリを作成して基点にする
- Gemfileをコンテナ上にコピーした後、bundle install
- ローカルのディレクトリ、ファイルをコンテナ上にコピー
という感じかと思います。
3. docker-compose.ymlの記載
Rubyのコンテナは作成できるようになりました。
続いてこれをもとにアプリケーションのコンテナとデータベースのコンテナを作成し、それらのコンテナをリンクさせるための作業をしていきます。
docker-compose.ymlを以下のように記載します。
*mysqlは8.0以上だと認証方法が異なるようなので注意
https://qiita.com/yensaki/items/9e453b7320ca2d0461c7docker-compose.ymlversion: '2' services: db: image: mysql:5.6 volumes: - mysql-data:/var/lib/mysql #データの永続化のために必要 ports: - "4306:3306" #両方3306でもok。詳細は下の「番外編:DBをsequel proで可視化したい」へ app: tty: true #コンテナ上でbinding.pryするために必要 stdin_open: true #コンテナ上でbinding.pryするために必要 build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/myproject #ローカルのディレクトリをコンテナ上にマウント - bundle:/usr/local/bundle #bundle installした後buildし直さなくてよくなる links: - db volumes: mysql-data: bundle: #bundle installした後buildし直さなくてよくなる要点は以下
- versionは2でも3でもいいと思いますが、使えるコマンドが違ってくるみたいです。
- servicesのところにdbとappがありますが、これらがそれぞれコンテナになります。
- appのコンテナのlinksにdbがあり、これによってappコンテナとdbコンテナが連携できるようになります
- 一番下のvolumesには永続化させたいデータを記載
- appコンテナ上でvolumes: - .:/myprojectとすることで、ローカルのディレクトリをマウントしている。
- dbコンテナ上でvolumes: -mysql-data:/var/lib/mysqlとすることでデータベースで変更されたデータを永続化。この記述がないと、コンテナを壊した時に変更したデータが消えてしまいます。
- bundle installとbinding.pryのための記述は本記事、最後のおまけを参照
4. database.ymlの変更
これまでの作業でappコンテナとdbコンテナを連携させる設定をしました。
最後にappコンテナからdbコンテナに接続するために、接続設定をします。
database.ymlの中身はおそらく初期設定のままだとこんな感じの記述になってるかと思います。config/database.yml変更前default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: socket: /tmp/mysql.sockこのままだとsocket通信でDB接続をするので、せっかく作成したdbコンテナが意味なくなってしまいます。
作成したdbコンテナに接続するために以下のように変更します。config/database.yml変更後default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password:password host: db #変更(docker-compose.ymlのservice名を記載)usernameやpasswordは環境変数で設定している記事もいくつか見ますが、開発環境なら気にしなくてもいいかなと思いました。
本番環境ではちゃんと環境変数を設定します。以上で準備ができました。
あとはターミナルで該当アプリのディレクトリまで移動して、docker-compose upと入力するだけです
(Gemfile.lockの中身を削除して空にしないとエラーになるかもしれません)
localhost:3000で接続確認して終了です!今回はMySQLを使いましたが、他のDBでも可能なはずです(未検証)
*ポート番号は変わるはずなのでご注意ください番外編:DBをsequel proで可視化したい
今まで開発していた時、DBをsequel proで可視化していて便利だったのですが、docker上のDBも可視化したい!
という方に向けて以下に方法を記載しますdocker-compose.ymlで以下のように記載していました
Ruby:docker-compose.yml
db:
ports:
- "4306:3306"
これはホストが4306で接続した時にコンテナ上では3306に置き換えますという意味です。
準備はこれでokなのでsequel proで接続します。
sequel proを開いて、標準タブに切り替えます。
そこで以下の内容を入力します名前: 任意、変えなくてもok ホスト: 127.0.0.1 ユーザー名: root (database.ymlに記載のユーザー名) パスワード: password (database.ymlにパスワード) データベース: 空でok ポート: 4306(docker-compose.ymlのportsに記載した左側)ホストの127.0.0.1は自分自身を表すIPアドレス
これで見れるようになるはず!
その他開発する上で必要なコマンド
docker上でrails g controllerやrails db:migrateなどを行う時は以下のようにコンテナを通して入力します
appの部分はdocker-compose.ymlで作成したコンテナ名のappのことですdocker-compose run --rm app 入力したいコマンド(例: rails db:migrate)その他必要なコマンドは以下の記事参照
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1
全てのコンテナやイメージを削除する場合はこちら#全てのコンテナ停止 docker stop $(docker ps -q) #全てのコンテナ削除 docker rm $(docker ps -q -a) #全てのイメージ削除 docker rmi $(docker images -q)おまけ
bundle installしたい時
開発していく中で、gemを追加してbundle installしたい場面が出てくると思います
そのままやってもできるんですが、追加したgem内容がコンテナ内に反映されないため、イメージをbuildし直さなくてはなりません。
いくつか解決方法はあるみたいですが、今回はvolumeでマウントするという方法で解決しました。docker-compose.ymlapp: volumes: - bundle:/usr/local/bundle #中略 volumes: bundle:参考記事
https://qiita.com/neko-neko/items/abe912eba9c113fd527ebindin.pryしたい時
binding.pryをするためには以下の記述を追加します
docker-compose.ymlapp: tty: true stdin_open: trueおわりに
dockerについて全くわからないところから環境構築するのはかなり大変でした
自分なりにまとめられて良かった
同じような状況の人の参考になれば幸いです間違ってる場所があれば指摘していただけると幸いです
本番環境でDockerを使うのも苦労したので、そのうち開発環境との違いなどもまとめようかなと思います
参考記事
Dockerについての概要と色々なTIPSを知りたい場合は下記リンクがおすすめ
https://qiita.com/gold-kou/items/44860fbda1a34a001fc1実際の作業で参考にした記事
https://qiita.com/azul915/items/5b7063cbc80192343fc0
https://qiita.com/Nishi53454367/items/aee4cf0c346bc115be99
- 投稿日:2020-01-10T13:03:46+09:00
Rails Datetime型のカラムの値を日付(mm/dd/yyyy)単位で集計する方法
はじめに
gem chatkickを使用して、値を日付(mm/dd/yyyy)ごとにカウントしようとした際に、ハマってしまったのでその備忘録になります。
概要
やりたかったことは簡単グラフ表示 gem 'charkick'を使用して、テーブルの値を日付単位でカウントして表示したかった。
ちなみに、charkick の一次情報はこちら。
また、charkickを使っての日付単位での集計にはgem 'groupdate'を使うことがベストプラクティスらしい導入
以下の記事を参考にcharkickを導入しました
ー Railsメモ(29) : Chartkickで簡単にグラフを描画するここから本題
ぶつかった問題
エラー発生
ActiveRecord::Base.default_timezone must be :utc to use Groupdate
どうやらtimezoneがUTCでないといけないらしい。アプリのtimezoneをtokyoにしていたが、あくまでtokyoのままカウントしたい。
application.rbclass Application < Rails::Application ## 途中略 config.time_zone = 'Tokyo' end対応策
groupdateのメソッドgroup_by_day を使うとエラーの回避ができず、しょうがなくあきらめることに。
ちなみにエラーが出ていたコードは以下。
- 対応前
user_controller.rbclass UsersController < ApplicationController ## 途中略 def show @data2 = Message.where(user_id: current_user.id).group_by_day(:created_at).count ## 途中略 end end
- 対応後
user_controller.rbclass UsersController < ApplicationController ## 途中略 def show # messageテーブル値の取得 data2 = Message.where(user_id: current_user.id) # 配列の宣言 c = [] # data2の値を日付(mm/dd/yyyy)形式で取得し配列に格納 data2.each do |d| c << d.created_at.strftime('%Y%m%d').to_s end # 配列に含まれている重複している値を数える @data2 = c.each_with_object(Hash.new(0)){|v,o| o[v]+=1} @today = Date.today @lastmonth_today = @today.prev_day(14) end endもっといい書き方ができるかもしれませんが、とりあえずこれで日付単位でのカウントができた。
ちなみに表示側のHTML以下
show.html.haml.rb.learning-curve # 途中略 .learning-curve_graph = line_chart @data2, width: "100%", height: "300px",min: 0, max: 20, xmin: @lastmonth_today, xmax: @today,label: "Value",xtitle: "日付",ytitle: "登録件数"結果
無事に日付単位でのカウントに成功し、グラフの表示ができた。
- 投稿日:2020-01-10T12:28:24+09:00
2回目以降のAWSを無料で利用する方法(請求かからないようにする)
Amazon EC2の無料条件
- 750時間/月 (t2.microインスタンスの使用もこれに含む)まで
- Amazon S3: 5GBの標準ストレージ、20,000件のGETリクエスト、2,000件のPUTリクエスト
- Elastic IPアドレス 実行中のインスタンスに関連づけられたElastic IPアドレスを1つだけ インスタンスに紐付いていないElastic IPアドレスは全て課金対象
- IAM: IAMユーザーの一時的なセキュリティ認証情報を使用して他のAWSサービスにアクセスするときのみ料金が発生
2回目以降で実施する場合
- Elastic IPアドレスを解放する (すでに作成済みで、これ以上必要の無い場合)
- 紐付いているS3バケットを削除する
- インスタンスを削除する
Elastic IPアドレスを解放する
Elastic IPアドレスは、停止しているインスタンスに関連づけられている場合に時間ごとに料金が発生します。そのため、インスタンスを停止するときにElastic IPアドレスを解放する必要があります。
手順
(https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。
Elastic IP アドレスを選択✅し、[アクション]>[Elastic IPアドレスの解放]>[解放] の順に選択します。
参考URL: Elastic IPアドレスを解放する方法
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html#using-instance-addressing-eips-releasingS3バケットを削除しよう
不要なバケットである場合、以下の手順で削除することができます。(ただし、同じバケット名を別のサービス等で使いたい場合は、バケットの中身を空にするようにしてください。)
手順
AWS マネジメントコンソール にサインインし、Amazon S3 コンソール (https://console.aws.amazon.com/s3/) を開きます。
EC2インスタンスの停止させましょう
インスタンスを停止するとEIastic IPアドレスは関連づけられなくなるので、あらかじめEIastic IPアドレスを解放し課金されないように気をつけましょう。
手順
(https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。
停止したいインスタンスを選択✅
[インスタンスの状態] >[停止] を選択します。
[停止] が無効になっている場合は、インスタンスが既に停止しているか、またはルートボリュームがインスタンスストアボリュームです。(インスタンスを停止すると、インスタンスストアボリューム上のデータは消去されます。インスタンスストアボリュームのデータを保持するには、このデータを永続的ストレージに必ずバックアップしてください。)参考URL: インスタンスの停止と起動
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/Stop_Start.html費用はこまめに確認する
発生している料金については、AWSの請求ダッシュボードからいつでも確認することができます。気になる場合は、こまめに確認するようにしましょう。
手順
不明な課金がされている場合
その他にも数十円の料金が発生していたり、不明な料金が発生していることがあったら以下のような対応を取りましょう。
- AWSのカスタマーサポートに問い合わせてみる (https://aws.amazon.com/jp/contact-us/?nc2=h_header)
- 解決しない場合は、AWSのアカウントごと消去する
高度な設定
費用発生を最小限に留めるために、EC2を自動でシャットダウンされるように設定したり、無料利用枠を超えないようにS3でオブジェクトの有効期限を設定できたりします。以下のリンクを参考にしてください。
無駄なコストを省こう!AWSで消し忘れを防止するためにチェックすべき7つのポイント
(https://dev.classmethod.jp/cloud/aws/cost-check-point/)
- 投稿日:2020-01-10T12:28:24+09:00
2回目以降のAWSを無料で利用する方法(請求かからないようにインスタントの削除)
Amazon EC2の無料条件
- 750時間/月 (t2.microインスタンスの使用もこれに含む)まで
- Amazon S3: 5GBの標準ストレージ、20,000件のGETリクエスト、2,000件のPUTリクエスト
- Elastic IPアドレス 実行中のインスタンスに関連づけられたElastic IPアドレスを1つだけ インスタンスに紐付いていないElastic IPアドレスは全て課金対象
- IAM: IAMユーザーの一時的なセキュリティ認証情報を使用して他のAWSサービスにアクセスするときのみ料金が発生
2回目以降で実施する場合
- Elastic IPアドレスを解放する (すでに作成済みで、これ以上必要の無い場合)
- 紐付いているS3バケットを削除する
- インスタンスを削除する
Elastic IPアドレスを解放する
Elastic IPアドレスは、停止しているインスタンスに関連づけられている場合に時間ごとに料金が発生します。そのため、インスタンスを停止するときにElastic IPアドレスを解放する必要があります。
手順
(https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。
Elastic IP アドレスを選択✅し、[アクション]>[Elastic IPアドレスの解放]>[解放] の順に選択します。
参考URL: Elastic IPアドレスを解放する方法
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html#using-instance-addressing-eips-releasingS3バケットを削除しよう
不要なバケットである場合、以下の手順で削除することができます。(ただし、同じバケット名を別のサービス等で使いたい場合は、バケットの中身を空にするようにしてください。)
手順
AWS マネジメントコンソール にサインインし、Amazon S3 コンソール (https://console.aws.amazon.com/s3/) を開きます。
EC2インスタンスの停止させましょう
インスタンスを停止するとEIastic IPアドレスは関連づけられなくなるので、あらかじめEIastic IPアドレスを解放し課金されないように気をつけましょう。
手順
(https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。
停止したいインスタンスを選択✅
[インスタンスの状態] >[停止] を選択します。
[停止] が無効になっている場合は、インスタンスが既に停止しているか、またはルートボリュームがインスタンスストアボリュームです。(インスタンスを停止すると、インスタンスストアボリューム上のデータは消去されます。インスタンスストアボリュームのデータを保持するには、このデータを永続的ストレージに必ずバックアップしてください。)参考URL: インスタンスの停止と起動
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/Stop_Start.html費用はこまめに確認する
発生している料金については、AWSの請求ダッシュボードからいつでも確認することができます。気になる場合は、こまめに確認するようにしましょう。
手順
不明な課金がされている場合
その他にも数十円の料金が発生していたり、不明な料金が発生していることがあったら以下のような対応を取りましょう。
- AWSのカスタマーサポートに問い合わせてみる (https://aws.amazon.com/jp/contact-us/?nc2=h_header)
- 解決しない場合は、AWSのアカウントごと消去する
高度な設定
費用発生を最小限に留めるために、EC2を自動でシャットダウンされるように設定したり、無料利用枠を超えないようにS3でオブジェクトの有効期限を設定できたりします。以下のリンクを参考にしてください。
無駄なコストを省こう!AWSで消し忘れを防止するためにチェックすべき7つのポイント
(https://dev.classmethod.jp/cloud/aws/cost-check-point/)
- 投稿日:2020-01-10T12:14:49+09:00
【翻訳】Bundler 3アップグレードガイド
はじめに
Rubyのパッケージ管理ツールであるBundlerはバージョン 3で後方互換性が失われる様々な変更点が導入される予定になっています。
そして、バージョン 3への移行を容易にするため、バージョン 2.1ではバージョン 3で使えなくなる機能を使うと警告が出ます。これらの内容については公式リポジトリのアップグレードガイドで詳細が説明されています。
https://github.com/rubygems/bundler/blob/master/UPGRADING.md
この記事は上記のアップグレードガイドの日本語訳です。
翻訳したアップグレードガイドの版について
この記事で翻訳したのは2019年10月3日に更新された以下の版です。
(翻訳時点のBundlerの最新バージョンは2.1.4)https://github.com/rubygems/bundler/blob/e8f261882397f7e8a6c74760f8fe1a4955c9e980/UPGRADING.md
今後更新される可能性もあるため、必要に応じて最新の版を参照するようにしてください。
https://github.com/rubygems/bundler/blob/master/UPGRADING.md
おことわり
普段あまり使わない機能については、正しく翻訳できているかどうかあまり自信がありません。
もし明らかにおかしな内容を見つけたら、コメント欄や編集リクエスト等で報告してください?ラインセンスについて
この記事はBundlerと同様にMITライセンスで公開します。
This document is under the MIT License.
それでは以下がアップグレードガイドの翻訳になります。
【翻訳】アップグレードについて
Bundler 3について
以下で説明するのはBundler 3で導入される変更点のまとめです。なぜその変更を入れるのか、そして非推奨化のプロセスがどのようになるのかについても説明しています。非推奨になる変更点はBundler 2.1のリリース時にすべてデフォルトで表示されます。
もし非推奨警告の対応は後回しにして警告を非表示にしたい場合は、設定によってそのように変更できます。その場合は
BUNDLE_SILENCE_DEPRECATIONSという環境変数を"true"に設定するか、bundle configコマンドを使って設定してください。グローバルに設定を変更したい場合はbundle config set silence_deprecations trueコマンドを使い、ローカルの設定だけ変更したい場合はbundle config set --local silence_deprecations trueコマンドを使います。これ以降、本ドキュメントではこの3つの設定方法がすべて有効である前提で執筆していきますが、記述するのはbundle config set <option> <value>の方法だけにします。全般的な話として、これらの変更点は「新規Bundlerユーザー」のユーザー体験を改善するために行われます。ここでいう新規Bundlerユーザーとは、毎回特に決まった使い方をしておらず、これまでの使用体験から「Bundlerにはこう動いてほしい」という明確な意思も持っていないユーザーのことを指します。今回の変更点は長年Bundlerを使ってきたユーザーをイライラさせるものだと思います。その点は私たちも十分理解しています。ですので、私たちはこのプロセスをできる限りスムーズなものにしたつもりです。
非推奨化警告は、「CLIの非推奨警告」と「DSLの非推奨警告」と「その他の非推奨警告」という3つのグループに分けられます。それぞれについて今から見ていきましょう。
CLIの非推奨警告
CLIではBundlerを動かすためのコマンドとオプションの集合を定義しています。このコマンドとオプションの集合に対して、私たちはさまざまな変更を導入する予定です。
- 一度設定するとそれ以後の呼び出しでその設定が記憶される
bundle install用のフラグが非推奨となりました。具体的には、
bundle installに渡す--clean,--deployment,--frozen,--no-cache,--no-prune,--path,--shebang,--system,--without,--withオプションのことになります。記憶されるCLIオプションはこれまで混乱とバグレポートの温床になってきました。これは初心者に限った話ではなく、経験豊富なユーザーにとっても同様です。CLIツールは全く同じ呼び出し方なのに異なる振る舞いをするべきではありません。そうなってもよいのは、そのように明示的に設定されている場合「だけ」です。それが設定の存在理由であり、ユーザーが気づかないところでこっそりと設定が変更されるべきではありません。
この仕様変更によって影響を受けるのは、この機能に依存する「よくあるワークフロー」です。たとえば、本番環境で
bundle install --without development:testというコマンドを実行すると、このフラグがアプリケーションの設定ファイルに保存され、それ以降はbundleコマンドを実行してもdevelopmentとtestのgemをありがたく無視してくれます。Bundler 3以降はこの魔法が使えなくなります。同じ挙動を維持するためには明示的な設定が必要です。設定を入れる方法は、環境変数、アプリケーションの設定、マシン全体の設定のいずれかです。たとえば、bundle config set without development testというコマンドを使います。こうしたフラグの削除は類似のコマンドにも適用されます。たとえば、
bundle check --pathがそうです。
bundle installとbundle updateに渡す--forceフラグは、--redownloadにリネームされます。これは単なるフラグのリネームです。リネームするのは実際の挙動をよりわかりやすくするためです。このフラグは強制的にすべてのgemを再ダウンロード(redownload)するだけで、それ以外の何かを強制(force)するわけではありません。
bundle vizコマンドが削除され、プラグインとして切り出されます。これはBundlerで唯一外部依存が発生するコマンドです。依存先はOS(
graphvizパッケージ)とgem(ruby-graphvizgem)です。この依存性を排除することで開発がより容易になります。また、この機能はBundlerチームによって公式に保守されるBundlerプラグインになります。ユーザーもこのプラグインを参照すれば、独自のプラグインを作るのに役立ちます。このプラグインは従来のコアコマンドと同じコードになっていますが、唯一異なる点としてコマンド名がbundle graphに変わっています(でも、この方がずっとわかりやすいはずです)。この新しいプラグインのインストール方法や使い方についてはプラグインのリポジトリを参照してください。
bundle consoleコマンドが削除され、bin/consoleに置きかわります。時間の経過とともに
bundle consoleコマンドは保守するのが難しくなってきました。これは各ユーザーが自分独自の変更点を追加しようとしてくるためです。保守を容易にし、細々した議論を減らすため、bundle consoleコマンドをbin/consoleスクリプトに置き換えます。このスクリプトはgem開発時にbundle gemコマンドで作成され、ユーザーは自分が好きなようにこのコマンドを修正することができます。
bundle updateコマンドを実行しても、すべてのgemがアップデートされなくなります(--allオプションが必要になります)。Bundlerチームはこのコマンドを使ってすべてのgemを一気にアップデートするのは、このコマンドの主要なユースケースになるべきではないと判断しました。それよりも1回につき1つのgemをアップグレードする(または関連するgemのグループをアップグレードする)方がよいと考えます。すべてのgemを一気にアップグレードすることもできますが、その場合は
--allフラグが必要になります。
bundle installコマンドに--binstubsフラグを渡せなくなります。
--binstubsオプションはbundle installコマンドから削除され、bundle binstubsコマンドに置きかえられました。--binstubsオプションはプロジェクト内のgemに存在するすべての実行可能ファイル(executables)に対してbinスタブを作成します。しかし、これはほとんど役に立ちませんでした。なぜなら大半のユーザーが使うのはbinスタブの一部だけだからです。加えて、これを使うと、使われることのない大量のファイルがソース管理システムに追加されます。こうした理由により、binスタブは個別に作成され、個別にバージョン管理されるようになります。
bundle configコマンドに新しいサブコマンドが追加されました。従来のインターフェースは混乱の原因になっていたと思います。なぜなら様々なフラグと引数の組み合わせによって実行されるオペレーションを推測しなければならなかったからです。これに代わり、私たちは
list,get,set,unsetというサブコマンドを導入しました。このサブコマンドの導入により、configコマンドが以前よりもきっと扱いやすくなったはずです。従来のインターフェースは非推奨になりましたが、警告メッセージと一緒に新しいコマンドの提案を行います。
bundle injectコマンドが非推奨になり、bundle addコマンドに置きかえられました。新しいコマンド名の方がきっとユーザーのメンタルモデルにフィットし、より広いユースケースをサポートすると思います。
bundle injectコマンドでサポートされていたインターフェースはbundle addコマンドでもまったく同じように動作します。ですので、新しいコマンドに移行するのは簡単なはずです。ヘルパーの非推奨警告
- 右のメソッドは非推奨になりました。
Bundler.clean_env,Bundler.with_clean_env,Bundler.clean_system,Bundler.clean_execこれらのヘルパーメソッドはすべて、背後で
Bundler.clean_envメソッドを使っています。これにより実行されるブロック内ではBundlerに関連する環境は削除されます。ユーザーからたくさんのレポートを受け取った結果、ユーザーは通常この挙動を望まず、代わりにカレントプロセスが開始する前と同じBundler環境を使いたがっていることに私たちは気づきました。こうして生まれたのが、
Bundler.with_original_env,Bundler.original_system,Bundler.original_execという3つのメソッドです。これらのメソッドはすべて新しいBundler.original_envメソッドを背後で使います。とはいえ、特定の状況下では従来の
Bundler.clean_envの挙動が望ましいこともあるでしょう。たとえば、Railsジェネレータのテストをする場合は、bundlerのいない環境が欲しくなると思います。このため、私たちは従来の挙動を新しく、よりわかりやすい名前で維持できるようにしました。"clean"という単語はあまりにもあいまいだからです。というわけで、私たちはBundler.unbundled_env,Bundler.with_unbundled_env,Bundler.unbundled_system,Bundler.unbundled_execという4つのメソッドを新たに追加しています。
Bundler.environmentが非推奨になり、Bundler.loadに置き換えられました。どれくらいの人がこれを直接使っているのかはわかりませんが、私たちは
Bundler::Environmentクラスを削除しました。このクラスはBundler.environmentによってインスタンス化されるクラスです。削除した理由はBundler::Runtimeが同じ役割のクラスだと気づいたからです。移行期間中、Bundler.environmentはBundler.loadに委譲されます。このメソッドはBundler::Environmentへの参照を保持しています。DSLの非推奨警告
Bundler DSLで発生する下記の非推奨警告は、Bundler 3で予定されている厳格なソース固定(strict source pinning)への準備を意味します。Bundler 3ではすべての依存ライブラリのsourceは厳格に定義されます。
- 複数定義されたグローバルなGemfileのsourceはサポートされなくなります。
こんなふうに書く代わりに・・・
source "https://main_source" source "https://another_source" gem "dependency1" gem "dependency2"このように書いてください。
source "https://main_source" gem "dependency1" source "https://another_source" do gem "dependency2" end
- グローバルな
pathとgitのソース(source)はサポートされなくなります。こんなふうに書く代わりに・・・
path "/my/path/with/gems" git "https://my_git_repo_with_gems" gem "dependency1" gem "dependency2"このように書いてください。
gem "dependency1", path: "/my/path/with/gems" gem "dependency2", git: "https://my_git_repo_with_gems"もしくは各ソースに対して複数のgemがあり、もっとDRYに書きたい場合はブロック記法を使ってください。
path "/my/path/with/gems" do # gem "dependency1" # ... # gem "dependencyn" end git "https://my_git_repo_with_gems" do # gem "dependency1" # ... # gem "dependencyn" endその他の非推奨警告
vladとcapistrano用のデプロイヘルパー(Deployment helper)は削除されました。
vladツールは何年も活動が止まっているので自然に非推奨となりました。一方でcapistrano3はcapistrano-bundlergemによってBundlerに統合されています。Capistrano 3のユーザーはきっとこれを使っているはずです。なんらかの理由でCapistrano 2を使い続けている場合は、遠慮無くBundler 2のbundler/deployment.rbファイルからCapistrano用のタスクをコピーして、ご自身のアプリケーションに追加してください。基本的に私たちはあらゆるデプロイメントシステムの統合機能を保守したくありません。この機能を削除したのはこうした理由からです。
(翻訳は以上)
- 投稿日:2020-01-10T11:36:03+09:00
【Rails】config/localesに新規追加したファイルが読み込まれない【I18n】
はじめに
タイトルの通りです。
Railsで多言語化対応をする際にconfig/localesにymlファイルを追加していくと思いますが、それが読み込まれない場合の対応策です。結論
早速結論なのですが、超シンプルで、
Railsサーバを再起動するです。。。
既存ファイルに訳文を追加する場合はRailsサーバの再起動は不要ですが、新規ファイルを追加した場合はRailsサーバの再起動が必要です。ちなみに少しこの記事の内容と外れるかもしれませんが、RailsガイドにRailsの初期化プロセスについて記載があったので参考としてリンクを貼っておきます。
Railsの初期化プロセスおわりに
単純なミスで恥ずかしいのですが、めっちゃハマって辛かったので記事にしてみました。(typoやインデント、ディレクトリ構成等見直しまくりました。。。)
案外検索しても出てこず、他ごとしてたら急に「これ、サーバ再起動案件じゃね。。。?」と気が付いた次第です。はい。
- 投稿日:2020-01-10T09:19:28+09:00
I understand #Ruby Lonely operator &. is a operator allows nil receiver method chains
If receiver is nil you can do method chains many times
nil&.to_wow # => nil nil&.to_wow&.to_ya # => nil nil&.to_wow&.to_ya&.to_yes! # => nilIf not nil is reciever then you can not chain undefined method by lonely operator
100&.to_wow NoMethodError: undefined method `to_wow' for 100:IntegerOriginal by Github issue
- 投稿日:2020-01-10T01:57:51+09:00
index.html+mobile.haml なviewをrspecする
before_action do request.variant = :mobile if ua.match(/Android/) endとかするとviewを切り替えられる
ActionPack Variantsという機能1で
view specを書く方法# spec/views/users/index.html+mobile.haml_spec.rb RSpec.describe 'users/index.html+mobile.haml', type: :view do it do render end endとやると 「
html+mobile何ていうフォーマットねーよ」 と怒られる
なのでrenderの呼び出しで正しい情報を与える# spec/views/users/index.html+mobile.haml_spec.rb RSpec.describe 'users/index.html+mobile.haml', type: :view do it do render template: 'users/index.html.haml', variants: 'mobile' end endこれで正しくmobileのテンプレートをレンダーできる
(確認は適当に= 1 / 0とか追記すれば死んでくれる)しかし当然めんどくさい
renderの中身を見ると_default_render_optionsというのをdescribeの文字列から作っているようだ
なのでこいつをいじってしまう# spec/support/variants_support.rb module VariantsSupport def _default_render_options render_options = super if render_options[:formats].first formats, variants = render_options[:formats].first.to_s.split('+') render_options[:formats] = [formats.to_sym] if formats render_options[:variants] = [variants.to_sym] if variants end render_options end end RSpec::Rails::ViewExampleGroup::ExampleMethods.prepend(VariantsSupport)これで
renderするだけでよくなったなおこの現象は
rspec 3.9までの挙動で現在ベータの4.0では修正されている
本家の修正も_default_render_optionsなので大正解っぽい
早くリリースしてくれ
名前初めて知った ↩
- 投稿日:2020-01-10T00:17:21+09:00
テーブルの結合ができない。。Mysql2::Error: Column 'updated_at' in order clause is ambiguous
はじめに
Railsでeager_loadしようとしたときに、下記のようなエラーが出て解消に時間がかかったのでまとめました。
Mysql2::Error: Column 'updated_at' in order clause is ambiguousやりたいこと
user の updated_at を指定した期間のものだけ抽出するために、テーブルの結合をしたい。
なぜeager_loadできないのか
これを実行すると、
user.rbUser.where("updated_at >= '2020/01/01' and updated_at <= '2020/01/31'").eager_load(:post)MySQLのエラーが出る。
Mysql2::Error: Column 'updated_at' in order clause is ambiguousなぜか。
updated_at は User にも Post にも存在しているため、どちらの updated_at なのか判別がつかない。
そこで、incidents.updated_at とすることで、User の updated_at なのか Post の updated_at なのかを明確化する。
下のように書き換えることで、エラーを解消することができました。
user.rb# incidents.updated_at とすることで、user User.where("incidents.updated_at >= '2020/01/01' and incidents.updated_at <= '2020/01/31'").eager_load(:post)まとめ
updated_at は、どのテーブルでも持っている値となるので、こういう値でjoinするときは気をつけるようにします。
裏話としては、railsでデバックをしていていたのですが、eager_loadを実行したらSQL文しか表示されずエラーが表示されていませんでした。
.to_sで文字列化することで、上記のMysql2::Errorが出てなんとかデバックすることができました。
エラーが隠れてる??自分の確認方法が悪かっただけかもしれませんが、、
時間はかかりましたが、解決できてよかったです。参考
- includes,joins,eager_load,preloadの違いを噛み砕いて説明する
- Mysql2::Error: Column 'created_at' in order clause is ambiguousの対策




















































