Dockerで構築したRailsサービスのproductionモード起動方法

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

サービス開発中に本番環境のテストをする状況が発生し、Railsのproductionモードを起動する必要があったのですが、少し苦戦してしまった為、備忘録として残します。

関連ファイル

  • config/credentials.yml.enc
  • config/master.key rails newを実行した事がない場合、作成されていません。今回作成する手順も記載します。
  • docker-compose.yml
  • Dockerfile
  • config/database.yml
  • config/environments/production.rb

実行手順

※元々のconfig/credentials.yml.encに対応するmaster.keyを所持している場合、2~5の手順は飛ばして下さい。

1.ターミナルにてdocker-compose up -dでサーバーを起動し、docker-compose exec app bashでコンテナに入る。

2.コンテナにてEDITOR=vi rails credentials:editを実行し、config/master.keyを生成する。

スクリーンショット 2022-05-06 16 46 01

3.config/credentials.yml.encをukabu_01ディレクトリ以外のディレクトリに移動する。

4.コンテナにてEDITOR=vi rails credentials:editを実行し、config/credentials.yml.encを再作成。

(今回作成したmaster.keyでは、元々のconfig/credentials.yml.encを複合することができない為、再生成)

5.再生成されたconfig/credentials.yml.encファイルがvimで開かれている為、secret_key_baseに値が入っている事を確認後、:qvimを閉じる。

6.docker-compose.ymlのRailsサービスのコンテナにrails sコマンドを使用してる箇所がある為、-e productionを追記する。

7.Dockerfileにrails sコマンドを使用してる箇所に"-e", "production"を追記する。

8.config/database.ymlのproductionの記載をdevelopmentと同様の値にする。

※今回の記事では、テストの為の記事なので簡易にproductionモードのdatabaseの設定をしています。

9.ターミナルのコンテナをexitし、docker-compose downでサーバーを終了させる。

10.ターミナルでdocker-compose up -dを行い、docker-compose exec app bashでコンテナに再度入る。

11.config/environments/production.rbにあるconfig.cache_classesの値をfalseに変更する。

スクリーンショット 2022-05-06 17 28 36

上記の手順でproductionモードで操作する事ができるようになります。

動作確認後手順(developmentモードに戻す方法)

1. 今回作成したconfig/credentials.yml.encとconfig/master.keyを削除する。

2. 実行手順の3で別ディレクトリに移動したcredentials.yml.encをukabu_01/configディレクトリ配下に戻す。

3. docker-compose.yml、Dockerfile、config/database.yml、config/environments/production.rbで変更した箇所を元の状態に戻す。

4. .DS_Storeファイルが生成されている場合は、削除する。

最後に

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

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

API通信確認方法はThunderClientが便利

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

サービスの開発中にAPI通信が動作してるか確認する必要があった為、API通信確認方法の備忘録として残す為。

おすすめのAPI通信確認方法

おすすめのAPI通信確認方法としては、コードエディタにVScodeを利用している場合、VSCode拡張機能である「Thunder Client」をおすすめします。

昔は「Postman」というサービスがAPI通信確認方法として利用されており、VScodeを使っていない場合は、利用するのもありだと思いますが、「Thunder Client」はVScodeで完結できる為、非常に便利です。

「Thunder Client」の導入方法と使い方

  • 導入方法(インストールするだけですが笑)

VScode拡張機能を開き、以下のThunder Clientをクリックし、インストールを押して下さい。

スクリーンショット 2022-06-26 18 13 01
  • 使い方

1.拡張機能のマークの下に新しい雷のマークがあるので、クリックして下さい。

スクリーンショット 2022-06-26 18 23 45

2.「New Request」を押して下さい。

スクリーンショット 2022-06-26 18 26 05

3.検索バーの下にあるHeaderタブをクリックして下さい。

スクリーンショット 2022-06-26 18 26 44

4.「Raw」のチェックマークにチェックマークを入れて下さい。

スクリーンショット 2022-06-26 18 31 08

5.HttpHeadersにいらない情報がある為、全て削除して下さい。

6.HttpHeaderにcookieの値やX-CSRFtokenなど必要情報を入力して下さい。

もしわからない場合は、API通信できているか確認したいURLに関連するURLをグーグルで表示し、デベロッパーツールを開いて下さい。

「Network」タブを開き、⌘+Rを押し、RequestHeaderの中身を全てコピーして下さい。

スクリーンショット 2022-06-26 19 00 12

7.コピーした内容をThunderClientのHttpHeaderに貼り付け、検索バーにURLを入力後、Sendをクリックして下さい。

その後、ステータスコードなどが表示されます。

スクリーンショット 2022-06-26 19 03 45

