带有 AWS Elastic Beanstalk 问题的瘦服务器

Thin server with AWS Elastic Beanstalk issue

我正在尝试将使用瘦服务器的 Sinatra 应用程序从 Heroku 迁移到 AWS Elastic Beanstalk。目前的问题是 Nginx 正在寻找 Puma 服务器而不是 Thin:

connect() to unix:///var/run/puma/my_app.sock failed (2: No such file or directory)

是否可以使用 Thin AWS Elastic Beanstalk?

我能够使用以下文件在 AWS Elastic Beanstalk 上获得瘦服务器 运行。关闭 Puma 服务器尚未生效。

.ebextensions_nginx.config

commands:
  create_post_dir:
    command: "mkdir /opt/elasticbeanstalk/hooks/appdeploy/post"
    ignoreErrors: true

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/00_set_permissions.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user)
      su -s /bin/bash -c "mkdir -p /var/run/thin"
      su -s /bin/bash -c "mkdir -p /var/log/thin"
      chown -R $EB_APP_USER:$EB_APP_USER /var/run/thin
      chown -R $EB_APP_USER:$EB_APP_USER /var/log/thin

  "/etc/nginx/conf.d/02_app_server.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      # The content of this file is based on the content of /etc/nginx/conf.d/webapp_healthd.conf

      upstream my_app_new {
        least_conn;
        server unix:///var/run/thin/thin.0.sock;
        server unix:///var/run/thin/thin.1.sock;
      }

      log_format healthd_new '$msec"$uri"'
                      '$status"$request_time"$upstream_response_time"'
                      '$http_x_forwarded_for';

      server {
        listen 80;
        server_name _ localhost; # need to listen to localhost for worker tier

        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
          set $year ;
          set $month ;
          set $day ;
          set $hour ;
        }

        access_log  /var/log/nginx/access.log  main;
        access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd_new;

        location / {
          proxy_pass http://my_app_new; # match the name of upstream directive which is defined above
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /assets {
          alias /var/app/current/public/assets;
          gzip_static on;
          gzip on;
          expires max;
          add_header Cache-Control public;
        }

        location /public {
          alias /var/app/current/public;
          gzip_static on;
          gzip on;
          expires max;
          add_header Cache-Control public;
        }

        client_max_body_size 0;
      }

  "/opt/elasticbeanstalk/support/conf/pumaconf.rb":
    mode: "000644"
    owner: root
    group: root
    content: |
      directory '/var/app/current'
      threads 0
      workers 0
      bind 'unix:///var/run/puma/my_app.sock'
      pidfile '/var/run/puma/puma.pid'
      stdout_redirect '/var/log/puma/puma.log', '/var/log/puma/puma.log', true
      daemonize false

  "/opt/elasticbeanstalk/hooks/appdeploy/post/99_start_rhoconnect.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      # Loading environment data
      EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user)
      EB_APP_DEPLOY_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir)
      EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
      EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir)
      # Setting up correct environment and ruby version so that bundle can load all gems
      . $EB_SUPPORT_DIR/envvars
      . $EB_SCRIPT_DIR/use-app-ruby.sh
      # Stop Puma
      # su -s /bin/bash -c "pumactl -P /var/run/puma/puma.pid stop" $EB_APP_USER
      # Now we can do the actual restart of the server. Make sure to have double quotes when using env vars in the command.
      cd $EB_APP_DEPLOY_DIR
      FILE=/var/run/thin/thin.pid
      if [ -f "$FILE" ]; then
          su -s /bin/bash -c "RACK_ENV=production bundle exec thin restart -R config.ru -e production -p 9292 -C config/thin.yml" $EB_APP_USER
      else
          su -s /bin/bash -c "RACK_ENV=production bundle exec thin start -R config.ru -e production -p 9292 -C config/thin.yml" $EB_APP_USER
      fi

container_commands:
  01_reload_nginx:
    command: "sudo service nginx reload"
  02_remove_webapp_healthd:
    command: "rm -f /opt/elasticbeanstalk/support/conf/webapp_healthd.conf /etc/nginx/conf.d/webapp_healthd.conf"

config\thin.yml:

---
chdir: /var/app/current
environment: production
address: 0.0.0.0
port: 3000
timeout: 30
log: /var/log/thin/thin.log
pid: /var/run/thin/thin.pid
max_conns: 1024
max_persistent_conns: 512
require: []
wait: 30
threadpool_size: 20
daemonize: true
socket: /var/run/thin/thin.sock
servers: 2

