Ruby on Rails Background Job処理サーバの作成


始まる前に


ここで紹介する項目はRuby on Rails、Puma、Casperato、Sidekiq、aws EC 2、aws RDSを使用し、生産環境に基づいて作成されています.
Sidekiqイメージアップロードキュー内のworkerのみを処理するworker-image、非キュー内のworker-general、および2つの新しいサーバを作成することを目的としています.
(原記事の作成時期は2021年2月23日、Postingでの説明に従って行ったのですが、ちょっとしたミスがあったので、もう少し設定に触れた覚えがありますが、何の部分か覚えていないので追加できません😭 個人的な記録のために書かれたスペースですが、この文章を読んでいる人がいたら、その点を考えてみてください.)

aws-cliを使用してインスタンスの画像を作成(AMI)


configファイルの設定


aws-cliがインストールされていない場合は、インストールガイドに従ってaws-cli(バージョン2.x)をインストールします.
インストール後に作成されます.awsフォルダにconfigというファイルを次のように設定します.
> vi .aws/config

[default]
region=ap-northeast-2
output=json
この場合、regionの場合、AMIを作成する対応するインスタンスが存在する必要があります.

AMIの作成


端末に以下のように入力して実行すると、新しく作成したAMIのIDがjson形式で返される.
> aws ec2 create-image \
  --instance-id i-EXAMPLE_INSTACE_ID \
  --name "for-worker-server" \
  --no-reboot
作成したAMIは保留中です.次のフェーズに進むには、使用可能なステータスのみですが、ステータスの変更には時間がかかる場合があります.

Terraformを使用してaws EC 2インスタンスを作成する


Terraformファイルの作成

provider "aws" {
  access_key = "EXAMPLE_ACCESS_KEY"
  secret_key = "EXAMPLE_SECRET_KEY"
  region = "ap-northeast-2" # AMI가 존재하는 region과 같아야 한다
}

resource "aws_instance" "web" {  
  count = 2 # 지정한 숫자 만큼의 instance가 생성되며 count가 없을 경우는 자동으로 1로 설정된다
  ami = "ami-EXAMPLE_AMI"
  instance_type = "t2.medium"
  key_name = "EXAMPLE_KEY_NAME"
  vpc_security_group_ids = [
    "sg-EXAMPLE_SG"
  ]
  connection {
    user = "ubuntu"
    type = "ssh"
    host = self.public_ip
    private_key = file("~/.ssh/id_rsa")
    timeout     = "2m"
  }
}
以上のように.tfファイルを作成したら、次のコマンドを使用して実行します.(ただしterraform initの場合、以前に実行した場合はスキップします.)
> terraform init
> terraform plan
> terraform apply
この場合、同じ設定でインスタンスを作成した場合、以前に作成したインスタンスが削除される可能性がありますので、Terraform planの後に生成されたメッセージをよく確認してください.

上図のように、N to add、0 to destroyと確認した方が良いです.

RDSをEC 2インスタンスに関連付ける


RDSコンソールで使用中のRDSインスタンスを選択し、[接続とセキュリティ]タブでVPCセキュリティグループを検証します.次のようになります.

EC 2コンソールからセキュリティグループページにアクセスした後、RDSコンソールで確認したのと同じセキュリティグループを選択します.

Edit Inbound rulesをクリックして、Terraformで作成したEC 2インスタンスを含むセキュリティグループに設定します.

Cascaderano設定


config/deploy.rbに次の内容を追加します.
set :sidekiq_roles, %w{EXAMPLE_ROLE_1 EXAMPLE_ROLE_2}
config/deploy/production.rbに次の内容を追加します.
server 'PUBLIC_IP', user: 'EXAMPLE_USER', roles: 'EXAMPLE_ROLE_1'
server 'PUBLIC_IP', user: 'EXAMPLE_USER', roles: 'EXAMPLE_ROLE_2'

Sidekiq設定


各サーバのsidkiq.yml, sidekiq.confファイルは個別に作成されます.サーバに接続し、以下にsidkiqを示します.ymlファイルを作成または変更します.
> vi EXAPLE_PROJECT/shared/config/sidekiq.yml

...
:roles: :EXAMPLE_ROLE
...
:queues:
...
  - EXAMPLE_QUEUE
sidekiq.yml(config.yml)ファイルの形式はリンクで表示できます.
パスを移動し、sidekiq.confファイルを生成した後、以下のように変更します.
> vi /etc/init/sidekiq.conf

...
  exec bundle exec sidekiq -C shared/config/sidekiq.yml -e production
EOT

Nginxエラーが発生した場合の解決方法


接続されたNginx Defaultページが表示されたら



上の画像は、Nginx Defaultページ画面です.
生成されたEC 2インスタンスの共通IPアドレスに接続すると、上記のNginxのdefault画面が表示された場合、default configurationファイルを削除してcustomファイルを残すだけでこの問題を解決できます.
生成されたEC 2インスタンスは2つあるため、sshで1つずつ接続して削除するのは難しいため、Playbookを作成してAnableを実行します.

---

- hosts: all 
  become: true
  become_method: sudo
  become_user: root

  tasks:
    - name: check whether default in nginx is exist
      stat:
        path: /etc/nginx/sites-available/default
      register: default

    - name: remove default nginx
      command: zsh -lc "rm default"
      args: 
        chdir: /etc/nginx/sites-available
      when: default.stat.exists
    
    - name: unlink default nginx
      command: zsh -lc "unlink default"
      args: 
        chdir: /etc/nginx/sites-enabled
      when: default.stat.exists

    - name: restart nginx
      service: 
        name: nginx
        state: restarted
> ansible-playbook -i INVENTORY_FILE EXAMPLE_PLAYBOOK.yaml
Anableを使用せずに直接削除する場合は、まずsshを使用してサーバに接続します.
次にnginx sites-availableに存在するdefaultファイルを削除します.
> cd /etc/nginx/sites-available
> rm default
システムリンクも削除されます.
> cd /etc/nginx/sites-enabled
> unlink default
最後に、Nginxを再起動します.
> sudo service nginx restart

Nginx 502 Bad Gatewayエラーが発生しました


Pumaが開いていない可能性が高いです.以下のコマンドをローカルで実行します.
> bundle exec cap production puma:restart
サーバに接続し、Nginxを再起動します.
> sudo service nginx restart