最後に

間違っている箇所があれば、ぜひ教えていただけると嬉しいです。

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

gitのコンフリクト解消方法となぜ起こってしまうのか

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

サービスの開発中にブランチでのコンフリクトが発生した為、修正方法の備忘録として残す為。

そもそもコンフリクトはどの状況で起こる現象?

簡潔に言うと、同じブランチから派生した複数のブランチで同じファイルを編集した際に、コンフリクトが起きる。

hogeファイルを所持しているmainブランチとmainブランチからチェックアウトしたAブランチ、Bブランチがあるとします。Aブランチでhogeファイルを編集し、mainブランチにmergeした際に、Bブランチでもhogeファイルを編集し、mainブランチにmergeしようとした場合に、コンフリクトが生じます。

対処方法(備忘録の為、簡単に書きます笑)

  • 前提条件(コンフリクトを発生させる条件)

1. hogeファイルを所持するmainブランチの作成

hogeファイルの中身

あいさつの種類
①おはようございます。

2. mainブランチから派生したAブランチの作成

hogeファイルの中身

あいさつの種類
①おはようございます。
②こんにちは。

3. mainブランチから派生したBブランチの作成

hogeファイルの中身

あいさつの種類
①おはようございます。
②こんばんは。

4. Aブランチをmainブランチにmergeし、mainブランチでgit pullを行う。

5. Bブランチをmergeしようとしてもコンフリクトを起こしている。(githubのプルリクエストで確認)

スクリーンショット 2022-06-19 18 06 00
  • コンフリクト対処順序

1. ターミナルでBブランチにてgit merge mainを行い、Aブランチの修正内容をBブランチに更新する。

gitのターミナルでは以下の様に表示される。

Auto-merging hogeファイル
CONFLICT (content): Merge conflict in hogeファイル
Automatic merge failed; fix conflicts and then commit the result.

表示された内容は、「更新したけど、hogeファイルでコンフリクトが発生してるから修正してね。」と言う内容です。

2. Bブランチのhogeファイルの内容を確認すると、コンフリクト発生箇所が以下のように表示される。

hogeファイル

あいさつの種類
①おはようございます。
<<<<<<< HEAD
②こんばんは。
=======
②こんにちは。
>>>>>>> main

HEAD側のコードはBブランチの変更内容、main側のコードは取り込まれたmainブランチの内容を表しています。

3. Bブランチのhogeファイルを正しい内容に変更する。

hogeファイル

あいさつの種類
①おはようございます。
②こんにちは。
③こんばんは。

4. ターミナルにてBブランチでgit add [hogeファイルのパス]git commit -m "コメント"を行い、Bブランチにpushする。

`[hogeファイルのパス]`が分からない場合、git merge mainを行った際の表示された内容にhogeファイルのパスがあります。

5. これでコンフリクトは解消されて、Bブランチをmergeできるようになります。

プルリクエストなどを確認した場合、mergeできる様になっている事が確認できます。

スクリーンショット 2022-06-19 18 59 36

コンフリクトを少なくするために

基盤となるブランチ(ほぼmainブランチ)が他のブランチの変更をmergeした後に、新しいブランチを作成する事を心掛けるだけで極力コンフリクトを無くすことは可能だと思います。しかし、派生したブランチの変更をmergeせずに他のブランチを作成しないといけない状況もある為、その際はコンフリクトを解消しましょう。

最後に

もっと良い対処方法や対策方法、間違っている箇所があれば、ぜひ教えていただけると嬉しいです。

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

参考記事

Ruby on Railsの環境を構築する際のNginx設定ファイルのコマンド及びコード理解

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

Nginx 用の設定ファイルを作成する際にコマンド及びコードの理解を備忘録として残すため。

default.confのコマンド説明

default.conf

upstream puma {
    server app:3000;
  }

server {
    listen 80;
    server_name localhost;

    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    root /app/public;

    location @puma {
      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://puma;
    }

    location / {
      try_files $uri @puma;
    }

    location ~ ^/(assets|packs)/ {
      gzip_static on;
      expires max;
      add_header Cache-Control public;
    }

    location = /favicon.ico {
      access_log off;
      log_not_found off;
    }
    
    location = /robots.txt  {
      access_log off;
      log_not_found off;
    }

    error_page 404 /404.html;
    location = /404.html {
    }

    error_page 500 502 503 504 /50x.html;
    location = /500.html {
    }
}

以下にコマンド及びコードの解説を致します。

  • server app:3000

upstreameでpumaグループを定義、個々のサーバーに app:3000を設定

  • listen 80

デフォルトでは、 Nginx HTTP サーバーは受信接続を待機し、標準のWebポートを表すポート 80 にバインドする。

  • server_name localhost

