91s

プログラミング関係、日記などを書きます

Rails6 staging環境でunicornが動かないときに確認すること

  • 結論
    • database.ymlにrubyを埋め込む時は<%= =%>で囲うのを忘れないようにする!!
    • ymlの中にruby埋め込んだら使われずとも実行されるので全ての環境でcredentials:editで該当項目を設定しておくこと

それは、unicornの謎エラー、「master failed to start, check stderr log for details」と格闘していたときのこと...

credentialsではこのように設定しており、

db:
    host: db_host
    username: root
    password: password

こうやって取得しようとしたら....

staging:
  <<: *default
  database: db_staging
  host: Rails.application.credentials.db.host
  username: Rails.application.credentials.db.username
  password: Rails.application.credentials.db.password

サーバー側で以下のエラー発生

Unknown MySQL server host 'Rails.application.credentials.db.host' (-2) (Mysql2::Error::ConnectionError)

ネット記事を参考に以下のように修正

staging:
  <<: *default
  database: db_staging
  host: Rails.application.credentials.db[:host]
  username: Rails.application.credentials.db[:username]
  password: Rails.application.credentials.db[:password]

しかしこれでもなお動かない。。

Unknown MySQL server host 'Rails.application.credentials.db[:host]'

rails cの中で確認した時は動いたのに... あれ...?

よく見たら上の方に

pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

こんな表記があるぞ...?? erbでもないのになんで囲っているんだろう...??

... ... ... ......あ!!!!

このファイル.rbじゃない、.ymlだ!!!!!!

staging:
  <<: *default
  database: db_staging
  host: <%= Rails.application.credentials.db[:host] %>
  username: <%= Rails.application.credentials.db[:username] %>
  password: <%= Rails.application.credentials.db[:password] %>

これでとりあえず取得することはできるっぽい。

その後、試しにrspecを実行したところ、以下のエラーが出た。

Failure/Error: require File.expand_path('../config/environment', __dir__)

