Dockerコンテナ使用時に何故サーバーを立てる際にIPアドレス0.0.0.0を指定するのか

概要

Dockerを利用する際に何故rails sでバインドするIPアドレス0.0.0.0で指定するのか気になった為、備忘録として残す。

何故バインドするIPアドレスlocalhost(127.0.0.1)ではなく、0.0.0.0を指定するのか

ローカルマシンで127.0.0.1にアクセスしようとしてもローカルにlistenするのではなく、Dockerコンテナにlistenしており、アクセスができない為、localhost(127.0.0.1)は指定しません。

そこで何故0.0.0.0を指定するのかと言うと、Dockerで0.0.0.0ワイルドカードIPアドレスとして公開しているからです。

このワイルドカードIPアドレスによって、ホストマシン(自分のMacなど)で到達可能な全てのIPアドレスが対象になっている為、ローカルマシンで127.0.0.10.0.0.0にアクセスしようとしても問題なくlistenしてくれます。

最後に

この知識が皆さんの参考になれば嬉しいです。何か気になる箇所や間違ってる箇所があればコメントして頂けると嬉しいです。ここまで読んで下さりありがとうございました〜

参考資料

ホスト上にコンテナのポートを割り当て [Docker]0.0.0.0でサーバーを立てる理由(Python)

Javascriptでのreplaceメソッドの第二引数の関数が理解できた件について

なぜ記事を書こうと思ったか

開発の際にJavascriptのreplaceメソッドで第一引数に正規表現、第二引数にインライン関数を使用する際のインライン関数の引数に何の情報が入っているか分からず開発が進まない事があった為、今回replace関数の引数に入る情報をまとめたいと思います。

replaceメソッドはどのような処理?

replaceメソッドは簡単に言うと、パターンに一致した部分文字列の一部またはすべてを置換文字列で置き換えた新しい文字列を返します。

簡単な例だと以下のような形です。

const greeting = "初めまして、私は田中太郎です。このクラスの田中健太君と友達です。よろしくお願いします。";

// 第一引数が文字列の場合
console.log(greeting.replace("田中", "佐藤"));
// コンソール結果("初めまして、私は佐藤太郎です。このクラスの田中健太君と友達です。よろしくお願いします。")

// 第一引数が正規表現の場合
console.log(greeting.replace(/田中/i, "佐藤"));
// コンソール結果("初めまして、私は佐藤太郎です。このクラスの田中健太君と友達です。よろしくお願いします。")

上記のreplaceメソッドは簡単に理解できると思います。自分にとってはこの後の内容が理解に苦しみました。(こんな事すぐ分かって当然だろ!って思う方もいると思いますが、そっと目を瞑って温かい目でご覧になって下さい)

replaceメソッドの第二引数に関数を指定した場合について

以下にreplaceメソッドの第二引数に関数を指定した場合の例を記載致します。

function replacer(match, regexpMatch1, regexpMatch2, offset, string) {
  return "{小池徹平}";
}
const introduction = "初めまして、私は田中太郎です。このクラスの{佐藤健}と友達です。よろしくお願いします。";
const newIntroduction = introduction.replace(/({佐藤([^}}]*)})/g, replacer);
console.log(newIntroduction);
// コンソール結果("初めまして、私は田中太郎です。このクラスの{小池徹平}と友達です。よろしくお願いします。")

このreplaceメソッドの第二引数のreplacerの引数に何が入っているのか分かりませんでした。

簡単に以下にreplacer関数の引数にどのような情報が入っているかまとめます。

  • 第一引数(match)

replaceメソッドの第一引数の正規表現に該当する文字列を格納しています。今回の場合は"{佐藤健}"が該当します。

  • 第二・第三引数(regexpMatch1・regexpMatch2)

replaceメソッドの第一引数の正規表現の()に囲まれた部分(サブパターン)を格納します。regexpMatch1には正規表現の"({佐藤([^}}]*)})"に該当する"{佐藤健}"が格納され、regexpMatch2には正規表現の"([^}}]*)"に該当する"健"が格納されています。

この第二・第三引数については、正規表現のサブパターンを指定しない場合は存在せず、今回よりも多くのサブパターンを指定する場合は第四引数、第五引数・・・と増えていきます。

  • 第四引数(offset)

変数introductionの文字列で何文字目の後に正規表現が合致するかを格納します。今回の場合は21が該当します。

  • 第五引数(string)

replaceメソッドをしている変数の値を格納します。今回の場合は"初めまして、私は田中太郎です。このクラスの{佐藤健}と友達です。よろしくお願いします。"が該当します。

 