ホスト名を指定

  • access_log /var/log/nginx/access.log` `error_log /var/log/nginx/error.log

access_logとerror_logのパス指定

  • root /app/public

ドキュメントルートを指定

  • location

locationはURI毎に異なる設定をできるようにする

  • proxy_set_header

ロキシーサーバに送られるリクエストヘッダの フィールドを再定義、あるいは追加する。

  • proxy_pass http://puma

リクエストをHTTP プロキシされたサーバに送る

  • try_files $uri @puma

左から順に実体ファイルが存在しているかどうかを探し、あればそのままそのファイルを参照してくれる

  • gzip_static on

圧縮していない物を圧縮し、既に圧縮済みのファイル(e.g. xxx.js.gz)があればそれをそのまま配信する

  • expires max

クライアントキャッシュの有効期限設定

  • add_header Cache-Control public

下位のレベル(location)にadd_headerを設定した場合、上位のレベル(server)のadd_headerは破棄される。

拡張子 gif、jpeg、jpg、pngicosvgcss、jsのファイルをキャッシュする

  • access_log off` `log_not_found off

アクセスログ、エラーログを捨てる

  • error_page 404 /404.html

エラーページを作成する。

最後に

何か間違っている所や気になった事があれば、コメントいただけると嬉しいです。

参考記事

DockerでRuby on Railsの環境を構築する際のmysql.cnfのコマンド及びコード理解

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

mysql 用の設定ファイルを作成する際にコマンド及びコードの理解を備忘録として残すため。

entrypoint.shのコマンド説明

mysql.cnf

[mysqld]
default_authentication_plugin = mysql_native_password
skip-host-cache
skip-name-resolve

character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init-connect = SET NAMES utf8mb4
skip-character-set-client-handshake

[client]
default-character-set = utf8mb4

[mysqldump]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

以下にコマンド及びコードの解説を致します。

  • [mysqld]

MySQL サーバーとも呼ばれ、データベースおよびテーブルを含む MySQL データディレクトリへのアクセスを管理します。

  • default_authentication_plugin = mysql_native_password

Mysqlに接続する際のユーザー認証を行う認証プラグインを設定している。今回の場合は、mysql_native_passwordを認証プラグインとしている。Mysqlではこれまでデフォルトとして、mysql_native_passwordが設定されていたが、Mysql8.04以降からcaching_sha2_passwordがデフォルトとなっている。caching_sha2_passwordでは、暗号化の方法としてSHA-256を採用しており、mysql_native_passwordより安全なパスワードの暗号化をする事ができ、キャッシュ処理で、同一ユーザーの高速処理を可能としている。なぜ、今回caching_sha2_passwordを設定していないかと言うと、サーバー側とクライアント側でcaching_sha2_passwordを設定していないとエラーを起こしてしまい、クライアント側でもcaching_sha2_passwordに対応できない可能性もあるため、現状は、mysql_native_passwordが主流となっているため。

  • skip-host-cache

DNSのキャッシュ戦略機能をオフにする。

docker-composeでコンテナを立てる場合、dockerがprivate ipを当ててくれる為、dnsで名前解決する必要はない。

  • skip-name-resolve

`skip-host-name`と同様、DNSの名前解決の設定をオフにする。

  • character-set-server = utf8mb4

サーバー側でsql文を発行する際の文字コードの設定。

mysqlのutf8は1-3byte文字しか扱えない。

utf8mb4であれば、日本語や中国語、Androidの文字などの文字列を格納できるようになる。

  • collation-server = utf8mb4_unicode_ci

文字コードの照合を設定する。

設定値としては、以下がある。

1. utf8mb4_general_ci :大文字・小文字 区別しない、絵文字 区別しない、濁点・半濁点 区別する

2. utf8mb4_unicode_ci :大文字・小文字 区別しない、絵文字 区別しない、濁点・半濁点 区別しない

3. utf8mb4_unicode_520_ci :大文字・小文字 区別しない、絵文字 区別する 、濁点・半濁点 区別しない

4. utf8mb4_bin :大文字・小文字 区別する 、絵文字 区別する 、濁点・半濁点 区別する

  • init-connect = SET NAMES utf8mb4

接続する各クライアントに対してサーバーによって実行される文字列を設定できる。

今回では、クライアントからサーバーへの SQL ステートメントの送信に使用される文字セットはutfmb4で設定している。

  • skip-character-set-client-handshake

設定すると以下の3つを強制的にcharacter_set_serverの内容(utfmb4)に変更する。

character_set_connection:クエリを実行する文字コード

character_set_client   :クライアントが送ってくるとサーバーが想定している文字コード

