【Rails×Capistrano】自動デプロイしようとしたら「ArgumentError: Missing `secret_key_base` for ‘production’ environment, set this string with `rails credentials:edit`」
エラー
ArgumentError: Missing `secret_key_base` for ‘production’ environment, set this string with `rails credentials:edit`
結論
この記事通りにやればうまく行った。
原因
上の記事でも述べられているように、私も同じく下記の記事通りにCapistranoの実装を進めていたところ、タイトルのエラーが出た。
解決までの流れ
ArgumentError: Missing secret_key_base for ‘production’ environment, set this string with rails credentials:edit
でググってみた
いろいろ調べてみても、本番環境(サーバー)で設定したcredentials.yml.enc と master.key と、ローカルで設定したcredentials.yml.enc と master.key とが合致していないから、鍵と鍵穴がマッチしていなくこのタイトルのエラーがでるよ、という記事ばかりだった。
言われた通り、
[サーバーのappディレクトリ]$ rm config/credentials.yml.enc [サーバーのappディレクトリ]$ rm config/master.key
とやってみて、一度削除してから
[サーバーのappディレクトリ]$ EDITOR=vim rails credentials:edit
を打って再度生成。
そして生成されたcredentials.yml.enc と master.keyを、ローカルにコピペして、再度githubにプッシュした後、bundle exec cap production deployをするも、エラー内容は変わらず。
解決の兆しを発見
こちらの記事の下部に、Capistranoでデプロイ自動化するときに発生したエラーがいくつかまとめられていた。
よーくみると、
「secrets.yml」にかけ! 「master.key」をセキュアな方法でデプロイ先の「app_dir/shared/config」においてあげると動きます。 https://shikiyura.com/2018/05/ruby_rails-automate-deployment-by-capistrano/
との記載されている。
そういえば、Capistranoはshared配下に置かれるように、 config/deploy.rb
で設定したような・・・
そして解決してくれる記事を発見!
Railsが標準でsecrets.ymlを見に行くので、ファイル名はsecrets.ymlになっていないといけないとのこと。
ローカルで設定したコードを下記の通り訂正。
# 訂正前 set :linked_files, fetch(:linked_files, []).push('config/settings.yml') # 訂正後 set :linked_files, fetch(:linked_files, []).push('config/secrets.yml')
そしてサーバー側のファイル名も訂正。
$ cd /var/www/app名/shared/config $ mv settings.yml secrets.yml
再度、 bundle exec cap production deploy
を実行。
進んだ!!!
ちなみにサーバーの/shared/config/secrets.yml内にはrake secretコマンドを打って出てきたセキュアな値を貼り付ける。
[サーバーのappディレクトリ]$ rake secret 11111111111111122222222222223333333333333 [サーバーのappディレクトリ]$ vi shared/config/secrets.yml
production: secret_key_base: 11111111111111122222222222223333333333333
【Rails×Capistrano】自動デプロイ中に「SassC::SyntaxError: Error: File to import not found or unreadable: ~bulma/bulma.」エラー
エラー
環境はRails 6.0.3.6、Ruby2.7.2、Vue 2.6.12
SassC::SyntaxError: Error: File to import not found or unreadable: ~bulma/bulma. on line 16:1 of app/assets/stylesheets/style.scss >> @import "~bulma/bulma";
結論
パスを明示的に全部記載してあげるだけ!!
@import "../../../node_modules/bulma/bulma.sass";
原因
bundle exec cap production deploy中のエラー。 曖昧なままだが、おそらく単純にパスが終えていなかったんだと思う。 ローカルだと読み込めていたのになぜだろう・・・ あと、そもそもパッケージマネージャー(yarn)でインストールすくことについてちゃんと理解していなかった。ググった記事のコピペで済ませてきた代償です。。。
解決方法
解決策として、最初に下記項目にあたりをつけてみた。
- バージョン変わった?
- importのやりかた変わった?
- yarnでaddしたからCDNでやってみる?
- ファイル名がおかしい?
- またまたcapistranoの設定云々? ひとつめ、サーバーでyarn add bulmaしてみたらローカルと違うバージョンがインストールされてしまったので、戻してみてバージョンを揃えてみたが、エラーは変わらず。
二つ目、importのやり方が変わった?
これを突き進めていくに当たって、「あれ?importってそもそもどこのファイル読みに行ってるんだっけ?」となり、そういえばググった記事を見つけてコピペしたら動いたのでそのままにしていたのを思い出した。
ここにきて初めてちゃんとyarnとnodeについて調べてみた。
どうやら /node_modules/bulma/bulma.sass
このファイルを読み込みに行っているらしい。
では丁寧にちゃんと明示してあげよう!と下記のとおり、修正してみた。
# 修正前 @import "~bulma/bulma"; # 修正後 @import "../../../node_modules/bulma/bulma.sass";
これでちゃんと通りました!
なぜローカルでは修正前の書き方でもいいのに、本番環境だと明示してあげないといけないかはまだ謎。
学んだこと
yarn add
したものは、node_modules内のフォルダに格納され、それを読み込む必要がある。- 記事のコピペは後で痛い目見る!
【Rails×Capistrano】Gemfile not found (Bundler::GemfileNotFound)
解決方法
app/config/unicorn/production.rb
に下記を追記
before_exec do |server| ENV["BUNDLE_GEMFILE"] = File.join(File.expand_path("../../../../", __FILE__), "current", "Gemfile") end
ローカルにて下記コマンドでunicornをSTOPしてSTARTしてあげる。
$ bundle exec cap production unicorn:stop $ bundle exec cap production unicorn:start
原因
deployを何度もやっていると、急にGemfileが読み込まれなくなり、再起動できなくなることがある。
app/config/unicorn/production.rb
にて、 preload_app true
を設定している場合に起こりうるらしい。
preload_app trueとは、ほっとホットデプロイ、緩やかなデプロイとよく言われるらしい。USR2。ググればたくさん出てくる。
この時点でENV[“BUNDLE_GEMFILE”]にはRAILS_ROOT/releases/日付的なやつ/Gemfileが入ってしまうので、これをunicornプロセスが覚え続けてしまう。
そうすると、そのうちSIGUSR2がなげられても、一旦BUNDLE_GEMFILEの方にGemfileを確認してしまうので、既に存在しないGemfileを確認にいってしまう。
参考
【PHP】小数点以下の桁数を指定して切り捨てる方法(floor、number_format、sprintf)
やりたいこと
ある桁数以下は切り捨てて、それより上の桁数で値を返したかった。
例えば、小数点第三位以下は切り捨てて、小数点第二位までを返したい。
課題
ググると、 floor
と sprintf
と number_format
があるよう。
floor
だと小数点以下の切り捨てて整数にするのみで、桁数の指定はできない。
sprintf
と number_format
なら、小数点以下の桁数を指定するだけなので簡単そう!と思ったが、よくよく調べてみると、なぜか四捨五入されてしまうらしい。
結論
結局、完全な切り捨てを行いたいなら floor
を工夫して使うのが良さそうという結論に辿り着いた。
イメージは、元の数値を割って小数点の位置を左にズラしてから floor
で小数点以下を切り捨てて、割った数分、倍にすれば良い。
例えば、小数第三位以下は切り捨てたいなら、ある数値を100倍してからfloor
で切り捨てて、その後で100で割って、小数第二位までに戻す。
もし元の数字の小数点以下の桁数が動的であれば、その数字に
number_format
かsprintf
で桁数を揃えてから(小数点第二位までにしたければ、第三位までを一旦揃える)、floor
を使って切り捨てれば良さそう。もし元の数字の小数点以下の桁数が動的であれば、その数字に
number_format
かsprintf
で桁数を揃えてから、floor
を使って切り捨てれば良さそう。
下記のサンプルコードは下記サイトから引用。
<?php // 小数第一位で切り捨て print floor(2.26); // 2 // 小数第一位で切り捨て print floor(2.82); // 2 // マイナスの場合 print floor(-2.82); // -3 // 小数第二位で切り捨て print (floor(12.262 * 10) / 10); // 12.2 // 小数第三位で切り捨て print (floor(12.262 * 100) / 100); // 12.26 // 1の位で切り捨て print (floor(122.2 / 10) * 10); // 120 // 10の位で切り捨て print (floor(122.2 / 100) * 100); // 100 ?>
小数第二位で切り捨てています。以下の操作です。 1.対象の値に10を掛けます。(12.262 * 10 = 122.62) 2.floorメソッドを使用して小数点以下を切り捨てます。(122.62 → 122) 3.対象の値を再度10で割ります。(122 / 10 = 12.2)
number_formatとsprintfの挙動
number_format
number_format( float $num, int $decimals = 0, ?string $decimal_separator = ".", ?string $thousands_separator = "," ): string
num
フォーマットする数値。
decimals
小数点以下の桁数。 0
を指定すると、 返り値の decimal_separator
は省略されます。
decimal_separator
小数点を表す区切り文字。
thousands_separator
千の位毎の区切り文字。
$number = 1234.56; // 英語での表記 (デフォルト) $english_format_number = number_format($number); // 1,235 $number = 1234.5678; // 千位毎の区切りがない英語での表記 $english_format_number = number_format($number, 2, '.', ''); // 1234.57 // ここ四捨五入されてる
PHPで小数点以下を2桁とか3桁に切り捨てる2つの方法 | PisukeCode - Web開発まとめ
なぜか四捨五入されてる。切り捨てたい。
sprintf
sprintfとprintfの違いは、sprintfはフォーマットされた値が戻り値。printfはフォーマットされた値を標準出力する。
$num1 = 10; $num2 = 1000.5; $num3 = 0.456789; echo sprintf('%.2f',$num1),PHP_EOL; echo sprintf('%.2f',$num2),PHP_EOL; echo sprintf('%.2f',$num3),PHP_EOL; /* 10.00 1000.50 0.46 // ここがなぜか四捨五入されてる。 */
なぜか四捨五入されてしまう場合もあるので、切り捨て対時は使えなさそう。