上記に書いた事で引数にはどのような情報が格納されているか理解できると思います。

最後に

正直他の方の記事のreplaceメソッドの第二引数に関数を指定した場合の説明は、自分には全く分からなかったです笑(自分が頭悪いだけです、、すみません、、)

今回の記事は丁寧に書いているので、恐らく初心者の方でも理解できる内容になっていると思います。最後まで読んでいただきありがとうございました〜

参考資料

MDN/String.prototype.replace()

ストロングパラメーターの基本的な書き方と対応できないオブジェクト例

なぜ記事を書こうと思ったか

Railsアプリ開発している際に、ストロングパラメーターで対応できないオブジェクトがあることを知った為、今回ストロングパラメータの基本的な書き方と一緒にこの記事にまとめようと思います。

ストロングパラメーターの書き方

基本的なオブジェクト

{
  name: "田中",
  age: 23
}
params.permit(:name, :age)

配列が入っている場合

{
  name: "田中",
  hobbies: [
    "サッカー", "映画鑑賞"
  ],
  age: 23,
  favorite_food: [
    "ラーメン", "寿司"
  ]
}
値に配列が入っているプロパティはストロングパラメーターで最後に記述する
params.permit(:name, :age, hobbies: [], favorite_food: [])

オブジェクトがネストした場合

{
  name: "田中",
  setting: {
    age: 23,
    department: "営業部"
  }
}
ネストしたプロパティもストロングパラメーターで最後に記述する
params.permit(:name, setting: [:age, department])

ストロングパラメーターで対応できないオブジェクトについて

ストロングパラメーターで全てのオブジェクトを対応している訳ではなく、直接、値を取得しないといけない場合もある。

二次元配列が入っている場合

{
  person: [
    "田中", "佐藤"
  ],
  setting: [
    [
      23, "営業部"
    ],
    [
      28, "開発部"
    ]
  ]
}
settingsをストロングパラメーターで取得しようとすると、エラーになる。
params.permit(person: [], setting: [[]])
settingsは直接取得する必要がある。
params.permit(person: [])
params[:setting]

最後に

正直、二次元配列のようにストロングパラメータで書く事ができないオブジェクトがあることは知りませんでした笑(開発中にたまたま見つけました)

もし他にストロングパラメーターで書くことができないオブジェクトや他のストロングパラメーターの書き方がある場合は、コメントで教えていただけると嬉しいです。読んで頂きありがとうございました。

参考資料

Rails及びDocker環境でのpry-railsのデバッグ方法

なぜ記事を書こうと思ったか

Rails及びDocker環境でpry-railsでのデバッグをおこなったので、そのやり方を記載致します。

これまで、行っていたデバッグよりもより細かくコードを確認できるので、すごく便利に感じたので、多くの新人の方が使ってくれると嬉しいです。

Rails及びDocker環境でpry-railsでのデバッグ手順

※Dockerは構築して、起動してある事を前提として記載致します。

デバッグ手順

1.Railsのコードで動作を止めて、確認したいコードの直後にbinding.pryを追加します。

今回は例として、createメソッドのコードに付け足したいと思います。

def create
  permit_parameters = params.permit(:name, :age, :sex).to_h
  binding.pry

  user = User.create!(
           name: permit_parameters[:name].to_i,
           age: permit_parameters[:age],
           sex: permit_parameters[:sex]
         )

  return_json = { "#{ user.name }さんの登録を受け付けました。" }
  render json: return_json
end

上記のようにするだけで、permit_parameters変数の行までしか実行されないようになります。

2.docker ps -aでDockerで起動しているコンテナの一覧を表示し、Railsサーバーを立ち上げているコンテナのIDを確認します。

3.docker attach コンテナIDを入力し、Railsサーバーを立ち上げているコンテナに入ります。

4.今回の場合はcreateメソッドにデータをPOSTします。

ログと共に、以下のようなログも表示されます。

  1:      def create
  2:        permit_parameters = params.permit(:name, :age, :sex).to_h
  3:        binding.pry
  4:
=>5:        user = User.create!(
  6:                 name: permit_parameters[:name],
  7:                 age: permit_parameters[:age],
  8:                 sex: permit_parameters[:sex]
  9:               )
  10:
  11:       return_json = { "#{ user.name }さんの登録を受け付けました。" }
  12:       render json: return_json
  13:     end

上記のログでは、=>が書いてある行以前まで、コードが動いている事を表します。

