- 投稿日:2020-01-18T23:58:49+09:00
独学ではじめてAWS(EC2)にデプロイする方法⑩(macでNginxのインストールと設定)
Nginx
Webサーバの一種であるNginxの導入と設定を行います。
nginxは静的コンテンツ(つまりサーバ上のファイル)を高速に配信するように設計されている。
ユーザーのリクエストに対して静的コンテンツの取り出し処理を行い、そして動的コンテンツの生成をアプリケーションサーバに依頼することが可能Nginxをインストール
下記のコマンドでインストール
[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install nginxNginxの設定ファイルを編集
[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.conf下記を貼り付ける
(ディレクトリの場所などは、自分にあった場所を指定してください)rails.confupstream app_server { # Unicornと連携させるための設定。 # アプリケーション名を自身のアプリ名に書き換えることに注意。今回であればおそらく server unix:/var/〇〇〇(アプリをまとめているディレクトリ)/〇〇〇〇〇〇<アプリケーション名>/tmp/sockets/unicorn.sock; } # {}で囲った部分をブロックと呼ぶ。サーバの設定ができる server { # このプログラムが接続を受け付けるポート番号 listen 80; # 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない server_name 18.〇〇〇.〇〇〇.〇〇(Elastic IP); # クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく client_max_body_size 2g; # 接続が来た際のrootディレクトリ root /var/www/〇〇〇〇〇<アプリケーション名>/public; # assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定 location ^~ /assets/ { gzip_static on; expires max; add_header Cache-Control public; } try_files $uri/index.html $uri @unicorn; location @unicorn { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; } error_page 500 502 503 504 /500.html; }
- 3行目の<アプリケーション名> となっている箇所は、ご自身のものに変更してください。
- 11行目の<Elastic IP>となっている箇所も同様に、ご自身のものに変更してください。
- 14行目の<アプリケーション名> となっている箇所は、ご自身のものに変更してください。
Nginxの権限を変更
POSTメソッドでもエラーが出ないようにするために、下記のコマンドも実行してください。
[ec2-user@ip-172-31-25-189 ~]$ cd /var/lib [ec2-user@ip-172-31-25-189 lib]$ sudo chmod -R 775 nginxNginxを再起動して設定ファイルを再読み込み
[ec2-user@ip-172-31-25-189 lib]$ cd ~ [ec2-user@ip-172-31-25-189 ~]$ sudo service nginx restartローカルでunicorn.rb修正
listen 3000 ↓以下のように修正 listen "#{app_path}/tmp/sockets/unicorn.sock"Githubで変更点をpushしたら、本番環境でも反映させます。
ターミナル(EC2)[ec2-user@ip-172-31-25-189 ~]$ cd /var/www/アプリ名 [ec2-user@ip-172-31-23-189 <アプリ名>]$ git pull origin masterUnicornを再起動
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn ec2-user 17877 0.4 18.1 588472 182840 ? Sl 01:55 0:02 unicorn_rails master -c config/unicorn.rb -E production -D ec2-user 17881 0.0 17.3 589088 175164 ? Sl 01:55 0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D ec2-user 17911 0.0 0.2 110532 2180 pts/0 S+ 02:05 0:00 grep --color=auto unicorn続いて、unicorn_rails master(一番上)のプロセスをkillします。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill <確認したunicorn rails masterのPID(上のコードでは17877)>unicornを起動します
[ec2-user@ip-172-31-23-189 <アプリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -DブラウザからElastic IPでアクセス
https:// (Elastic IP)
これでサイトが表示されず、下記が表示されたら、、、、、、、、、
もう一度、下記をやり直してください。
Nginxの設定ファイルを編集
[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.conf下記を貼り付ける
(ディレクトリの場所などは、自分にあった場所を指定してください)rails.confupstream app_server { # Unicornと連携させるための設定。 # アプリケーション名を自身のアプリ名に書き換えることに注意。今回であればおそらく server unix:/var/〇〇〇(アプリをまとめているディレクトリ)/〇〇〇〇〇〇<アプリケーション名>/tmp/sockets/unicorn.sock; } # {}で囲った部分をブロックと呼ぶ。サーバの設定ができる server { # このプログラムが接続を受け付けるポート番号 listen 80; # 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない server_name 18.〇〇〇.〇〇〇.〇〇(Elastic IP); # クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく client_max_body_size 2g; # 接続が来た際のrootディレクトリ root /var/www/〇〇〇〇〇<アプリケーション名>/public; # assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定 location ^~ /assets/ { gzip_static on; expires max; add_header Cache-Control public; } try_files $uri/index.html $uri @unicorn; location @unicorn { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; } error_page 500 502 503 504 /500.html; }これで無事にサイトが表示されたら、完了です!
- 投稿日:2020-01-18T23:31:36+09:00
AWS(EC2)でNginxのrails.confを設定する方法
AWSのNginxを設定する際に、rails.confファイルの設定をします。
この方法の説明が意外とないので、説明していきます
Nginxの設定ファイルを編集
[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.confrails.confファイルが開かれたら、下記の記述をします。
rails.confupstream app_server { # Unicornと連携させるための設定。 # アプリケーション名を自身のアプリ名に書き換えることに注意。 server unix:/var/〇〇〇(アプリをまとめているディレクトリ)/〇〇〇〇〇〇<アプリケーション名>/tmp/sockets/unicorn.sock; } # {}で囲った部分をブロックと呼ぶ。サーバの設定ができる server { # このプログラムが接続を受け付けるポート番号 listen 80; # 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない server_name 18.〇〇〇.〇〇〇.〇〇(Elastic IP); # クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく client_max_body_size 2g; # 接続が来た際のrootディレクトリ root /var/www/〇〇〇〇〇<アプリケーション名>/public; # assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定 location ^~ /assets/ { gzip_static on; expires max; add_header Cache-Control public; } try_files $uri/index.html $uri @unicorn; location @unicorn { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; } error_page 500 502 503 504 /500.html; }3行目の<アプリケーション名> となっている箇所は、ご自身のものに変更してください。
11行目の<Elastic IP>となっている箇所も同様に、ご自身のものに変更してください。
14行目の<アプリケーション名> となっている箇所は、ご自身のものに変更してください。これで設定ができます。
- 投稿日:2020-01-18T23:18:20+09:00
Kernel.#forkで作成した子プロセスをゾンビ化させない
背景
ジョブキューをさばくバッチ処理を開発していると、子プロセスを使って並列処理を実装したくなりました。
最大で10プロセスまで子プロセスを生成し10並列で処理できるように実装したは良いものの、
子プロセスがゾンビプロセス化してジョブキューをうまくさばくことができませんでした。これまでなんとなくRubyでプロセスを扱ってきたので、これを機にいろいろ試してみました。
検証環境
- OS
- Debian GNU/Linux 9 (stretch)
- Dockerコンテナで検証しました。
- Ruby
- 2.6.3
検証
以下、やったことを書いていきます。
親プロセス
手始めに親プロセスの確認。
root@05b9ab6e9fa3:~# irb irb(main):001:0> irb(main):002:0> Process.pid => 534root@05b9ab6e9fa3:~# ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 1.2 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 3.7 0.8 90008 16596 pts/0 S+ 12:23 0:00 \_ irb :親のpidが「534」であることが確認できました。
子プロセス
次に子プロセスの確認。
Kernel.#fork
を使って、子プロセスを生成します。irb(main):003:0> fork { sleep 60 } => 543root@05b9ab6e9fa3:~# ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 0.4 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 0.9 0.8 90148 16596 pts/0 S+ 12:23 0:00 \_ irb root 543 0.0 0.5 90148 11396 pts/0 S+ 12:25 0:00 \_ irb :子プロセスが生成できました。
ゾンビ化する子プロセス
しばらく時間をおいてプロセスを確認すると、子プロセスが になり、STATが Z+ になっていました。
root@05b9ab6e9fa3:~# ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 0.2 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 0.5 0.8 90148 16596 pts/0 S+ 12:23 0:00 \_ irb root 543 0.0 0.0 0 0 pts/0 Z+ 12:25 0:00 \_ [irb] <defunct> :これは親プロセスが子プロセスを管理していないため、子プロセスがカーネルのキューに残り続けてしまっている状態のようです。
子プロセスをゾンビ状態から開放させてあげるためには、親プロセスにて
Process.wait
を読んであげると良いらしいのでやってみました。irb(main):004:0> Process.wait => 543root@05b9ab6e9fa3:~# ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 0.0 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 0.2 0.8 90148 16664 pts/0 S+ 12:23 0:00 \_ irb :子プロセスが無事に開放されましたね。
子プロセスをゾンビにさせない
子プロセスが終了するより先に、
Process.#detach
を呼んでみます。irb(main):007:0> fork { sleep 60 } => 555 irb(main):008:0> Process.detach(555) => #<Process::Waiter:0x000055ca51dad5b0 run> irb(main):009:0>子プロセスの処理が終了する前にプロセスの状況を確認してみると、先ほどとは変わらないですね。
root@05b9ab6e9fa3:~# ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 0.0 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 0.1 0.8 157740 16724 pts/0 Sl+ 12:23 0:00 \_ irb root 555 0.0 0.5 90148 11420 pts/0 S+ 12:32 0:00 \_ irb :子プロセスの処理が終了した後にプロセスの状況を確認してみると...
root@05b9ab6e9fa3:~# ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 0.0 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 0.1 0.8 157740 16732 pts/0 S+ 12:23 0:00 \_ irb :おー。ゾンビにならず無事に(?)子プロセスが終了しています。
ゾンビプロセスにさせたくないときは、子プロセスを生成した後すぐにデタッチしてあげると良いみたいですね。子プロセスが終了した後に、
Process.#detach
を呼ぶとどうなるかまずは子プロセスの生成。
irb(main):018:0> fork { sleep 60 } => 562子プロセスがゾンビ化するのを待ちます。
root@05b9ab6e9fa3:~# ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 0.0 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 0.0 0.8 157888 16836 pts/0 S+ 12:23 0:00 \_ irb root 562 0.0 0.0 0 0 pts/0 Z+ 12:38 0:00 \_ [irb] <defunct> :親プロセスで
Process.#detach
を呼び出します。irb(main):020:0> Process.detach(562) => #<Process::Waiter:0x000055ca51dc8ec8 run> irb(main):021:0>プロセスの状態を確認すると
root@05b9ab6e9fa3:~# ps auxf USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 0.0 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 0.0 0.8 157888 16860 pts/0 S+ 12:23 0:00 \_ irb :子プロセスが消えてますね。
まあ、これはそうなるような気がしてました。スレッドの状態を確認する
irb(main):023:0> fork { sleep 60 } => 577root@05b9ab6e9fa3:~# ps aux -L USER PID LWP %CPU NLWP %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 529 0.0 1 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 534 0.0 1 0.8 157888 16860 pts/0 S+ 12:23 0:00 irb root 577 577 0.0 1 0.5 157888 11636 pts/0 S+ 12:43 0:00 irb子プロセスが終了する前に、
Process.#detach
を呼びます。irb(main):024:0> Process.detach(577) => #<Process::Waiter:0x000055ca51dd4b60 run>スレッドを確認すると、
root@05b9ab6e9fa3:~# ps aux -L USER PID LWP %CPU NLWP %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 529 0.0 1 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 534 0.0 2 0.8 157888 16904 pts/0 Sl+ 12:23 0:00 irb root 534 580 0.0 2 0.8 157888 16904 pts/0 Sl+ 12:43 0:00 irb root 577 577 0.0 1 0.5 157888 11636 pts/0 S+ 12:43 0:00 irb :PIDが534のプロセスが2プロセスになってます。
ps
コマンドの-L
オプションで スレッドも表示するようにしているためです。子プロセスが終了すると、
root@05b9ab6e9fa3:~# ps aux -L USER PID LWP %CPU NLWP %MEM VSZ RSS TTY STAT START TIME COMMAND : root 529 529 0.0 1 0.1 18188 3216 pts/0 Ss 12:23 0:00 /bin/bash root 534 534 0.0 1 0.8 157888 16904 pts/0 S+ 12:23 0:00 irb :子プロセスが消え、親プロセスも1スレッドに戻っていることが確認できました。
この状態から、親プロセスで
Process.#wait
を呼ぶとirb(main):026:0> Process.wait Traceback (most recent call last): 5: from /usr/local/bin/irb:23:in `<main>' 4: from /usr/local/bin/irb:23:in `load' 3: from /usr/local/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>' 2: from (irb):26 1: from (irb):26:in `wait' Errno::ECHILD (No child processes)
Errno::ECHILD
エラーが発生してますね。
子プロセスがいなくなっているのだから、当然ですね。同じことを、Rubyのプログラムからも確認してみました。
irb(main):043:0> fork { sleep 60 } => 585 irb(main):044:0> irb(main):045:0> Process.detach(585) => #<Process::Waiter:0x000055ca51b51230 run> irb(main):046:0> irb(main):047:0> Thread.list => [#<Thread:0x000055ca5174f2b8 run>, #<Process::Waiter:0x000055ca51b51230 sleep>] irb(main):048:0> irb(main):049:0> # ここで子プロセスが終了。 irb(main):050:0> Thread.list => [#<Thread:0x000055ca5174f2b8 run>] irb(main):051:0>スレッドが2になり、子プロセスが終了するとスレッド数も1に戻っていることがわかります。
Process.#detach
と `Process.#wait を同時に呼ぶとどうなるかirb(main):034:0> fork { sleep 60 } => 583 irb(main):035:0> Process.detach(583) => #<Process::Waiter:0x000055ca51dff518 run> irb(main):036:0> irb(main):037:0> Process.wait Traceback (most recent call last): 5: from /usr/local/bin/irb:23:in `<main>' 4: from /usr/local/bin/irb:23:in `load' 3: from /usr/local/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>' 2: from (irb):37 1: from (irb):37:in `wait' Errno::ECHILD (No child processes)
Process.wait
を読んだ直後は、待ち状態に入りました。
子プロセスの処理が終了したタイミングでErrno::ECHILD
エラーが発生しました。
Process.#detach
と `Process.#wait のどちらか一方を呼び出すようにするのが良さそうです。結論
forkしたあと、すぐに
Process.#detach
を呼び出し、スレッド数を監視することで子プロセス数の制御するのが良さそうな気がしました。このようなユースケースではどうやってプロセス管理するのがいいんでしょうね。
他の方法でやってる方がいらっしゃったら教えてください?
参考
- 投稿日:2020-01-18T22:02:44+09:00
Github Actionsを使ってAWS Lambda関数を更新する
モチベーション
AWSコンソールを開いたり、AWS CLIを使わずに、gitの操作だけでAWS Lambda関数のデプロイを完了します。
近年、Github AcitonsというGithub純正のCI/CDツールがリリースされました。
これを使って、Githubで管理しているAWS Lambda関数の変更を、AWSに反映します。先駆者
検索すると、AWS Lambda関数をデプロイするGithub Acitonsがいくつか公開されているのが見つかります。1
例えば Deploy AWS Lambda function のソースコードを見てみましょう。
aws-sdk
を使っているのがわかります。2
その中でもupdate_function_code
メソッドを使っています。3同様に
aws-sdk
を使えば上手くいきそうです。
今回はRuby用のaws-sdk-lambda gemを使います。準備
IAMユーザー
万が一、AWSのIDとパスワードが漏れたときに、該アカウントだけを停止できるように、AWS上にdeploy専用のIAMユーザーを作成します。
必要なIAMポリシーは次のとおりです。{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "lambda:UpdateFunctionCode", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXX:function:tange" } ] }
Action
には今回使いたいupdate_function_code
メソッドを表すlambda:UpdateFunctionCode
を指定します。
Resource
には、更新対象のLambda関数のARN
の値を指定します。ここでは
arn:aws:lambda:ap-northeast-1:XXXXXXX:function:tange
を指定しました。Github Secrets
Github Actionsには、リポジトリに設定されたパスワードのような秘密情報を参照する機能があります。
IAMのaccess_key_id
とsecret_access_key
をGithub Actionsから参照するのに使います。手順は暗号化されたシークレットの作成と利用 - GitHub ヘルプを参照してください。
Github Actions
完成形
最初に完成形を示します。これをLambda関数を管理しているリポジトリに追加すると、Github Acitonsは動作します。
.github/workflows/deploy_lambda.ymlname: Ruby on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Set up Ruby 2.5 uses: actions/setup-ruby@v1 with: ruby-version: 2.5.x - name: bundle install run: | gem install bundler bundle install --deployment - name: Zip run: | zip deploy_package lambda_function.rb -r vendor - name: Deploy env: access_key_id: ${{ secrets.access_key_id }} secret_access_key: ${{ secrets.secret_access_key }} run: | gem install aws-sdk-lambda bin/deploy各ジョブの解説
リポジトリへのpushに応じてGithub Actionsを起動する
on: [push]onには色々なトリガーが指定できます。
詳しくはワークフローをトリガーするイベント - GitHub ヘルプを見てください。ソースコードをチェックアウトする
- uses: actions/checkout@v1Ruby 2.5の環境を作る
AWS Lambdaはruby 2.5をサポートしています。4
- name: Set up Ruby 2.5 uses: actions/setup-ruby@v1 with: ruby-version: 2.5.x依存ライブラリをダウンロードする
- name: bundle install run: | gem install bundler bundle install --deployment
--deployment
をつけると、依存ライブラリはvendor
ディレクトリ配下に格納されます。zip圧縮
zipコマンドで必要なファイルを1つのzipファイルに纏めます。
- name: Zip run: | zip deploy_package lambda_function.rb -r vendor
deploy_package
は作成するzipファイル名です。
lambda_function.rb
はzipファイルに含めるファイル名です。
AWS LambdaでRubyランタイムを使うときのデフォルトファイル名がlambda_function.rb
です。
他に必要なファイルがあれば、空白で区切って続けて書いてください。
-r vendor
はbundle install
コマンドで保存した依存ライブラリをzipファイルに入れるためにつけています。
他に必要なディレクトリがあれば追加してください。AWSにアップロード
- name: Deploy env: access_key_id: ${{ secrets.access_key_id }} secret_access_key: ${{ secrets.secret_access_key }} run: | gem install aws-sdk-lambda bin/deployGithub Secretsに設定した秘密情報を読み込みます。
env: access_key_id: ${{ secrets.access_key_id }} secret_access_key: ${{ secrets.secret_access_key }}
${{ secrets.access_key_id }}
がGithub Secretsを参照している箇所です。デプロイに必要な
aws-sdk-lambda
gemをインストールして、デプロイを実行します。run: | gem install aws-sdk-lambda bin/deploy
bin/deploy
はRubyスクリプトです。bin/deploy#!/usr/bin/env ruby require "aws-sdk-lambda" client = Aws::Lambda::Client.new region: "ap-northeast-1", access_key_id: ENV["access_key_id"], secret_access_key: ENV["secret_access_key"] zip_file = File.open "deploy_package.zip", "r" client.update_function_code function_name: "tange", zip_file: zip_fileAws::Lambda::Client#update_function_codeを使って、AWS Lambda関数を更新します。
https://github.com/marketplace?utf8=%E2%9C%93&type=actions&query=lambda ↩
https://github.com/yvesgurcan/deploy-lambda-function/blob/master/index.js#L4 ↩
https://github.com/yvesgurcan/deploy-lambda-function/blob/master/index.js#L34 ↩
https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html ↩
- 投稿日:2020-01-18T22:02:44+09:00
Github Actionsを使ってRuby製のAWS Lambda関数を更新する
モチベーション
AWSコンソールを開いたり、AWS CLIを使わずに、gitの操作だけでAWS Lambda関数のデプロイを完了します。
近年、Github AcitonsというGithub純正のCI/CDツールがリリースされました。
これを使って、Githubで管理しているAWS Lambda関数の変更を、AWSに反映します。前提条件
今回はRubyで作成されたAWS Lambda関数を更新します。
Lambda関数とデプロイスクリプトが同じ言語だとメンテナンスが楽なので、デプロイにもRubyを使います。先駆者
検索すると、AWS Lambda関数をデプロイするGithub Acitonsがいくつか公開されているのが見つかります。1
例えば Deploy AWS Lambda function のソースコードを見てみましょう。
aws-sdk
を使っているのがわかります。2
その中でもupdate_function_code
メソッドを使っています。3引数にはZipファイルを指定しています。
AWSコンソールでAWS Lambda関数を更新するときと同様に、zipファイルを作って更新すれば良さそうです。Ruby用のaws-sdk-lambda gemを使います。
準備
IAMユーザー
万が一、AWSのIDとパスワードが漏れたときに、該アカウントだけを停止できるように、AWS上にdeploy専用のIAMユーザーを作成します。
必要なIAMポリシーは次のとおりです。{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "lambda:UpdateFunctionCode", "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXX:function:tange" } ] }
Action
には今回使いたいupdate_function_code
メソッドを表すlambda:UpdateFunctionCode
を指定します。
Resource
には、更新対象のLambda関数のARN
の値を指定します。ここでは
arn:aws:lambda:ap-northeast-1:XXXXXXX:function:tange
を指定しました。Github Secrets
Github Actionsには、リポジトリに設定されたパスワードのような秘密情報を参照する機能があります。
IAMのaccess_key_id
とsecret_access_key
をGithub Actionsから参照するのに使います。手順は暗号化されたシークレットの作成と利用 - GitHub ヘルプを参照してください。
Github Actions
完成形
最初に完成形を示します。これをLambda関数を管理しているリポジトリに追加すると、Github Acitonsは動作します。
.github/workflows/deploy_lambda.ymlname: Ruby on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Ruby 2.5の環境を作る uses: actions/setup-ruby@v1 with: ruby-version: 2.5.x - name: 依存gemをダウンロード run: | gem install bundler bundle config set deployment 'true' bundle install - name: zip圧縮 run: | zip deploy_package lambda_function.rb -r vendor - name: AWSにアップロード env: access_key_id: ${{ secrets.access_key_id }} secret_access_key: ${{ secrets.secret_access_key }} run: | gem install aws-sdk-lambda bin/deploy各ジョブの解説
リポジトリへのpushに応じてGithub Actionsを起動する
on: [push]onには色々なトリガーが指定できます。
詳しくはワークフローをトリガーするイベント - GitHub ヘルプを見てください。ソースコードをチェックアウトする
- uses: actions/checkout@v1Ruby 2.5の環境を作る
AWS Lambdaはruby 2.5をサポートしています。4
- name: Ruby 2.5の環境を作る uses: actions/setup-ruby@v1 with: ruby-version: 2.5.x依存gemをダウンロード
- name: bundle install run: | gem install bundler bundle config set deployment 'true' bundle installAWS Lambdaでは、関数は実行可能は状態でアップロードする必要があります。
つまりアップロードzipファイルには依存ライブラリも入れる必要があります。
zipファイルに入れやすくするため、依存gemをローカルディレクトリにインストールします。
bundle config set deployment 'true'
を設定すると、依存ライブラリはvendor
ディレクトリ配下に格納されます。zip圧縮
zipコマンドで必要なファイルを1つのzipファイルに纏めます。
- name: Zip run: | zip deploy_package lambda_function.rb -r vendor
deploy_package
は作成するzipファイル名です。
lambda_function.rb
はzipファイルに含めるファイル名です。
AWS LambdaでRubyランタイムを使うときのデフォルトファイル名がlambda_function.rb
です。
他に必要なファイルがあれば、空白で区切って続けて書いてください。
-r vendor
はbundle install
コマンドで保存した依存ライブラリをzipファイルに入れるためにつけています。
他に必要なディレクトリがあれば追加してください。AWSにアップロード
- name: Deploy env: access_key_id: ${{ secrets.access_key_id }} secret_access_key: ${{ secrets.secret_access_key }} run: | gem install aws-sdk-lambda bin/deployGithub Secretsに設定した秘密情報を読み込みます。
env: access_key_id: ${{ secrets.access_key_id }} secret_access_key: ${{ secrets.secret_access_key }}
${{ secrets.access_key_id }}
がGithub Secretsを参照している箇所です。デプロイに必要な
aws-sdk-lambda
gemをインストールして、デプロイを実行します。run: | gem install aws-sdk-lambda bin/deploy
bin/deploy
はRubyスクリプトです。bin/deploy#!/usr/bin/env ruby require "aws-sdk-lambda" client = Aws::Lambda::Client.new region: "ap-northeast-1", access_key_id: ENV["access_key_id"], secret_access_key: ENV["secret_access_key"] zip_file = File.open "deploy_package.zip", "r" client.update_function_code function_name: "tange", zip_file: zip_fileAws::Lambda::Client#update_function_codeを使って、AWS Lambda関数を更新します。
https://github.com/marketplace?utf8=%E2%9C%93&type=actions&query=lambda ↩
https://github.com/yvesgurcan/deploy-lambda-function/blob/master/index.js#L4 ↩
https://github.com/yvesgurcan/deploy-lambda-function/blob/master/index.js#L34 ↩
https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html ↩
- 投稿日:2020-01-18T21:58:20+09:00
ActiveRecord::AdapterNotSpecified: 'production' database is not configured. が表示された場合
アセットコンパイル時に下記を実行するが
ターミナル(EC2)[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails assets:precompile RAILS_ENV=productionこの際にエラーが表示される場合がある。
エラーが出る場合
ActiveRecord::AdapterNotSpecified: 'production' database is not configured. Available: ["default", "development", "test", "database", "username", "password", "socket"]下記を修正してください
database.yamlに『 <<: *default 』を追記する
(もともとあるが、いらないだろうと思い消してしまうとエラーが表示される)config/database.ymlproduction: <<: *default # ここが抜けているはず database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %>追記したらpullして更新しましょう
ターミナル(EC2)[ec2-user@ip-172-31-23-189 <アプリ名>] git pull origin master再度
ターミナル(EC2)[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails assets:precompile RAILS_ENV=production今度は成功するはずです
- 投稿日:2020-01-18T20:44:40+09:00
配列の奇数の個数の取り出し
初めに
配列の中から奇数の個数を取り出す方法をわからなかった(odd?を初めて学んだ)ので記事にまとめました。
odd? メソッド
公式リファレンスによると
自身が奇数であれば真を返します。そうでない場合は偽を返します。
本題
[1, 2, 3, 4, 5, 6, 7] <= 配列 この中から奇数の個数4を取り出す1. eachメソッドで数を取り出す
2. 取り出した数の個数を出す
3. 条件分岐で奇数のみの個数を出す
この順番で考えます
1. eachメソッドで数を取り出す
def numbers(nums) nums.each do |num| puts num end end numbers([1, 2, 3, 4, 5, 6, 7]) # 出力結果 => 1 2 3 4 5 6 72. 取り出した数の個数を出す
def numbers(nums) count = 0 nums.each do |num| count += 1 #繰り返される度にcountが1増える end puts count end numbers([1, 2, 3, 4, 5, 6, 7]) # 出力結果 => 73. 条件分岐で奇数のみの個数を出す
def numbers(nums) count = 0 nums.each do |num| if num.odd? #numが奇数の時trueを返す count += 1 end end puts count end numbers([1, 2, 3, 4, 5, 6, 7]) # 出力結果 => 4無事に奇数のみを取り出すことができました。
逆に偶数のみ取り出したいときはeven?メソッドがあります
最後に
公式リファレンスを見ると知らないことがたくさんあるので定期的に見ることが大事だと思いました。
最後まで読んでくださってありがとうございます。
- 投稿日:2020-01-18T20:23:04+09:00
Can't connect to local MySQL server through socket '/tmp/mysql.sock'が表示された場合
AWSのEC2にデプロイしようとした際に、下記エラーが表示された場合の対処方法をまとめたいと思います。
『Can't connect to local MySQL server through socket '/tmp/mysql.sock'』原因
問題点としては、下記のsocketに接続できないのが問題
credentials.ymldb: database: アプリ名 username: root password: 設定したPW socket: /var/lib/mysql/mysql.sock #ここに接続ができないmysqlを再起動すると、/var/lib/mysql/mysql.sockが自動的に作成されるので、起動
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
1) MySQLの起動確認
Mysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'というエラーが起こった場合、mysqlが起動していない可能性があります。ターミナル(EC2)sudo service mysqld start #再起動をさせたい場合は、 sudo service mysqld restart改善があるか?確認
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (13)
database.ymlとcredentials.ymlの中身に漏れがないか確認をしてください
database.ymlにsocketの記述漏れがあれば、エラーがおきますcredentials.ymldb: database: アプリ名 username: root password: 設定したPW socket: /var/lib/mysql/mysql.sockconfig/database.ymlproduction: database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %> #ここのsocketが抜けていないか???
- 投稿日:2020-01-18T20:23:04+09:00
Can't connect to local MySQL server through socket '/tmp/mysql.sock'が表示された場合(本番環境)
AWSのEC2にデプロイしようとした際に、下記エラーが表示された場合の対処方法をまとめたいと思います。
『Can't connect to local MySQL server through socket '/tmp/mysql.sock'』原因
問題点としては、下記のsocketに接続できないのが問題
credentials.ymldb: database: アプリ名 username: root password: 設定したPW socket: /var/lib/mysql/mysql.sock #ここに接続ができないmysqlを再起動すると、/var/lib/mysql/mysql.sockが自動的に作成されるので、起動
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
1) MySQLの起動確認
Mysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'というエラーが起こった場合、mysqlが起動していない可能性があります。ターミナル(EC2)sudo service mysqld start #再起動をさせたい場合は、 sudo service mysqld restart改善があるか?確認
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (13)
database.ymlとcredentials.ymlの中身に漏れがないか確認をしてください
database.ymlにsocketの記述漏れがあれば、エラーがおきますcredentials.ymldb: database: アプリ名 username: root password: 設定したPW socket: /var/lib/mysql/mysql.sockconfig/database.ymlproduction: database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %> #ここのsocketが抜けていないか???
- 投稿日:2020-01-18T19:18:22+09:00
rails5.2のmaster.keyを本番環境(AWS EC2)に設定する方法
master.keyを作成していないとどうなるのか?
master.keyを本番環境で設定しておかなければ、rails db:create RAILS_ENV=productionなどを実行した際にエラーが表示される。
rails db:create RAILS_ENV=productionを実行
$ rails db:create RAILS_ENV=productionするとエラーが表示される
rails aborted! NoMethodError: Cannot load database configuration: undefined method `[]' for nil:NilClassこの'[]'はdatabase.ymlの下記が読み込めないために発生する。
database.ymlproduction: <<: *default database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %>'[]'は、[:database]、[:username]、[:password]、[:socket]が読み込めないことを意味している。
なぜ読み込めないのか?
credential.ymlの中身は他の人が閲覧できないように暗号化されている。
この暗号化を解除するのがmaster.key。
master.keyは扉を開ける鍵の役割をしており、鍵を使って解除しなければ、その先のデータを読み込むことができない。これは、本番環境でも同じです。
master.keyがなければ、暗号化を解除できないので、環境変数を読み込めずエラーとなる。本番環境のshared/configにmaster.keyを作成
ローカル環境にある,master.keyの中身を確認する
rails newで作成された、ローカルのmaster.keyを確認する。
$ vi config/master.keyすると下記のようにmaster.keyの中身が表示されます。
fadfdfdgaf44623535y....この表示された、master.keyの値をコピーしましょう
表示されたmaster.keyをコピーします。
これを本番環境で貼り付けていきます。本番環境でmaster.keyを作成
EC2のアプリのconfigを開きましょう
#本番環境 [ec2-user@ip-172-31-23-189 ~]$ cd /var/ここはそれぞれ違います/[アプリ名] [ec2-user@ip-172-31-23-189 <アプリ名>]$ cd configそうしたら、本番環境上でmaster.keyを作成します
[ec2-user@ip-172-31-23-189 config]$ vi master.key # ローカル環境のmaster.keyの値を入力 fsdgagaf08deg424~~~~~画像だと下記のような画面になります。
『 i 』を押すと----INSERT-----と表示がされて、文字入力ができます。
ここにコピーしたローカルのmaster.keyの値を貼り付けします。『 esc 』ボタンを押した後、:wq入力して保存します
これで本番環境でもmaster.keyが設定されています。
- 投稿日:2020-01-18T19:18:22+09:00
【rails5.2】master.keyを本番環境(AWS EC2)に設定する方法
master.keyを作成していないとどうなるのか?
master.keyを本番環境で設定しておかなければ、rails db:create RAILS_ENV=productionなどを実行した際にエラーが表示される。
rails db:create RAILS_ENV=productionを実行
$ rails db:create RAILS_ENV=productionするとエラーが表示される
rails aborted! NoMethodError: Cannot load database configuration: undefined method `[]' for nil:NilClassこの'[]'はdatabase.ymlの下記が読み込めないために発生する。
database.ymlproduction: <<: *default database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %>'[]'は、[:database]、[:username]、[:password]、[:socket]などの環境変数が読み込めないことを意味している。
なぜ読み込めないのか?
credential.ymlの中身は他の人が閲覧できないように暗号化されている。
この暗号化を解除するのがmaster.key。
master.keyは扉を開ける鍵の役割をしており、鍵を使って解除しなければ、その先のデータを読み込むことができない。これは、本番環境でも同じです。
master.keyがなければ、暗号化を解除できないので、環境変数を読み込めずエラーとなる。本番環境のshared/configにmaster.keyを作成
ローカル環境にある,master.keyの中身を確認する
rails newで作成された、ローカルのmaster.keyを確認する。
$ vi config/master.keyすると下記のようにmaster.keyの中身が表示されます。
fadfdfdgaf44623535y....この表示された、master.keyの値をコピーしましょう
表示されたmaster.keyをコピーします。
これを本番環境で貼り付けていきます。本番環境でmaster.keyを作成
EC2のアプリのconfigを開きましょう
#本番環境 [ec2-user@ip-172-31-23-189 ~]$ cd /var/ここはそれぞれ違います/[アプリ名] [ec2-user@ip-172-31-23-189 <アプリ名>]$ cd configそうしたら、本番環境上でmaster.keyを作成します
[ec2-user@ip-172-31-23-189 config]$ vi master.key # ローカル環境のmaster.keyの値を入力 fsdgagaf08deg424~~~~~画像だと下記のような画面になります。
『 i 』を押すと----INSERT-----と表示がされて、文字入力ができます。
ここにコピーしたローカルのmaster.keyの値を貼り付けします。『 esc 』ボタンを押した後、:wq入力して保存します
これで本番環境でもmaster.keyが設定されています。
- 投稿日:2020-01-18T19:18:22+09:00
【rails5.2】master.keyを本番環境(AWS EC2)に設定(追加作成)する方法
master.keyを作成していないとどうなるのか?
master.keyを本番環境で設定しておかなければ、rails db:create RAILS_ENV=productionなどを実行した際にエラーが表示される。
rails db:create RAILS_ENV=productionを実行
$ rails db:create RAILS_ENV=productionするとエラーが表示される
rails aborted! NoMethodError: Cannot load database configuration: undefined method `[]' for nil:NilClassこの'[]'はdatabase.ymlの下記が読み込めないために発生する。
database.ymlproduction: <<: *default database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %>'[]'は、[:database]、[:username]、[:password]、[:socket]などの環境変数が読み込めないことを意味している。
なぜ読み込めないのか?
credential.ymlの中身は他の人が閲覧できないように暗号化されている。
この暗号化を解除するのがmaster.key。
master.keyは扉を開ける鍵の役割をしており、鍵を使って解除しなければ、その先のデータを読み込むことができない。これは、本番環境でも同じです。
master.keyがなければ、暗号化を解除できないので、環境変数を読み込めずエラーとなる。本番環境のshared/configにmaster.keyを作成
ローカル環境にある,master.keyの中身を確認する
rails newで作成された、ローカルのmaster.keyを確認する。
$ vi config/master.keyすると下記のようにmaster.keyの中身が表示されます。
fadfdfdgaf44623535y....この表示された、master.keyの値をコピーしましょう
表示されたmaster.keyをコピーします。
これを本番環境で貼り付けていきます。本番環境でmaster.keyを作成
EC2のアプリのconfigを開きましょう
#本番環境 [ec2-user@ip-172-31-23-189 ~]$ cd /var/ここはそれぞれ違います/[アプリ名] [ec2-user@ip-172-31-23-189 <アプリ名>]$ cd configそうしたら、本番環境上でmaster.keyを作成します
[ec2-user@ip-172-31-23-189 config]$ vi master.key # ローカル環境のmaster.keyの値を入力 fsdgagaf08deg424~~~~~画像だと下記のような画面になります。
『 i 』を押すと----INSERT-----と表示がされて、文字入力ができます。
ここにコピーしたローカルのmaster.keyの値を貼り付けします。『 esc 』ボタンを押した後、:wq入力して保存します
これで本番環境でもmaster.keyが設定されています。
- 投稿日:2020-01-18T19:06:28+09:00
The asset "" is not present in the asset pipeline
assetへのパイプラインがうまくいってない時に起こるエラーです。
config/envitonments/production.rbで
config.assets.compile = trueをして、再起動してとりあえずうまく行かない時は、
<%= image_tag user.image.to_s %>みたいな記述をしていませんか。
特にbxsliderをお使いの初学者の方。
このままだとただの変数を入れているだけになるので
そういう場合は、<%= image_tag '/assets/user.jpg' %>みたいに「app/assets/images」ディレクトリに置いて呼び出すか。
refireのgemを使って呼び出せばうまく行きます。<%= f.attachment_field :image %>
- 投稿日:2020-01-18T18:47:34+09:00
独学ではじめてAWSのEC2にデプロイする方法⑨(Railsの起動)
ポートの解放
config/unicorn.rb に listen 3000 と記述しましたが、これはRailsのサーバを3000番ポートで起動するということを意味するのでした。
HTTPがつながるように「ポート」を開放する必要があります。手順
1.EC2を開く
2. 『実行中のインスタンス』を開く
3. インスタンスを選択
4. セキュリティグループの『launch-wizard-3』をクリック
5. 下記の画面が表示される
6.『 インバウンド 』を選択
7. 『 編集 』をクリック
8. 左下の『ルールの追加』をクリック
9. タイプ:「カスタムTCPルール」、プロトコルを「TCP」、ポート範囲を「3000」、送信元を「カスタム」「0.0.0.0/0」に設定
10. 画面左下の『 保存 』をクリックRailsの起動
Rails 5.1以前の場合
database.ymlに下記を追加します
config/database.yml(ローカル)production: <<: *default database: アプリ名 username: root password: <%= ENV['DATABASE_PASSWORD'] %> socket: /var/lib/mysql/mysql.sock追記が完了したら、EC2でも反映させます。
EC2とGithubは接続できているため、git pullコマンドを利用します。ターミナル(EC2)[ec2-user@ip-172-31-23-189 <アプリ名>] git pull origin masterデータベースの作成をする
ターミナル(EC2)[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails db:create RAILS_ENV=production Created database '<データベース名>'アプリのディレクトリを開いてからコマンドを実行しましょう
#うまくいかない = アプリ名を指定していない [ec2-user@ip-172-31-23-189 ~( ここが指定されていない )]$ rails db:create RAILS_ENV=production Created database '<データベース名>' #アプリ名(リポジトリ)を指定しているのでちゃんと処理がされる [ec2-user@ip-172-31-23-189 <アプリ名>]$ rails db:create RAILS_ENV=production Created database '<データベース名>'rails db:migrateを実行して、migrationを完了させる。
ターミナル(EC2)[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails db:migrate RAILS_ENV=productionエラーが出る場合
Mysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'というエラーが起こった場合、mysqlが起動していない可能性があります。
ターミナル(EC2)sudo service mysqld start #再起動をさせたい場合は、 sudo service mysqld restartというコマンドをターミナルから打ち込み、mysqlの起動を試してみましょう。
参考記事
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)ユニコーンを起動
[ec2-user@ip-172-31-23-189 ~]$ cd /var/www/[リポジトリ] [ec2-user@ip-172-31-23-189 <app名>]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -DRails5.2以降の場合
credentials.ymlの設定
ターミナル(ローカル)アプリ名 $ EDITOR=vim bin/rails credentials:editすると編集画面が表示されます。
しかし文字入力ができないので、
『 i 』を押して、----INSERT----モードに変更します下記を入力します。
credentials.ymldb: database: アプリ名 username: root password: 設定したPW socket: /var/lib/mysql/mysql.sockpasswordははじめてAWSでデプロイする方法⑤(EC2の環境構築、Ruby, MySQL)の『MySQLのrootパスワードの設定』で設定しています。
次に、database.ymlにcredential.ymlで設定した環境変数を記述します
config/database.ymlproduction: <<: *default database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %>本番環境のshared/configにmaster.keyを作成
ローカル環境にある,master.keyの中身を確認する
rails newで作成された、ローカルのmaster.keyを確認する。
$ vi config/master.keyすると下記のようにmaster.keyの中身が表示されます。
fadfdfdgaf44623535y....この表示された、master.keyの値をコピーしましょう
表示されたmaster.keyをコピーします。
これを本番環境で貼り付けていきます。本番環境でmaster.keyを作成
EC2のアプリのconfigを開きましょう
#本番環境 [ec2-user@ip-172-31-23-189 ~]$ cd /var/ここはそれぞれ違います/[アプリ名] [ec2-user@ip-172-31-23-189 <アプリ名>]$ cd shared/configそうしたら、本番環境上でmaster.keyを作成します
[ec2-user@ip-172-31-23-189 config]$ vi master.key # ローカル環境のmaster.keyの値を入力 fsdgagaf08deg424~~~~~画像だと下記のような画面になります。
『 i 』を押すと----INSERT-----と表示がされて、文字入力ができます。
ここにコピーしたローカルのmaster.keyの値を貼り付けします。『 esc 』ボタンを押した入力モードを終了
『 :wq 』入力して保存しますこれで本番環境でもmaster.keyが設定されています。
ユニコーンを起動
[ec2-user@ip-172-31-23-189 ~]$ cd /var/www/[リポジトリ] [ec2-user@ip-172-31-23-189 <app名>]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -Dエラーが発生した場合
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
Mysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'というエラーが起こった場合、mysqlが起動していない可能性があります。
ターミナル(EC2)sudo service mysqld start #再起動をさせたい場合は、 sudo service mysqld restartCan't connect to local MySQL server through socket '/tmp/mysql.sock' (13)
database.ymlとcredentials.ymlの中身に漏れがないか確認をしてください
credentials.ymldb: database: アプリ名 username: root password: 設定したPW socket: /var/lib/mysql/mysql.sockconfig/database.ymlproduction: <<: *default database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %> #ここのsocketが抜けていないか???サイトにアクセスしてみる
ブラウザで http://<サーバに紐付けたElastic IP>:3000/ にアクセスしてみましょう
ブラウザにCSSの反映されていない(ビューが崩れている)画面が表示されていれば成功です。アセットコンパイルする
レイアウトが崩れてしまっているでしょう。
開発中には正常に表示されていたのに、本番ではうまく表示されないのはなぜでしょうか?
これは、開発中はアクセス毎にアセットファイル(画像・CSS・JSファイルの総称)を自動的にコンパイル(圧縮)する仕組みが備わっていますが、本番モードのときにはパフォーマンスのためアクセス毎には実行されないようになっているためです。
ターミナル(EC2)[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails assets:precompile RAILS_ENV=production成功した場合Yarn executable was not detected in the system. Download Yarn at https://yarnpkg.com/en/docs/install I, [2020-01-18T12:51:01.4345644 #1265] INFO -- : Writing /var/app/web-share/public/assets/member_photo_noimage_thumb-224a733c50d48aba6d9fdaded809788bbeb5ea5f6d6b8368adaebb95e58bcf53.png I, [2020-01-18T12:51:02.2615123#1265] INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js I, [2020-01-18T12:51:02.2626434 #1265] INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js.gz I, [2020-01-18T12:51:08.484546 #1265] INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css I, [2020-01-18T12:51:08.485454 #1265] INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css.gzエラーが出る場合
ActiveRecord::AdapterNotSpecified: 'production' database is not configured. Available: ["default", "development", "test", "database", "username", "password", "socket"]下記を修正してください
config/database.ymlproduction: <<: *default # ここが抜けているはず database: <%= Rails.application.credentials.db[:database] %> username: <%= Rails.application.credentials.db[:username] %> password: <%= Rails.application.credentials.db[:password] %> socket: <%= Rails.application.credentials.db[:socket] %>追記したら
ターミナル(EC2)[ec2-user@ip-172-31-23-189 <アプリ名>] git pull origin master再度
ターミナル(EC2)[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails assets:precompile RAILS_ENV=production今度は成功するはずです
成功した場合Yarn executable was not detected in the system. Download Yarn at https://yarnpkg.com/en/docs/install I, [2020-01-18T12:51:01.4345644 #1265] INFO -- : Writing /var/app/web-share/public/assets/member_photo_noimage_thumb-224a733c50d48aba6d9fdaded809788bbeb5ea5f6d6b8368adaebb95e58bcf53.png I, [2020-01-18T12:51:02.2615123#1265] INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js I, [2020-01-18T12:51:02.2626434 #1265] INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js.gz I, [2020-01-18T12:51:08.484546 #1265] INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css I, [2020-01-18T12:51:08.485454 #1265] INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css.gzRailsの再起動
コンパイルが成功したら反映を確認するため、Railsを再起動します。しかし、まずは今動いているUnicornをストップします。
EC2のターミナルから以下のように入力します。「aux」と打っているのは、psコマンドのオプションです。表示結果を見やすくしてくれます。また、| grep unicornとしているのはpsコマンドの結果からunicorn関連のプロセスのみを抽出するためです。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn ec2-user 17877 0.4 18.1 588472 182840 ? Sl 01:55 0:02 unicorn_rails master -c config/unicorn.rb -E production -D ec2-user 17881 0.0 17.3 589088 175164 ? Sl 01:55 0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D ec2-user 17911 0.0 0.2 110532 2180 pts/0 S+ 02:05 0:00 grep --color=auto unicorn大事なのは左から2番目の列です。ここに表示されるのがプロセスのid、つまりPIDになります。
「unicorn_rails master」と表示されているプロセスがUnicornのプロセス本体です。この時のPIDは、17877となっています。[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill <確認したunicorn rails masterのPID>killコマンド:現在動いているプロセスを停止させるためのコマンドです
再度、プロセスを表示させ終了できていることを確認しましょう。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn ... ec2-user 17911 0.0 0.2 110532 2180 pts/0 S+ 02:05 0:00 grep --color=auto unicorn3つあった項目が一つになっています
では、Railsを起動させましょう!
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -Dもう一度、ブラウザで http://<Elastic IP>:3000/ にアクセスしてみましょう。今度はレイアウト崩れも無くサイトが正常に表示されていることでしょう。
参考
【Rails5.2】credentials.yml.encとmaster.keyでのデプロイによる今までとの変更点
【備忘録】credentials.yml.encにdatabase設定を保存する
- 投稿日:2020-01-18T18:05:47+09:00
content_tagでmodalやリンクを表示する
はじめに
RailsでWebサービスを構築していると、フロントのコードをサーバーサイドで実装する場面ってありますよね。(あんまりないか)
Railsにはcontent_tagというメソッドが用意されていて、フロントのコードをサーバーサイドで記述することができます。content_tag
content_tagの引数は以下のように構成されています。
- 第一引数: タグ
- 第二引数: 内容
- 第三引数: クラスなどのオプション
# divタグ生成 content_tag(:div, 'hoge', class: 'fuga') # => <div class="fuga">hoge</div>modalを表示するには
modal表示のサンプルです。
hoge_helper.rbdef show_modal_button content_tag(:a, class: 'btn btn-default form-control', data: { toggle: 'modal', target: '#hoge-modal' }) do concat render 'hoge-modal' concat 'モーダル表示' endhoge/_hoge_modal.html.haml.modal.fade#hoge-modal .modal-dialog .modal-content .modal-header %h4.modal-title Title! .modal-body hogehogefugafuga .modal-footer .btn.btn-default.data{ dismiss: 'modal' } 閉じるhoge/show.html.haml... .show-modal = show_modal_button ...リンクを作成する場合
content_tagはlink_toをそのまま扱えないので、以下のように書く必要があります。
fuga_helper.rbcontent_tag(a:, class: 'fuga', href: 'https://www.hoge.fuga.com') do concat 'hoge&fugaへのリンクです!'
- 投稿日:2020-01-18T18:01:35+09:00
Ruby on Rails使用時のデバッグで便利なメソッド
今日、久しぶりに使いたくなってなかなか思い出せなかったので念のためにQiitaにも書いておく。
そこそこの規模で開発していると、自分が今みているメソッドがどこから呼ばれているか分からない時たまにありませんか?
メタプログラミング的に書かれていたりしてgrepがなかなか上手くできないケースがあります。そういう時に便利なのがrubyの
caller
メソッド
https://magazine.rubyist.net/articles/0031/0031-BackTrace.html一旦pryで止めて、callerメソッドを実行するとその前に実行されていたメソッドの歴史が表示されるので、今見ているメソッドがどこから呼ばれているかすぐにわかります。
いやー、思い出せてスッキリ。
- 投稿日:2020-01-18T17:22:41+09:00
CentOS 8 で Ruby 2.5 から Ruby 2.6 へアップグレード(AppStream)
はじめに
Application Stream(AppStream)を利用してCentOS8にRuby2.6をアップグレードインストール
参考:ユーザー空間コンポーネントのインストール、管理、および削除 Red Hat Enterprise Linux 8 | Red Hat Customer Portalサポート
各Streamのサポート期間はRed Hat Enterprise Linux 8 Application Streams Life Cycle - Red Hat Customer Portalを参照。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。LOG
Ruby2.5(default)インストール
# cat /etc/redhat-release CentOS Linux release 8.1.1911 (Core) # yum install -y ruby ... 略 # ruby -v ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux]Stream切り替え
# yum distro-sync # yum module reset ruby # yum module enable ruby:2.6 # yum distro-sync # ruby -v ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
- 投稿日:2020-01-18T16:58:54+09:00
rubyでFizzBuzz問題を解いてみる
fizzbuzz問題とは
プログラミングの基礎的な技術力を測るために用いられる有名な問題らしい。
とあるプログラミングスクールで出題され、「こんなの簡単じゃん」と思い解き始めると、
全く解けなかったため、解説していきます。問題内容
1から100まで数を数える時に、3の倍数なら「fizz」、5の倍数なら「buzz」、ただし15の倍数なら「fizzbuzz」、それ以外はその数を答えるものです。
例)
1
2
Fizz
4
.
.これを実現するコードを記述しなさい。
ただし、elsifは使用せずに。
という問題回答
まずは、単純に1〜100を出力するコードを記載してみる。
sample.rbarray=[*1..100] puts arrayこれで、1〜100までを出力できました。
ここから、
3の倍数なら「fizz」、
5の倍数なら「buzz」、
15の倍数なら「fizzbuzz」、
を出力出来るように変更していく。まずはelsifありで、
each文↓sample.rbarray=[*1..100] array.each do |n| if n%15 == 0 puts "FizzBuzz" elsif n%3 == 0 puts "Fizz" elsif n%5 == 0 puts "Buzz" else puts n end endfor文↓
sample.rbarray=[*1..100] for n in array if n%15==0 puts "FizzBuzz" elsif n%3==0 puts "Fizz" elsif n%5==0 puts "Buzz" else puts n end endwhile文↓
sample.rbn=1 #nが100になるまで繰り返す while n <=100 if n%15==0 puts "FizzBuzz" elsif n%3==0 puts "Fizz" elsif n%5==0 puts "Buzz" else puts n end n +=1 endelsifを使用せずに回答↓
sample.rbn = 1 while n <= 100 str = "" if n % 3 == 0 #① 3で割り切れたらstrに"fizz"を代入 str = str + "fizz" end if n % 5 == 0 #② 5で割り切れたらstrに"buzz"を代入 str = str + "buzz" end #①と②の結果が共にtrueであれば、strは"fizzbuzz"になる(15の倍数) if str == "" str = str + n.to_s #①と②の結果が共にfalseであれば、strにnの数値を代入(3と5でも割り切れない) end puts str n += 1 end実行結果
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz . .elsifは使用せずに、という意地悪な問題でしたが、
rubyのアルゴリズムを組む上でif文の基本が詰まった良い問題だと思います。
- 投稿日:2020-01-18T16:29:54+09:00
CentOS 8にRuby 2.6をインストール(AppStream)
はじめに
Application Stream(AppStream)を利用してCentOS8にRuby2.6をインストール
参考:RHEL8のパッケージ構成 - BaseOSとApplication Stream - 赤帽エンジニアブログサポート
本手法で導入した場合、Red Hat Enterprise Linux 8 Application Streams Life Cycle - Red Hat Customer Portalより、2021-11がEOLだと思われる。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。LOG
インストール
# cat /etc/redhat-release CentOS Linux release 8.1.1911 (Core) # yum install -y @ruby:2.6/common ... 略各種確認
# which ruby /usr/bin/ruby # ruby -v ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux] # yum module info ruby:2.6 Failed to set locale, defaulting to C.UTF-8 Last metadata expiration check: 0:02:50 ago on Sat Jan 18 07:24:40 2020. Name : ruby Stream : 2.6 [e] [a] Version : 8010020191122185822 Context : cdc1202b Architecture : x86_64 Profiles : common [i] Repo : AppStream Summary : An interpreter of object-oriented scripting language Description : Ruby is the interpreted scripting language for quick and easy object-oriented programming. It has many features to process text files and to do system management tasks (as in Perl). It is simple, straight-forward, and extensible. Artifacts : ruby-0:2.6.3-106.module_el8.1.0+249+93480f15.i686 : ruby-0:2.6.3-106.module_el8.1.0+249+93480f15.src : ruby-0:2.6.3-106.module_el8.1.0+249+93480f15.x86_64 : ruby-debuginfo-0:2.6.3-106.module_el8.1.0+249+93480f15.i686 : ruby-debuginfo-0:2.6.3-106.module_el8.1.0+249+93480f15.x86_64 : ruby-debugsource-0:2.6.3-106.module_el8.1.0+249+93480f15.i686 : ruby-debugsource-0:2.6.3-106.module_el8.1.0+249+93480f15.x86_64 : ruby-devel-0:2.6.3-106.module_el8.1.0+249+93480f15.i686 : ruby-devel-0:2.6.3-106.module_el8.1.0+249+93480f15.x86_64 : ruby-doc-0:2.6.3-106.module_el8.1.0+249+93480f15.noarch : ruby-libs-0:2.6.3-106.module_el8.1.0+249+93480f15.i686 : ruby-libs-0:2.6.3-106.module_el8.1.0+249+93480f15.x86_64 : ruby-libs-debuginfo-0:2.6.3-106.module_el8.1.0+249+93480f15.i686 : ruby-libs-debuginfo-0:2.6.3-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-abrt-0:0.3.0-4.module_el8.1.0+249+93480f15.noarch : rubygem-abrt-0:0.3.0-4.module_el8.1.0+249+93480f15.src : rubygem-abrt-doc-0:0.3.0-4.module_el8.1.0+249+93480f15.noarch : rubygem-bigdecimal-0:1.4.1-106.module_el8.1.0+249+93480f15.i686 : rubygem-bigdecimal-0:1.4.1-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-bigdecimal-debuginfo-0:1.4.1-106.module_el8.1.0+249+93480f15.i686 : rubygem-bigdecimal-debuginfo-0:1.4.1-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-bson-0:4.5.0-1.module_el8.1.0+249+93480f15.src : rubygem-bson-0:4.5.0-1.module_el8.1.0+249+93480f15.x86_64 : rubygem-bson-debuginfo-0:4.5.0-1.module_el8.1.0+249+93480f15.x86_64 : rubygem-bson-debugsource-0:4.5.0-1.module_el8.1.0+249+93480f15.x86_64 : rubygem-bson-doc-0:4.5.0-1.module_el8.1.0+249+93480f15.noarch : rubygem-bundler-0:1.17.2-106.module_el8.1.0+249+93480f15.noarch : rubygem-did_you_mean-0:1.3.0-106.module_el8.1.0+249+93480f15.noarch : rubygem-io-console-0:0.4.7-106.module_el8.1.0+249+93480f15.i686 : rubygem-io-console-0:0.4.7-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-io-console-debuginfo-0:0.4.7-106.module_el8.1.0+249+93480f15.i686 : rubygem-io-console-debuginfo-0:0.4.7-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-irb-0:1.0.0-106.module_el8.1.0+249+93480f15.noarch : rubygem-json-0:2.1.0-106.module_el8.1.0+249+93480f15.i686 : rubygem-json-0:2.1.0-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-json-debuginfo-0:2.1.0-106.module_el8.1.0+249+93480f15.i686 : rubygem-json-debuginfo-0:2.1.0-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-minitest-0:5.11.3-106.module_el8.1.0+249+93480f15.noarch : rubygem-mongo-0:2.8.0-1.module_el8.1.0+249+93480f15.noarch : rubygem-mongo-0:2.8.0-1.module_el8.1.0+249+93480f15.src : rubygem-mongo-doc-0:2.8.0-1.module_el8.1.0+249+93480f15.noarch : rubygem-mysql2-0:0.5.2-1.module_el8.1.0+249+93480f15.src : rubygem-mysql2-0:0.5.2-1.module_el8.1.0+249+93480f15.x86_64 : rubygem-mysql2-debuginfo-0:0.5.2-1.module_el8.1.0+249+93480f15.x86_64 : rubygem-mysql2-debugsource-0:0.5.2-1.module_el8.1.0+249+93480f15.x86_64 : rubygem-mysql2-doc-0:0.5.2-1.module_el8.1.0+249+93480f15.noarch : rubygem-net-telnet-0:0.2.0-106.module_el8.1.0+249+93480f15.noarch : rubygem-openssl-0:2.1.2-106.module_el8.1.0+249+93480f15.i686 : rubygem-openssl-0:2.1.2-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-openssl-debuginfo-0:2.1.2-106.module_el8.1.0+249+93480f15.i686 : rubygem-openssl-debuginfo-0:2.1.2-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-pg-0:1.1.4-1.module_el8.1.0+249+93480f15.src : rubygem-pg-0:1.1.4-1.module_el8.1.0+249+93480f15.x86_64 : rubygem-pg-debuginfo-0:1.1.4-1.module_el8.1.0+249+93480f15.x86_64 : rubygem-pg-debugsource-0:1.1.4-1.module_el8.1.0+249+93480f15.x86_64 : rubygem-pg-doc-0:1.1.4-1.module_el8.1.0+249+93480f15.noarch : rubygem-power_assert-0:1.1.3-106.module_el8.1.0+249+93480f15.noarch : rubygem-psych-0:3.1.0-106.module_el8.1.0+249+93480f15.i686 : rubygem-psych-0:3.1.0-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-psych-debuginfo-0:3.1.0-106.module_el8.1.0+249+93480f15.i686 : rubygem-psych-debuginfo-0:3.1.0-106.module_el8.1.0+249+93480f15.x86_64 : rubygem-rake-0:12.3.2-106.module_el8.1.0+249+93480f15.noarch : rubygem-rdoc-0:6.1.0-106.module_el8.1.0+249+93480f15.noarch : rubygem-test-unit-0:3.2.9-106.module_el8.1.0+249+93480f15.noarch : rubygem-xmlrpc-0:0.3.0-106.module_el8.1.0+249+93480f15.noarch : rubygems-0:3.0.3-106.module_el8.1.0+249+93480f15.noarch : rubygems-devel-0:3.0.3-106.module_el8.1.0+249+93480f15.noarch Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled, [a]ctive
- 投稿日:2020-01-18T16:27:00+09:00
Railsチュートリアル第1章で勉強をブロックしたやつ
はじめに
この記事では私がRailsチュートリアルの第1章でつまづいた所を共有します。
個人的な備忘録ですが、プログラミング学習入門で人気のRailsなのでお役に立てればうれしいです!実行環境
AWS Cloud9を使用しました。チュートリアルの手順通りに環境設定しました。
問題
rails server
を実行し、アプリケーションをブラウザで開こうとしたところ、
まったく開きませんでした...解決策
色々調べた結果、ブラウザに導入していた広告ブロックが邪魔をしていました。広告ブロックを停止するとブラウザでRailsのウェルカム画面が無事表示されました。
また、下図のような表示がずっとでていましたが、EC2を再起動すれば解決しました。
こちらの記事が参考になります。
まとめ
広告ブロックはプログラミング学習以外では非常に便利ですが、プログラミング学習するときは常時切っておくほうがよいかもしれません。
- 投稿日:2020-01-18T15:08:20+09:00
Ruby で C言語の enum っぽく連番定数を作る
この場合の「enumっぽい」というのは、下の C コードのように単に「整数を連番で入れた定数を作りたい」程度の意味です。
enum { // 曜日ごとに順番に 1, 2, 3, .... が割り振られる SUNDAY = 1, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };Ruby では言語としては enum は用意されていないので、通常の方法では下のように1つ1つ定数を定義することになります。
module Foo SUNDAY = 1 MONDAY = 2 TUESDAY = 3 WEDNESDAY = 4 THURSDAY = 5 FRIDAY = 6 SATURDAY = 7 end曜日くらいならいいんですが、もっと大量の連番を作りたいときはこれでは大変ですね。
そんなわけで、Ruby でできるだけ手軽に enum っぽいことをする方法を考えてみました。
module Foo %i( SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY ).each.with_index(1){ |v, i| const_set(v, i) } # ruby2.7 なら { const_set(_1, _2) } でも行けますね endC の enum と違って途中から値を変更するということはできませんが、比較的手軽に実現できたのではないかと思います。もっとシンプルな方法があればぜひコメントお願いします。
- 投稿日:2020-01-18T13:23:23+09:00
【Sorcery】よく使うメソッドまとめ
はじめに
SorceryのGitHubに書いてあることを日本語でまとめました。
公式GitHubではメソッド名をクリックすると定義のページに飛びます。随時更新します。
メソッドについて・実際の使い方
require_login
ログインをしていないユーザーをアクション単位で弾く。
アクセスしようとしたURLをセッションに格納し、not_authenticated
を実行する。hoges_controller.rbbefore_action :require_loginアクションごとに変える場合は、
only: :action
を付ける。
アクション内の分岐など、もっと細かい単位で弾きたい場合は後述のlogged_in?
を使う。not_authenticated
先ほどの
require_login
が実行されたときに、このメソッドも実行される。
デフォルトではredirect_to root_path
と定義されているが、カスタマイズしたい場合はapplication_controllerで上書きをする。application_controller.rbclass ApplicationController < ActionController::Base protected def not_authenticated redirect_to login_url, danger: 'ログインしてください' end endcurrent_user
きっと一番よく使う。
現在ログイン中のUserを返す。コントローラ、ビューで使える。logged_in?
現在ログイン中かどうか、true or falseで返す。コントローラ、ビューで使える。
ログインしているかどうかによって場合分けをしたいときに使うことが多い。view.html.erb<% if logged_in? %> <%= link_to 'プロフィール', user_url(current_user) %> <% else %> <%= link_to 'ログイン', login_url %> <% end %>redirect_back_or_to(dafault_url, flash_hash = {})
ログインのアクションで使う。
require_login
のときにセッションに格納されたURLまたはデフォルトのURLにリダイレクトする。user_sessions_controller.rbclass UserSessionsController < ApplicationController def create @user = login(params[:email], params[:password]) if @user redirect_back_or_to root_url, success: 'ログインしました' else flash.now[:danger] = 'ログインに失敗しました' render :new end end end
- 投稿日:2020-01-18T13:04:28+09:00
Ruby 配列結合
- 投稿日:2020-01-18T12:15:25+09:00
#Ruby + Faker で 16進数 の Mac アドレスを生成する例
- 投稿日:2020-01-18T11:01:30+09:00
Bundler が Ruby 2.7 で変な件
Ruby 2.7 で Bundler がらみの不可解な現象に遭遇している。
前提
この記事で述べる実験は 2020-01-17 時点のもの。
Ruby 2.6.5 と Ruby 2.7.0 の二つについて実験を行った。
Windows と macOS と CentOS で実験した。
Windows は RubyInstaller for Windows でインストールしたもの。他は rbenv でインストール。Ruby 2.6.5 も 2.7.0 も,デフォルトの bundler gem は 2.1.2 だが,
gem update bundlerして,bundler 2.1.4 をインストールした。
したがって,どの OS,どの Ruby でも,2.1.2 と 2.1.4 が入った状態。実験 1
まず,OS と Ruby バージョンに関わらず,端末で
bundle -vとやったら
Bundler version 2.1.4と表示された(当然)。
次に,
gem list bundlerとやったときの結果が意外だった。
macOS と CentOS の Ruby 2.7.0 でだけ
bundler (2.1.4)と表示され,その他の OS,Ruby バージョンの組み合わせでは
bundler (2.1.4, default: 2.1.2)と表示されたのだ。後者のほうがしかるべき表示のような気がする。
Ruby のバージョンだけで違いが生じるなら「Ruby 2.7 で仕様が変わったのかな」と思うところだが,Windows の場合,バージョンによる違いはない。実験 2
以下のスクリプトを実行した。
gem "bundler" require "bundler" p Bundler::VERSIONすると,すべての組み合わせにおいて,「
"2.1.4"
」が表示された。
これは期待通り。
インストールされている最新版が require されるはずだから。実験 3
前の実験をちょっと改変して,
require "bundler" p Bundler::VERSIONとしてみた。
すると今度は,どの OS でも,Ruby 2.6.5 では「"2.1.4"
」と表示されるが,Ruby 2.7.0 では「"2.1.2"
」と表示される。
え? 最新版じゃない?これは何か Ruby 2.7 で仕様が変わったとした思えない。うーむ。
実験 4
まず,Gemfile に以下のようにだけ書く。
Gemfilesource "https://rubygems.org"(なんか gem を指定してもいいのだが,何も書かなくても実験は可能)
そして,コマンドライン上で
bundle checkする。
そうすると,Gemfile.lock が出来る。
Ruby 2.6.5 でやっても,Ruby 2.7.0 でやっても,その末尾にはBUNDLED WITH 2.1.4と書かれる。
これは納得できる話だ。実験 1 で,bundle コマンドは最新版である 2.1.4 が使われることを確認しているから。しかし,この状態で以下のスクリプトを動かすとどうなるか。
require "bundler" Bundler.requireRuby 2.6.5 では何事もなく終わるが,Ruby 2.7.0 ではドバドバっとメッセージが出る。
先頭はこれ。Warning: the running version of Bundler (2.1.2) is older than the version that created the lockfile (2.1.4). We suggest you to upgrade to the version that created the lockfile by running `gem install bundler:2.1.4`.これはエラーではなく警告。
「Gemfile.lock に書いとる(Bundler の)バージョンは 2.1.4 なのに,今走っとる Bundler は 2.1.2。古いやんけ」
と怒っているようだ。親切にも
「gem install bundler:2.1.4
ってやってアップグレードしたらよろし」
て suggest してくれてるのだが,もう入っとるっちゅーに。末尾はこれ。
/Users/hogehoge/.rbenv/versions/2.7.0/lib/ruby/2.7.0/rubygems.rb:275:in `find_spec_for_exe': Could not find 'bundler' (2.1.4) required by your /Users/hogehoge/temp/xxx/Gemfile.lock. (Gem::GemNotFoundException) To update to the latest version installed on your system, run `bundle update --bundler`. To install the missing version, run `gem install bundler:2.1.4`こっちは警告じゃなくてエラー。
「Gemfile.lock で要求されている bundler 2.1.4 が,み,見つからない」(がくっ)
という dying message を残して死亡している。これはどう解釈できるのか?
実験 3 の結果と整合的,という気はする。
Ruby 2.7.0 では単純に bundler を require すると,なぜか最新版ではなく 2.1.2 が読み込まれるのだった。実験 5
実験 4 と同じファイルを使い,
bundle exec ruby hoge.rbのような形でスクリプトを動かすと正常だった。
bundle exec
は,(よく分からんけど)Gemfile.lock の内容を見て使う gem のバージョンを決定してからスクリプトを動かすらしいので,これで正常化するのは納得できる気がする。ruby コマンドでなく,Rake タスクを実行したいときは要注意。
いままでrake hogeとやっていたのを
bundle exec rake hogeとするためには,Gemfile に
gem 'rake'
を入れてやらないといけない。対策
結局どうすればいいのか。
おそらく以下の二つしかないと思う。
bundle exec
を付けて実行require "bundler"
の前にgem "bundler"
を書く前者の場合,Rake タスクなら Gemfile を書き換える必要がある。確かめてはいないが Thor タスクでも同様だろう。
後者の場合も当然スクリプトを書き換える必要がある。既存のコードを大量に書き換えなければならないことになりそう。
え〜っ
- 投稿日:2020-01-18T07:38:50+09:00
スクリプト言語の比較しながらGoのお勉強 〜 環境構築編(MacOS)
ごあいさつ
はじめまして。@kuroseetsと申します。
2000年からフリーランスで仕事を始め開発12年、インフラ8年経験してきたオッサンです。
皆さんはどのプログラミング言語、スクリプト言語が好きですか?または仕事などで何をよく使っていますか?
開発をされている方だとJavaが多いのかな?またはC#?Ruby?PHP?
事務系でスクリプトを組む方などはVBScriptなども現役ですよね。
私は現在インフラ運用構築側にいますので、私を含めて周辺でよく使われているのが、Python, Ruby, Perl, Bash辺りが多く、最近ではさらにGolangが増えてきている印象です。(あくまで個人的主観で、ですよ
それぞれ好みはあるとは思いますが、環境や現場による制約で使えるもの使えないものがありまして、私もその都度現場でキャッチアップしてスキルを身に付けてきました。
現在ではInfrastructure as Code
と謳われるだけあって、構成管理の設定ファイル以外でも手を動かすことも増えてきたと身を以て感じています。
今回個人的にGolangを勉強しようと思っているのですが、折角なので勉強ついでに有名なスクリプト言語を比較してみようかなと思います。
対象はGolangの他、Python, Ruby, Perl, Bash(インフラ運用4強スクリプト!)を予定しています。
環境構築
使うからには最新版を使いたい!
ということで常に最新版をインストールしやすく、また管理しやすくするためにバージョン管理ツール越しにインタプリタをインストールすることにしました。anyenvのインストール
@rinpa さんの https://qiita.com/rinpa/items/81766cd6a7b23dea9f3c を参考にしてインストールしました。
各スクリプト言語を使用するのにenv系コマンドは非常に便利なのですが、個別にインストールすると面倒です。
が、anyenvで一元管理できたら非常に便利ですね。# anyenvインストール brew install anyenv # anyenvが実行できるか確認 anyenv --version # 初期ディレクトリがないので初期化して作成 anyenv install --init # インストールできるenv系コマンドの確認 anyenv install -l # 各envをインストール anyenv install goenv anyenv install pyenv anyenv install rbenv anyenv install plenv # 環境変数の設定 echo 'eval "$(anyenv init -)"' >> ~/.bash_profile source ~/.bash_profilegolang
golangの最新版のインストールはgoenvに従って粛々と進めていきます。
# インストール可能なgoのバージョンを確認 goenv install -l # 最新版をインストール(執筆時は1.13.6) goenv install 1.13.6 # インストールしたバージョンを指定 goenv global 1.13.6 # 指定したバージョンが実行できているか確認 go --versionpython
pythonも同様に最新版をインストールします。
# インストール可能なpythonのバージョンを確認 pyenv install -l # 最新版をインストール(執筆時は3.8.1) pyenv install 3.8.1 # インストールした最新版バージョンを指定 pyenv global 3.8.1 # 指定したバージョンが実行できているか確認 python --versionruby
rubyも同じ手順です。
# インストール可能なrubyのバージョンを確認 rbenv install -l # 最新版をインストール(執筆時は2.7.0) rbenv install 2.7.0 # インストールした最新版バージョンを指定 rbenv global 2.7.0 # 指定したバージョンが実行できているか確認 ruby --versionperl
そしてperlも。
# インストール可能なrubyのバージョンを確認 plenv install -l # stableの最新版をインストール(執筆時は5.30.1) plenv install 5.30.1 # インストールした最新版バージョンを指定 plenv global 5.30.1 # 指定したバージョンが実行できているか確認 perl --versionbash
anyenvにはbashのバージョンを管理するツールがありませんので、下記のツールを利用させて頂きました。
https://i-beam.org/2015/12/25/211817/サイトを参考にインストールしてみましたがエラーが出ました
git clone https://github.com/ueokande/bashvm ~/.bashvm echo 'source $HOME/.bashvm/bin/bashvm-init' >> ~/.bashrc source ~/.bashrc readlink: illegal option -- f usage: readlink [-n] [file ...]BSD系のMacは
readlink
に-f
オプションがないみたいですね
こちらを参考にreadlink -f
するコマンドを作成
https://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-maccat << 'EOF' > /usr/local/bin/readlinkf #!/bin/sh TARGET_FILE=$1 cd `dirname $TARGET_FILE` TARGET_FILE=`basename $TARGET_FILE` # Iterate down a (possible) chain of symlinks while [ -L "$TARGET_FILE" ] do TARGET_FILE=`readlink $TARGET_FILE` cd `dirname $TARGET_FILE` TARGET_FILE=`basename $TARGET_FILE` done # Compute the canonicalized name by finding the physical path # for the directory we're in and appending the target file. PHYS_DIR=`pwd -P` RESULT=$PHYS_DIR/$TARGET_FILE echo $RESULT EOF chmod 755 /usr/local/bin/readlinkf
readlink -f
しているところをこのコマンドに置き換えます--- bashvm-init.bak 2020-01-18 07:08:43.000000000 +0900 +++ bashvm-init 2020-01-18 07:09:30.000000000 +0900 @@ -124,7 +124,7 @@ export -f bashvm export BASHVM_HOME=${BASHVM_HOME:-$HOME/.bashvm} -PATH="$(readlink -f $(dirname $BASH_SOURCE)):$PATH" +PATH="$(readlinkf $(dirname $BASH_SOURCE)):$PATH" test -f $BASHVM_HOME/config && source $BASHVM_HOME/config export bashvm_default_version=${bashvm_default_version:-system}改めて
source ~/.bashrc
を実行すると成功しました
ではbashの最新版をインストールします# 執筆次の最新は5.0 bashvm install 5.0 # インストールした最新版バージョンを指定 bashvm use 5.0 # 指定したバージョンが実行できているか確認 bash --version
以上で構築作業は完了です。
次回から各言語を比較しながらプログラミングしていきます。
- 投稿日:2020-01-18T07:01:35+09:00
Rails Tutorial 第一章でつまづいたところと参考URL(簡易メモ)
○所要時間
とりあえず一読 → 2:30(現在合計2:30)
一読後手を動かして → 4:00(現在合計4:00)
合計6:30・cloud9初期設定迷う
→初期設定から変更なしでOK
参考URL:https://note.com/yutsuku/n/ncb752afcc61f・rails server 起動できない(rails serverが弾かれる)
javascriptをダウンロード(具体的には、vi Gemfile→最後に「gem 'therubyracer'」を追記)
参考URL:http://yso15.hatenablog.com/entry/2015/03/21/225843かつ、cd ~/environment/hello_app でディレクトリ の移動後、rails serverを起動。
・rais serverってどうやって開けば(確認すれば)いいの?
ページの表示方法は以下
0.画面上部tools→preview(これ以外下記参考URL引用)
1. $ rails serverでサーバを起動する(上記の結果でOK)
2. 画面上部Preview → Preview Running Application をクリック
3. cloud9上にブラウザが表示されるので、アドレスバーの右にあるボタンをクリック
4. ページが表示される。
参考URL:https://qiita.com/iwato/items/c70eeb87f944043ba356・Gitでユーザを確認する方法
git config --global --list
Gitユーザを切り替える方法
XXXXのところは自分のユーザ名とメールアドレスに置き換えてください。
git config --global user.name XXXXX
git config --global user.email xxxx@xxxx.xxx
参考URL:http://javatechnology.net/service/git-config-global-list-user/・git公開鍵のbitbucketへの登録
1.公開鍵が作成されているか確認する
$ cat ~/.ssh/id_rsa.pub
2.公開鍵を作成する
$ cd ~/.ssh
$ ssh-keygen
(ssh-keygenでAWS上の/var/lib/jenkins/.sshに公開鍵、秘密鍵を作るでした。)
参考URL:https://teratail.com/questions/48406→ssh key imageなるもの(The key's randomart image)ができてこれは使えなかった→cat id_rsa.pubで確認すると、ssh-rsaで始まるものが出てきて、これはbitbucketでsshkeyとして使えた。
参考URL:https://note.com/yutsuku/n/ncb752afcc61f・bitbucket登録後、Bitbucketへのリポジトリ追加とリポジトリへのプッシュ
$ cd ~/environment/hello_app(この移動大事)(要はhello_appのマスターブランチで以下コマンドを行うということ)
$ git remote add origin git@bitbucket.org:アカウント名/hello_app.git
$ git push -u origin master
参考URL:https://note.com/yutsuku/n/ncb752afcc61f・$ bundle install --without production
→"Gemfile could no locate"のエラー
→hello_app(master)に移動して実行
- 投稿日:2020-01-18T02:04:54+09:00
Rubyのコロン:の位置がわかるようになる記事
RubyやRailsを書いていると:が前に来たり、後ろついたりとてもややこしくありませんか??
というわけで:を前に書く時と後ろに書くときのパターンについて、整理していきたいと思います。後置:パターン。
test.rb#ハッシュのキーをシンボルとして定義 hash = { a: 1, b: 2, c: 3 } #キーワード引数(シンボルとは異なる)を利用するパターン def my_method(arg1: arg:2) pp arg1, arg2 end以上の2パターンが後置:です。
では前置:のパターンをみていきましょう。
前置:パターン
test.rb#その他はすべて後置:です。 hash[:a] = 4なんと上記の2つ以外はすべて後置:です。
こうやって整理してみると意外とシンプルなものですね〜
- 投稿日:2020-01-18T00:37:52+09:00
ruby 2.7.0 + Rails 5.2.4 + mysql 5.7.28 でDocker開発環境を構築する備忘録
流れ
- Dockerfileを作成
- docker-compose.ymlを作成
- Gemfile,Gemfile.lockを作成
- イメージ・コンテナの作成
- Rails初期設定
- Githubにリモートリポジトリ作成
ディレクトリ構成
application_root/ - Dockerfile - docker-compose.yml - Gemfile - Gemfile.lock - その他Railsアプリケーションファイル群Dockerfileを作成
application_root下に下記のファイルを作成
# イメージのベースラインにRuby2.7.0を指定 FROM ruby:2.7.0 # Railsに必要なパッケージをインストール RUN apt-get update -qq && apt-get install -y build-essential nodejs RUN gem install bundler # ルートディレクトリを作成 RUN mkdir /app # 作業ディレクトリを指定 WORKDIR /app # ローカルのGemfileとGemfile.lockをコピー COPY ./Gemfile /app/Gemfile COPY ./Gemfile.lock /app/Gemfile.lock # Gemのインストール実行 RUN bundle install # カレントディレクトリの内容をコピー COPY . .docker-compose.ymlを作成
同様に下記のファイルを作成。
DBはmysqlで、ローカルにデータストアを設けて永続化している。# docker-compose.ymlフォーマットのバージョン指定 version: '3' services: # Railsコンテナ定義 web: # Dockerfileを使用してイメージをビルド build: . # ポート3000が来たらrailsサーバーが応答 command: bundle exec rails s -p 3000 -b '0.0.0.0' # ローカルのsrcをコンテナにマウント volumes: - .:/app ports: - 3000:3000 # dbコンテナが先に起動するよう設定 depends_on: - mysql tty: true stdin_open: true # MySQLコンテナ定義 mysql: # mysqlを使用してコンテナ作成 image: mysql:5.7.28 volumes: # データストアからマウント - ./tmp/mysql:/var/lib/mysql # コンテナ内の環境変数を定義 environment: # mysqlのルートユーザーのパスワード設定 MYSQL_ROOT_PASSWORD: password ports: - "3306:3306" restart: alwaysGemfile,Gemfile.lockの作成
以下のコマンドでGemfileを作成。
bundle init下記のように編集。
# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "rails", "~> 5.2.4"Gemfile.lockは空で作成しておく。
touch Gemfile.lockイメージ・コンテナの作成
Railsプロジェクトを作成する。
docker-compose run web rails new . --force --database=mysqlDockerイメージを作成する。(で合っているよね?)
docker-compose build作成されたイメージを確認できる。
コンテナはまだない。# イメージのリスト docker image list # 動作しているコンテナ一覧 docker psここまでがうまくいかなかった時は削除してやり直す。
docker rm -f [container_id] docker rmi -f [image_id]いよいよコンテナを立ち上げる。
-dをつけるとデーモン実行できるが、ログを見たいのでそのまま実行。docker-compose upRails初期設定
config/database.ymlのpassword, hostを編集する。
default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password # docker-compose.ymlに記載したパスワード host: mysql # docker-compose.ymlに記載したホスト名コンテナ内に入って、DBを作成する。
docker exec -it [container_name] bash rake db:create下記URLで動作が確認できる。
http://localhost:3000Github設定(ついでに)
Githubアカウントは作ってある前提で・・・
まずはSSHキーを作成。もうある場合は不要。
内容をGithubの設定から、SSH keysにアップロードする。ssh-keygen -t rsa cat .ssh/id_rsa.pubあとはリモートリポジトリのSSHアドレスを設定してPush。
# ユーザー名の設定 git config --global user.name [ユーザー名] # リモートリポジトリの設定 git remote add origin git@github.com:xxxxxxxx/xxxxxxxxx.git # アプリケーションの初期状態をPush git add -A git commit -m "create application" git push origin master