character_set_result   :クライアントに結果を返すときの文字コード

  • [client]

mysqlクライアントツールへの設定

  • default-character-set = utf8mb4

デフォルトの文字コードとしてutf8mb4を設定。

  • [mysqldump]

バックアップコマンドへの設定

MySQLコマンドラインツールである mysql.exe の設定

最後に

何か間違っている所や気になった事があれば、コメントいただけると嬉しいです。

参考記事

DockerでRuby on Railsの環境を構築する際のentrypoint.shのコマンド及びコード理解

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

前回の記事のRails用のDockerfileを作成する際にentrypoint.shを指定していますが、今回そのentrypoint.shのコマンド及びコードの理解を備忘録として残すため。

entrypoint.shのコマンド説明

entrypoint.sh

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

以下にコマンド及びコードの解説を致します。

  • `set -e`

[set]はシェルの設定を確認、変更するコマンドで[-e]によって、実行したコマンドが1つでもエラーになったら直ちにシェルを終了。

  • rm -f /app/tmp/pids/server.pid

"/app/tmp/pids/server.pid"が存在する場合は削除、存在しない場合は無視する。

  • exec "$@"

execコマンドはbashの組み込みコマンドでシェルを実行するコマンドで置き換えるコマンドにする。また、変数"$@"はシェルスクリプトの変数がすべて展開される変数。

何故server.pidを削除する必要があるのか

"server.pid"はサーバー起動時に生成されるものであり、生成されている場合、サーバーは起動状態にあると認識されます。サーバー終了後、"server.pid"が残存する恐れがあり、サーバーを再起動する場合に「サーバーは起動しています」というエラーが吐かれる場合があります。よって、明示的に残存した"server.pid"を削除する事で問題なくサーバーを起動する事ができるようになります。

最後に

最後まで読んで頂き有難うございました!

何か間違っている所や気になった事があれば、コメントいただけると嬉しいです。

参考記事

DockerでRuby on Railsの環境を構築する際のDockerfileのコマンド及びコード理解

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

Rails用のDockerfileを作成する際にコマンド及びコードの理解を備忘録として残すため。

Dockerfileとコマンド説明

  • Dockerfile
FROM ruby:[バージョン]
RUN set -x && curl -sL https://deb.nodesource.com/setup_14.x | bash -

RUN set -x && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
    echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list

RUN set -x && apt-get update -qq && apt-get install -yq nodejs yarn vim default-mysql-client

RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app

# Add a script to be executed every time the container starts.
COPY ./forDocker/rails/entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

以下にコマンド及びコードの解説を致します。

Dockerfileコマンド

  • FROM

Dockerイメージとバージョンの指定

  • RUN

コンテナ内で実行するコマンドの指定

  • WORKDIR

Dockerfileで設定した命令の作業ディレクトリの指定

  • COPY

ローカルのディレクトリ及びファイルをDockerコンテナにマウント

  • ENTRYPOINT

最初に実行するコマンドの指定

  • EXPOSE

Dockerコンテナを公開するポート番号の指定

  • CMD

デフォルトで実行するコマンドの指定

コード理解と用語理解

  • `set -x`

[set]はシェルの設定を確認、変更するコマンドで[-x]によって、シェルが実行したコマンドとその引数を出力。

NodeSourceをインストール。数字部分でNode.jsのバージョンを指定。(今回の場合はNodejsバージョン14を指定)

Debian系で新しいyarnをインストールできるようにする。

  • `apt-get`

Debian系のディストリビューションのパッケージ管理システムであるAPTライブラリを利用してパッケージを操作管理するコマンド

  • `apt-get update -qq && apt-get install -yq nodejs yarn vim default-mysql-client`

APTパッケージ管理システムのアップデート及びnodejs、yarnなどのインストール

  • `chmod +x /usr/bin/entrypoint.sh`

全てのユーザーに/usr/bin/entrypoint.shの実行権限を与える。

最後に

私の記事だけで理解できない部分があったら、適宜調べてみて下さい。

一つ一つのコードを理解することで、理解できていない事が少なくなり、成長していけると信じています笑

ここまで読んで頂き有難うございました〜。

参考記事

Nginx+Rails6.0+MySQL8.0+Adminer:docker-compose で rails new | Zenn | 北山淳也 DockerfileのRUN命令 DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】 dockerfileのEXPOSEとネットワークオプション 【 set 】コマンド――シェルの設定を確認、変更する NodeSource Node.js Binary Distributions - GitHub Ruby:2.6 のdockerコンテナでrails6.0を入れようとしたらyarnがコケた | 北山淳也 | zenn apt-get パッケージの操作・管理 - Linuxコマンド chmod コマンド