また、[1] pry(#)>railsコンソールの時と同様の操作ができます。

[1] pry(#)> params[:name]
=> "田中太郎"

5.次の行のコードまで動作させたい場合は、nextと入力する。

[2] pry(#)> next

  1:      def create
  2:        permit_parameters = params.permit(:name, :age, :sex).to_h
  3:        binding.pry
  4:
  5:        user = User.create!(
  6:                 name: permit_parameters[:name],
  7:                 age: permit_parameters[:age],
  8:                 sex: permit_parameters[:sex]
  9:               )
  10:
=>11:       return_json = { "#{ user.name }さんの登録を受け付けました。" }
  12:       render json: return_json
  13:     end

[3] pry(#)>

先ほどまでは4行まで動作していましたが、今回は10行まで動作した状態になります。

このような作業をするだけで各コードが適切に動作しているか確認することができます。

デバッグ終了方法

1.continueを入力して、止まっていたコードを全て動作させる。

[3] pry(#)> continue

~~~ログが流れる~~~

2.controlボタンを押しながら、pの後にqを押す。

こうすることで、コンテナから出ることができます。もし、exitcontorol + cをした場合は、サーバーも停止されます。

3.binding.pry`を削除します。

最後に

自分は、logger.debugやログで動作状況を確認していたので、このデバッグ方法は非常に便利に感じました。是非、やった事がない方はやってみる事をお勧めします。もし、もっと良いデバッグ方法がある場合は、コメントで教えていただけると嬉しいです。読んで頂きありがとうございました。

Rails及びDocker環境でのpry-railsのデバッグ方法

なぜ記事を書こうと思ったか

Rails及びDocker環境でpry-railsでのデバッグをおこなったので、そのやり方を記載致します。

これまで、行っていたデバッグよりもより細かくコードを確認できるので、すごく便利に感じたので、多くの新人の方が使ってくれると嬉しいです。

Rails及びDocker環境でpry-railsでのデバッグ手順

※Dockerは構築して、起動してある事を前提として記載致します。

デバッグ手順

1.Railsのコードで動作を止めて、確認したいコードの直後にbinding.pryを追加します。

今回は例として、createメソッドのコードに付け足したいと思います。

def create
  permit_parameters = params.permit(:name, :age, :sex).to_h
  binding.pry

  user = User.create!(
           name: permit_parameters[:name].to_i,
           age: permit_parameters[:age],
           sex: permit_parameters[:sex]
         )

  return_json = { "#{ user.name }さんの登録を受け付けました。" }
  render json: return_json
end

上記のようにするだけで、permit_parameters変数の行までしか実行されないようになります。

2.docker ps -aでDockerで起動しているコンテナの一覧を表示し、Railsサーバーを立ち上げているコンテナのIDを確認します。

3.docker attach コンテナIDを入力し、Railsサーバーを立ち上げているコンテナに入ります。

4.今回の場合はcreateメソッドにデータをPOSTします。

ログと共に、以下のようなログも表示されます。

  1:      def create
  2:        permit_parameters = params.permit(:name, :age, :sex).to_h
  3:        binding.pry
  4:
=>5:        user = User.create!(
  6:                 name: permit_parameters[:name],
  7:                 age: permit_parameters[:age],
  8:                 sex: permit_parameters[:sex]
  9:               )
  10:
  11:       return_json = { "#{ user.name }さんの登録を受け付けました。" }
  12:       render json: return_json
  13:     end

上記のログでは、=>が書いてある行以前まで、コードが動いている事を表します。

また、[1] pry(#)>railsコンソールの時と同様の操作ができます。

[1] pry(#)> params[:name]
=> "田中太郎"

5.次の行のコードまで動作させたい場合は、nextと入力する。

[2] pry(#)> next

  1:      def create
  2:        permit_parameters = params.permit(:name, :age, :sex).to_h
  3:        binding.pry
  4:
  5:        user = User.create!(
  6:                 name: permit_parameters[:name],
  7:                 age: permit_parameters[:age],
  8:                 sex: permit_parameters[:sex]
  9:               )
  10:
=>11:       return_json = { "#{ user.name }さんの登録を受け付けました。" }
  12:       render json: return_json
  13:     end

[3] pry(#)>

先ほどまでは4行まで動作していましたが、今回は10行まで動作した状態になります。

このような作業をするだけで各コードが適切に動作しているか確認することができます。

デバッグ終了方法

1.continueを入力して、止まっていたコードを全て動作させる。

[3] pry(#)> continue

~~~ログが流れる~~~

2.controlボタンを押しながら、pの後にqを押す。

こうすることで、コンテナから出ることができます。もし、exitcontorol + cをした場合は、サーバーも停止されます。

3.binding.pry`を削除します。

最後に

自分は、logger.debugやログで動作状況を確認していたので、このデバッグ方法は非常に便利に感じました。是非、やった事がない方はやってみる事をお勧めします。もし、もっと良いデバッグ方法がある場合は、コメントで教えていただけると嬉しいです。読んで頂きありがとうございました。

webサーバーとアプリケーションサーバーの違いについて

なぜ記事を書こうと思ったか

アプリケーションサーバーとWebサーバーについての明確な違いと例えば、どのような種類があるか調べた為、備忘録としてまとめる。

webサーバーとアプリケションサーバーの説明

ユーザーから送られてきた自サイトへのリクエストを受け取り、なんらかの処理を加えるプログラムです。そして、場合によってはあなたのRailsアプリケーションにリクエストを投げます。SSLリクエストや静的なファイルやアセット、圧縮されたリクエスト等を処理したり、その他大半のwebサイトが必要としそうな数多くの処理をこなしたりすることができます。もし、Railsアプリケーションがリクエストを処理しなければならない場合は、webサーバーはリクエストをアプリケーションサーバーにパスします。

複数のアプリケーションを一度に処理したり、アセットを素早くレンダリングしたり、リクエストごとに発生する多くの処理をさばいたりしてくれます。

Railsアプリケーションを動かしているもの。コードを読み込み、アプリケーションをメモリに保持します。webサーバーからリクエストを受け取ると、Railsアプリケーションにそのことを知らせます。アプリケーションがリクエストを処理すると、アプリケーションサーバーはそのレスポンスをwebサーバーに返します。webサーバーを使わずに単体で実行できます。

 

まとめると、ユーザーからのリクエストをwebサーバーが処理し、Railsにアクセスする必要がある場合は、アプリケーションサーバーにリクエストを送る。その後、アプリケションからレスポンスされた情報をアプリケションサーバーがwebサーバーに送り、ユーザーに届けます。

しかし、必ずしもアプリケーションサーバーが必須なわけではなく、Pumaなどは、webサーバーでありながら、アプリケーションサーバーの仕事もこなすことができる為、Puma一つだけでもアプリケーションを動作させる事は可能である。

最後に

正直、インフラ関連の内容について理解が薄い為、今後も触れて行き深く理解して行きたいと思います。

間違っている箇所やわからない箇所があれば、ぜひコメントしていただけると嬉しいです。

読んで頂きありがとうございました。

参考資料

Railsのproduction.rbはどういう事が設定できるの?全ての設定を調べてみた!

なぜ記事を書こうと思ったか

Railsのproduction.rbでどのような設定をしているか及びどのような設定ができるかを確認する為に調べたので備忘録として残します。

default.confのコマンド説明

  • config.cache_classes = true

ソースコードをリロードしない。キャッシュが適用される。

  • config.eager_load

Railsのapp以下にあるクラス(ModelやController)を起動時に全て読み込むかどうか設定

  • config.consider_all_requests_local

すべてのエラーをブラウザに表示をするかの設定

例:Routing Errorなど詳細なエラー情報が表示される。

  • config.action_controller.perform_caching

アプリケーションのキャッシュの有無

  • config.require_master_key = true

ENV["RAILS_MASTER_KEY"]環境変数またはconfig/master.keyファイルでマスターキーを取得できない場合はアプリを起動しないようにする。

  • config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

public/ディレクトリ内の静的アセットを配信するかどうかを指定するかの設定。

production環境ではアプリケーションを実行するNginxやApacheなどのサーバーが静的アセットを扱う必要があるので、falseに設定されます。

  • config.asset_host

アセットを置くホストを設定

アセットとは、Webアプリケーションの直接のレスポンス以外の構成要素のことを指します。JavascriptCSS、画像などがこれにあたります。

  • config.action_dispatch.x_sendfile_header = 'X-Sendfile'

バックエンドで認証やログ記録などを処理し、Apacheにリダイレクトされた場所からエンドユーザーへのコンテンツの提供を処理させることができるため、バックエンドを解放して他のリクエストを処理できる。

  • config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'

バックエンドで認証やログ記録などを処理し、NGINXにリダイレクトされた場所からエンドユーザーへのコンテンツの提供を処理させることができるため、バックエンドを解放して他のリクエストを処理できる。

  • config.active_storage.service = :local

config/storage.ymlで名前を宣言し、このオプションでファイルを保存する場所を指定

  • config.action_cable.mount_path = nil

Action Cableをメインサーバープロセスの一部としてマウントする場所を文字列で指定します。デフォルト値は/cableです。nilを設定すると、Action Cableは通常のRailsサーバーの一部としてマウントされなくなります。

ActionCableとは、Railsのアプリケーションと同様の記述で、WebSocket通信という双方向の通信によるリアルタイム更新機能を実装できるフレームワークで、Rails5から実装されました。利用することで、たとえばリアルタイムで更新されるチャット機能を実装することができます。

Cableサーバを決めたら、ServerのURLをclientサイドに提供する必要がある。Action CableサーバーがホストされているURLを文字列で指定します。Action Cableサーバーがメインのアプリケーションと別になっている場合に使う可能性があります。View側に action_cable_meta_tag を書く。

指定されていない送信元からのリクエストを受け付けません。送信元リストは、配列の形でサーバー設定に渡します。送信元リストには文字列のインスタンス正規表現を利用でき、これに対して一致するかどうかがチェックされます。

  • config.force_ssl = true

すべてのリクエストをHTTPSプロトコル下で実行するよう強制し、URL生成でも"https://"をデフォルトのプロトコルに設定します。

  • config.log_level = :info

Railsのログ出力をどのぐらい詳細にするかを指定します。

ログレベル(順に必要度が低くなる):①unknown ⇨ ②fetal → ③error → ④warn → ⑤info → ⑥debug)

④を指定した場合、④⑤⑥のログが出力される。

  • config.log_tags = [ :request_id ]

ログにタグ付けをする。

今回の場合、ログの前に一意の値が出力される。

  • config.cache_store = :mem_cache_store

Railsでのキャッシュ処理に使われるキャッシュストアを設定します。

キャッシュの種類

①:memory_store → プロセス内のメモリ

②:file_store → ファイルシステム

③:mem_cache_store → Dangaのmemcachedサーバーに一元化

④:null_store → キャッシュをしない

  • config.active_job.queue_adapter = :resque

キューのバックエンドに用いるアダプタを設定

Resqueは、バックグラウンドジョブを作成し、それらのジョブを複数のキューに配置し、後で処理するためのRedisがサポートするライブラリ

  • config.active_job.queue_name_prefix = "app_production"

キューの前にプレフィックスを付ける。

プレフィックスとは、単語の先頭に付加して特定の意味を付け加える要素(接辞)のこと。

  • config.action_mailer.perform_caching = false

メイラーのテンプレートでフラグメントキャッシュを有効にするかどうかを指定します。指定のない場合のデフォルト値はtrueです。

フラグメントキャッシュとは、ページの一部分をキャッシュする機能。キャッシュされたデータはキャッシュストアに保存され、2回目以降はキャッシュストアからデータを取り出される。

  • config.action_mailer.raise_delivery_errors = true

メール配信が完了しなかった場合にエラーを発生させるかどうかを指定

  • config.action_mailer.default_url_options

Action MailerのビューでURLを生成する

  • ActionMailer::Base.smtp_settings

ActionMailer経由の全てのメールがこのSMTP設定を用いて配信される

  • ActionMailer::Base.delivery_method

配信方法の設定

  • config.i18n.fallbacks = true

訳文がない場合のフォールバック動作を設定

フォールバック動作とは、システムに障害が発生したときに性能を落としたり機能を制限したりして限定的ながら稼動を続行すること。あるいは、利用したい機能が条件が悪く使えない場合に、代替となる機能に切り替えること。また、そのような機能や構成。

  • config.active_support.deprecation = :notify

非推奨警告メッセージの振る舞いを設定。どこにメッセージを出力するかを指定。

  • config.active_support.disallowed_deprecation = :log

利用が許されない非推奨警告メッセージの振る舞いを設定します。すべてのログ行の前に次のタグを付けます。

  • config.active_support.disallowed_deprecation_warnings = []

どの非推奨メッセージを禁止するかをアクティブサポートに伝えます。

  • config.log_formatter = ::Logger::Formatter.new

Railsロガーのフォーマットを定義

  • config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')

Rails.loggerで使われるロガーやRails関連のあらゆるロガー(ActiveRecord::Base.loggerなど)を指定します。デフォルトでは、ActiveSupport::LoggerのインスタンスをラップするActiveSupport::TaggedLoggingのインスタンスが指定されます。

標準出力用の Logger オブジェクトを作成する。

  • config.active_record.dump_schema_after_migration = false

マイグレーション実行時にスキーマダンプ(db/schema.rbまたはdb/structure.sql)を行なうかどうかを指定

スキーマダンプとは、スキーマを抽出する。db/schema.rb の作成

最後に

間違っている箇所やわからない箇所があれば、ぜひコメントしていただけると嬉しいです。

読んで頂きありがとうございました。

参考資料