結論
gem 'irb', require: false
がある状態で、
eb ssh
して、rails cするならこう。
sudo su -c 'env $(cat /opt/elasticbeanstalk/deployment/env | xargs) su webapp -c "cd /var/app/current ; bundle exec rails c"'
じゃなくて必要な環境変数を持った状態でwebappユーザになるだけならこう。
sudo su -c 'env $(cat /opt/elasticbeanstalk/deployment/env | xargs) su webapp'
Gemfileについて
ここはちょっと自信がない部分。
Ruby2.5までは明示しなくてもirbが利用できたけど、2.6以降はGem化されたらしく、使用するのであれば明示的に書いておく必要があるらしい。
ただ、アプリケーションとして必要なわけではないことが多いはずなので、require: falseとしています。
コマンドの説明
以前までの手順よりも大幅ブラッシュアップのワンライナーで登場です。
以前のものも同様に書き換えることはできるんですが、今後需要がなくなって行くと思うのでそのままにしておきます。
ちなみにAL2ではrbenvでrubyのバージョンが管理されていましたがAL2023ではalternativesになったようです。
なんでなのかは謎です。
あ、eb sshについては説明しませんのであしからず。
要素を分解していくと案外簡単な構造です。
sudo su -c 'XXX`
AL2023にログインした直後のec2-userは直接suを実行できないので、sudoを経由してsuを実行しています。
ユーザを省略しているのでrootユーザになろうとしています。
-c 'XXX'は指定ユーザでXXXを実行するというオプションになります。
XXX部分は少々長く、
env $(cat /opt/elasticbeanstalk/deployment/env | xargs) su webapp -c "cd /var/app/current ; bundle exec rails c"
となっていますが、展開後の構文的には
env A=1 B=2 C=3 su webapp -c "YYY"
のような形になっていて、環境変数を指定しつつコマンドの実行をしています。
実行しているコマンドは先程とほぼ同じですが、webappユーザでコマンドYYYを実行することになります。
環境変数の部分は直接コマンドを入力する場合にはenvがなくても問題ありませんが、コマンド実行した結果の展開($())を利用するため、明示する必要があります(多分)
/opt/elasticbeanstalk/deployment/envにはElastic Beanstalk環境に設定されている環境変数が1行に1つずつ
A=1
B=2
C=3
のような形で定義されています。
これをcatしてxargsを通すことで
cat /opt/elasticbeanstalk/deployment/env | xargs
A=1 B=2 C=3
という結果を得ることができます。
最後のYYY部分については簡単です。
cd /var/app/current ; bundle exec rails c
コマンドの連続実行になっていますが、アプリケーションルートに移動し、rails cです。
-
rootユーザで- 環境変数を設定しつつ
-
webappユーザで- アプリケーションを実行
という感じですね。
Railsが起動するまでの流れ
できる限り本来のアプリケーションが起動するのと同じものを利用してrails cしたかったのでなんとなーく、動作を追ってみたのでその記録として。
一部、想像も入ってます。
Procfile
アプリケーションルートのProcfileが使われます。
存在しない場合はデフォルト設定で起動するようですが、デフォルト設定はEBとして動作確認されているので同じ内容にしています。
web: bundle exec puma -C /opt/elasticbeanstalk/config/private/pumaconf.rb
systemctlのweb.service
おそらくProcfileを元にしてこのファイルが作られてる・・・と思います。
Procfileのprocess typeに指定してある部分を持ってきてXXX.serviceに、起動用のcommand部分をExecStart=/bin/sh -c "XXX"部分に埋め込んでる・・・んじゃないかな・・・
で、この中で実行ユーザがwebappであり、環境変数が記載されたファイルは/opt/elasticbeanstalk/deployment/envであることが明示されています。
[Unit]
Description=This is web daemon
PartOf=eb-app.target
[Service]
User=webapp
Type=simple
ExecStart=/bin/sh -c "bundle exec puma -C /opt/elasticbeanstalk/config/private/pumaconf.rb"
ExecStartPost=/bin/sh -c "systemctl show -p MainPID web.service | cut -d= -f2 > /var/pids/web.pid"
ExecStopPost=/bin/sh -c "rm -f /var/pids/web.pid"
Restart=always
EnvironmentFile=/opt/elasticbeanstalk/deployment/env
SyslogIdentifier=web
WorkingDirectory=/var/app/current/
[Install]
WantedBy=multi-user.target
環境変数
こんな感じでずらーっと書かれてます。
RAILS_SKIP_MIGRATIONS=false
AWS_REGION=ap-northeast-1
BUNDLE_WITHOUT=test:development
:
:
pumaconf.rb
でPumaの設定がこれ。
アプリケーションルートが/var/app/currentであることが明示されてます。
directory '/var/app/current'
threads 8, 32
workers %x(grep -c processor /proc/cpuinfo)
bind 'unix:///var/run/puma/my_app.sock'
config.ru
Pumaの設定にrackupの指定がないため、デフォルトのconfig.ruが参照され、ここからRuby・・・というかRailsが起動を始めていきます。
# This file is used by Rack-based servers to start the application.
require_relative 'config/environment'
run Rails.application
Amazon Linuxの表記揺れ吸収用
AmazonLinux
Amazon Linux
AL2
AmazonLinux2
AmazonLinux 2
Amazon Linux 2
AL2023
AmazonLinux2023
AmazonLinux 2023
Amazon Linux 2023