NoMethodError:
  Cannot load database configuration:
  undefined method `[]' for nil:NilClass

あれ、credentials使ったの、staging環境だけなのに... と思ったのですが、調べたところどうやら呼ばれなくても実行されるみたいです。

なので、test, staging, developmentの環境で

rails credentials:edit --environment ●● (●●は各環境) でstagingと同様に設定を行いました(値は仮のもので問題ないです)

ここまでして無事にローカル環境で動きました。

この後、CircleCIでまた少し詰まったのですがrailsとはあまり関係ないので別記事にしようと思います。

最後までお読みいただき、ありがとうございます。

【リモートワーク】家でEC2にSSH接続できないときに確認すること

リモートワークをしていてEC2に接続できない... となってしまっていたのでメモ

 

 

 

会社でEC2の設定をした時と同様、

  1. ipアドレス 確認」で検索してグローバルIPアドレスをメモ
  2. AWSコンソールで接続したいインスタンスのセキュリティグループを確認
  3. インバウンドルールに、typeにSSHを指定してソースはカスタムにしてアドレス入力欄に1 でメモしたIPアドレスを入力→保存

 

この手順で設定したらssh接続がTime outとなって接続に失敗していました。

 

ですが、インバウンドルールでソースをマイIPにすることでAWSが自動的にIPを検出してくれてそのまま保存すれば無事接続できました。

 

よく見たら普通に公式*1

にも書いてあるので、過去の自分がどこかでカスタムにしないといけない的な記事を見たんでしょうね...笑

 

原因としては、家のWifiが貧弱なのでそもそも固定IPではない可能性が高いんですよね。

実際、マイIPで自動取得されたipアドレスと検索で出てくるipアドレスがまるで違ったのでなるほどなーって感じです。

 

-------------------

追記:固定IPを使える設定で回線を契約していないと接続するたびにIPアドレスが変わるので、繋がらなくなったなーと思ったら再設定が必要です。

-------------------

【RSpec】FactoryBotで KeyError: Trait not registered: が出た時に確認すること

RSpecでFactoryBotを使っていたときに遭遇したエラー。

KeyError: Trait not registered:

結論から言うと凡ミスだったのですが場合によっては気づきにくいのでアウトプットして定着させておこうと思ってこの記事を書いています。


前提として、

spec/factories/product.rb

# frozen_string_literal: true

FactoryBot.define do
  factory :product, class: Product do
    supplier
    price
    buy_count { 0 }
  end
end

みたいな感じでfactoryを定義していました。

このfactoryをspec側で

create(:product, supplier: supplier, price: 1000)

のように使おうとすると

KeyError: Trait not registered: "price"

というエラーがでました。

定義しているのにおっかしいなーと思ってあれやこれやしている内に、「あれ、priceって関連先モデルがあるわけじゃないぞ」ということに気づいたわけです。

ということで、 price → price {}

とすると期待通りの動作をしました。


ちなみに、 Rails6 Ruby2.7 の環境です。(バージョンと今回の問題は多分関係ないです。)

activeadmin導入時、/adminにアクセスしたとき/admin/loginではなく/loginにリダイレクトされる不具合の修正法

完全に個人用メモにはなりますが修正にかなりの時間がかかったので、同じ現象で困っている人の参考になると幸いです。

  • 前提
    • Rails6, Ruby 2.7.0
    • activeadmin 2.6.0
    • admin_userの他に通常のuserも存在している
  • 起きたこと
    • /adminにアクセスしたとき/loginにリダイレクトされる
      • 理想は/admin/login
  • 解決法
    • lib/custom_failure.rbを以下のように変更
# frozen_string_literal: true

class CustomFailure < Devise::FailureApp
  def redirect_url
    return new_admin_user_session_path if request.original_fullpath == admin_root_path # 追加

    new_user_session_path
  end
end

このように、元々/loginが返っていたのを分岐させて/adminから呼ばれたときはadminのログインパスを返すように変更しました。

以上です。最後までご覧いただき、ありがとうございました。

Rails6, Ruby2,7, mysql8 でdocker環境を作成した時に詰まった箇所 メモ

  • Mysql8
    • 認証のデフォルトがcaching_sha2_passwordになっている
      • mysql2がまだ対応していない
      • Sequel Proもまだ対応していない(テストビルド版では対応している)
    • 対処

      • docker-compose.ymlのmysqlコンテナのコマンドに追記
        • command: mysqld --character-set-server=utf8mb4 --default-authentication-plugin=mysql_native_password
        • (--default-authentication-plugin=mysql_native_password が追記部分)
    • 参考:https://qiita.com/ucan-lab/items/3ae911b7e13287a5b917

  • Ruby2.7

unicornが起動できない(TypeError: no implicit conversion of nil into String)

  • 前提
    • fog-aws、carrierwaveを使用しています。

staging環境でunicornの再起動をしようとしたら以下のエラーが出ました

[fog][DEPRECATION] Fog::Storage::AWS is deprecated, please use Fog::AWS::Storage.

[fog][WARNING] Unrecognized arguments: region, aws_access_key_id, aws_secret_access_key

bundler: failed to load command: unicorn_rails (/home/(・・略・・)/vendor/bundler/ruby/2.5.0/bin/unicorn_rails)

TypeError: no implicit conversion of nil into String

...


fog-awsのエラーかと思いましたがその辺は触っていないので、carrierwave側で何かあるのかと思い確認してみると、aws_access_key、aws_secret_access_keyが読み込めていなかったようなので、以下のように変更


carrierwave.rb

・・略・・

# aws_access_key_id: Rails.application.credentials.aws[:access_key_id], ←コメントアウト

# aws_secret_access_key: Rails.application.credentials.aws[:aws_secret_access_key], ← コメントアウト

・・略・・


use_iam_profile: true # ←追加


で解消しました。

CodeDeployのエラー ~ The overall deployment failed ... 略 ~

codedeployが失敗していて、デプロイ詳細画面の上部に

The overall deployment failed because too many individual instances failed deployment, too few healthy instances are available for deployment, or some instances in your deployment group are experiencing problems.

 
これが出ていて、翻訳しても、

展開に失敗した個々のインスタンスが多すぎるか、展開に使用できる正常なインスタンスが少なすぎるか、展開グループ内の一部のインスタンスで問題が発生しているため、展開全体が失敗しました。

という控えめに言って意味不明な状態でした。

ステータスを見ようとしても全部スキップになっていて見れない為、ec2にssh接続して、

less /var/log/aws/codedeploy-agent/codedeploy-agent.log

で codedeployのログを確認すると以下のような記述を発見
 

booting child: error during start or run: NoMethodError - undefined method `underscore' for Seahorse::Util:Module - /opt/codedeploy-agent/lib/instance_agent/plugins/codedeploy/command_executor.rb:51:in `command'

 

そのまま読むとunderscoreメソッドがないってことなのですが、色々調べた結果、codedeployではaws-sdk-coreのバージョン3系に対応してないそうです。
(該当のunderscoreメソッドは3系で削除されたっぽい??)


aws-sdk-s3がaws-sdk-coreのV3を必要としていたので、アプリ側の問題かと思ってGemfileからaws-sdk-s3を削除したところ、デプロイが通らないがエラーが以下のように変わりました。

 

booting child: error during start or run: Gem::ConflictError - Unable to activate codedeploy-commands-1.0.0, because aws-sdk-core-3.85.1 conflicts with aws-sdk-core (~> 2.9) - /usr/local/rbenv/versions/2.5.3/lib/ruby/site_ruby/2.5.0/rubygems/specification.rb:2302:in `raise_if_conflicts'

 

codedeploy実行時に使用しているruby環境(アプリケーションで使用しているruby環境とは異なる??)でaws-sdk-coreが2系と3系の2つインストールされていてconflictしていることが判明。

なぜここにaws-sdk-core-3.85.1が入ってしまっているかは不明だが、今回は使わないので削除.. しようとしたらpermission deniedでuninstallできませんでした。

仕方がないので、

sudo su - 
gem uninstall aws-sdk-core -v "3.85.1"

でrootユーザーになってuninstallしたらデプロイが進みました。