.ebextensions\tail-logs.config

files:
 "/opt/elasticbeanstalk/tasks/taillogs.d/cloud-init.conf" :
  mode: "000755"
  owner: root
  group: root
  content: |
    /var/log/thin/thin.0.log
    /var/log/thin/thin.1.log

除了@user2666194的精彩回答外,我发现EB会抱怨由于应用程序不是运行而处于降级状态运行。

似乎 healthd 检查 /var/elasticbeanstalk/healthd/application.pid 中列出的 pid 以确保应用程序是 运行。默认情况下链接到 /var/run/puma/puma.pid.

为了解决这个问题,我修改了 01_nginx.config 文件以删除并替换此 pid。我还添加了 initctl 命令来停止 puma。现在我们正在检查正确的 pid,这似乎没有不良影响:

commands:
  create_post_dir:
    command: "mkdir /opt/elasticbeanstalk/hooks/appdeploy/post"
    ignoreErrors: true
files:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/00_set_permissions.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user)
      su -s /bin/bash -c "mkdir -p /var/run/thin"
      su -s /bin/bash -c "mkdir -p /var/log/thin"
      chown -R $EB_APP_USER:$EB_APP_USER /var/run/thin
      chown -R $EB_APP_USER:$EB_APP_USER /var/log/thin
  "/etc/nginx/conf.d/02_app_server.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      # The content of this file is based on the content of /etc/nginx/conf.d/webapp_healthd.conf

      upstream my_app {
        least_conn;
        server unix:///var/run/thin/thin.0.sock;
        server unix:///var/run/thin/thin.1.sock;
      }

      log_format healthd '$msec"$uri"'
                      '$status"$request_time"$upstream_response_time"'
                      '$http_x_forwarded_for';

      server {
        listen 80;
        server_name _ localhost; # need to listen to localhost for worker tier

        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
          set $year ;
          set $month ;
          set $day ;
          set $hour ;
        }

        access_log  /var/log/nginx/access.log  main;
        access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;

        location / {
          proxy_pass http://my_app; # match the name of upstream directive which is defined above
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
          # Application is 180, this is overhead
          proxy_read_timeout 200s;
        }

        location /assets {
          alias /var/app/current/public/assets;
          gzip_static on;
          gzip on;
          expires max;
          add_header Cache-Control public;
        }

        location /public {
          alias /var/app/current/public;
          gzip_static on;
          gzip on;
          expires max;
          add_header Cache-Control public;
        }

        client_max_body_size 0;
      }

  "/opt/elasticbeanstalk/support/conf/pumaconf.rb":
    mode: "000644"
    owner: root
    group: root
    content: |
      directory '/var/app/current'
      threads 0
      workers 0
      bind 'unix:///var/run/puma/my_app.sock'
      pidfile '/var/run/puma/puma.pid'
      stdout_redirect '/var/log/puma/puma.log', '/var/log/puma/puma.log', true
      daemonize false

  "/opt/elasticbeanstalk/hooks/appdeploy/post/99_start_thin.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      # Loading environment data
      EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user)
      EB_APP_DEPLOY_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir)
      EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
      EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir)
      # Setting up correct environment and ruby version so that bundle can load all gems
      . $EB_SUPPORT_DIR/envvars
      . $EB_SCRIPT_DIR/use-app-ruby.sh
      # Stop Puma
      /sbin/initctl stop puma
      # Now we can do the actual restart of the server. Make sure to have double quotes when using env vars in the command.
      cd $EB_APP_DEPLOY_DIR
      FILE=/var/run/thin/thin.pid
      if [ -f "$FILE" ]; then
          su -s /bin/bash -c "RACK_ENV=production bundle exec thin restart -R config.ru -e production -p 9292 -C config/thin.yml" $EB_APP_USER
      else
          su -s /bin/bash -c "RACK_ENV=production bundle exec thin start -R config.ru -e production -p 9292 -C config/thin.yml" $EB_APP_USER
      fi
      # Remove the old app pid (puma) and replace it with our one
      rm -f /var/elasticbeanstalk/healthd/application.pid
      ln -s /var/run/thin/thin.0.pid /var/elasticbeanstalk/healthd/application.pid

container_commands:
  01_reload_nginx:
    command: "sudo service nginx reload"
  02_remove_webapp_healthd:
    command: "rm -f /opt/elasticbeanstalk/support/conf/webapp_healthd.conf /etc/nginx/conf.d/webapp_healthd.conf"