将 Rails + Puma + Postgres 应用程序部署到 Elastic beanstalk 的正确方法?

Posted

技术标签:

【中文标题】将 Rails + Puma + Postgres 应用程序部署到 Elastic beanstalk 的正确方法?【英文标题】:Right way to deploy Rails + Puma + Postgres app to Elastic beanstalk? 【发布时间】:2017-04-17 17:09:58 【问题描述】:

我有一个 Rails 5 API,我正在尝试(正确)部署在 Elastic Beanstalk 上。

这是我最初使用的config/puma.rb 文件:

threads_count = ENV.fetch("RAILS_MAX_THREADS")  5 .to_i
threads threads_count, threads_count

# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
port        ENV.fetch("PORT")  3000 

# Specifies the `environment` that Puma will run in.
environment ENV.fetch("RAILS_ENV")  "development" 

# Allow puma to be restarted by `rails restart` command.

plugin :tmp_restart

我收到以下套接字错误:

2015/11/24 06:44:12 [crit] 2689#0: *4719 connect() to unix:///var/run/puma/my_app.sock failed (2: No such file or directory) while connecting to upstream

为了解决这个问题,我尝试添加以下行并让它工作:

rails_env = ENV['RAILS_ENV'] || "production"
if rails_env == "production"
  bind "unix:///var/run/puma/my_app.sock"
  pidfile "/var/run/puma/my_app.sock"
end

我真正的问题是,这是正确的做法吗?如果有人以前做过,你能指点我吗?有没有办法通过 docker 容器做到这一点?

【问题讨论】:

在完成 Elastic Beanstalk 设置时,您是否尝试仅在 Gemfile 中安装 puma gem 并选择带有 Puma 的 Ruby 平台?我会先看看你是否可以在没有任何特殊 Puma 配置文件的情况下运行它。 @littleforest Puma gem 已经在我的 gemfile 中了。除了添加这两行之外,我没有做任何其他配置。我在轨道上 5 您是否确认您使用 Puma 而非Passenger 启动了 Ruby 平台? 是的,我确定了。我猜这应该不是问题,因为它显示了有关套接字的错误,并且绑定它解决了问题 我的设置完全相同,但在我的情况下,nginx 返回 404 错误。有什么想法吗? 【参考方案1】:

您也可以将 Rails 应用程序作为 Rails - Puma 应用程序部署到 Elastic Beanstalk 或 Docker。答案会更笼统,而是指出从哪里开始,而不是提供完整的解决方案。

鲁比 - 彪马

这可能是一个相当棘手的问题:如果您通过控制台(在 Web 浏览器中)为 Ruby 创建新的 Elastic Beanstalk 环境,它可以默认设置乘客平台,而不是 Puma 平台。并且可能您无法在控制台中更改它:

要使用 Puma 创建新环境,请使用 eb cli。很好的演练here。但是,在运行eb create 之前,您还需要做一件事——选择平台:

$ eb platform select

It appears you are using Python. Is this correct?
(y/n): n

Select a platform.
1) Go
2) Node.js
3) php
4) Python
5) Ruby
6) Tomcat
7) IIS
8) Docker
9) Multi-container Docker
10) GlassFish
11) Java
(default is 1): 5

Select a platform version.
1) Ruby 2.3 (Puma)
2) Ruby 2.2 (Puma)
3) Ruby 2.1 (Puma)
4) Ruby 2.0 (Puma)
5) Ruby 2.3 (Passenger Standalone)
6) Ruby 2.2 (Passenger Standalone)
7) Ruby 2.1 (Passenger Standalone)
8) Ruby 2.0 (Passenger Standalone)
9) Ruby 1.9.3
(default is 1):

如果要创建 Elastic Beanstalk 的 Worker 而不是 Web Server,请运行:

 $ eb create -t worker

您可以使用控制台(Web 浏览器)或eb cli (docs) 设置其他配置。

Docker

以下帖子可能对如何设置 Rails + Puma + Nginx + Docker 有用:

http://codepany.com/blog/rails-5-and-docker-puma-nginx/

这是多容器配置,其中 Nginx 绑定到端口 80 并通过套接字将请求流式传输到 puma。在您的情况下,它将是:"unix:///var/run/puma/my_app.sock"

要上传 Docker,您可以使用 AWS ECR 来存储 Docker 映像。您必须创建 Dockerrun.aws.json 文件(与 docker-compose.yml 文件非常相似),然后您可以通过 AWS 控制台(Web 浏览器)将其部署到您的环境中。

编辑

这里是puma.rb的配置文件:

threads_count = ENV.fetch('RAILS_MAX_THREADS')  5 
threads threads_count, threads_count

bind "unix:///var/run/puma.sock?umask=0000"

stdout_redirect "/var/log/puma.stdout.log", "/var/log/puma.stderr.log", true

# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch('RAILS_ENV')  'development' 

# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart

某些设置可能会有所不同,但关键是我在那里绑定了一个 puma 服务器到 unix 套接字,并且它与 NGINX 连接。 NGINX 配置文件:

user  root;

error_log  /var/log/app-nginx-error.log;
pid        /var/run/app-nginx.pid;

events 
    worker_connections  8096;
    multi_accept        on;
    use                 epoll;


http 
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/app-nginx-access.log  main;

    sendfile           on;
    tcp_nopush         on;
    tcp_nodelay        on;
    keepalive_timeout  10;

    upstream appserver 
      server unix:///var/run/puma.sock;
    

    server 
      listen 80 default_server;
      root /var/www/public;
      client_max_body_size  16m;

      location ^~ /assets/ 
        gzip_static on;
        expires max;
        add_header Cache-Control public;
      

      try_files $uri/index.html $uri @appserver;
      location @appserver 
        proxy_set_header  Host $host;
        proxy_set_header  X-Real-IP $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  X-Forwarded-Host $server_name;
        proxy_set_header  Client-IP $remote_addr;
        proxy_pass        http://appserver;
      

      access_log    /var/log/app-nginx-access.log;
      error_log     /var/log/app-nginx-error.log debug;
      error_page    500 502 503 504 /500.html;
    

NGINX 配置文件中最重要的部分是:

upstream appserver 
  server unix:///var/run/puma.sock;

【讨论】:

能否请您粘贴您的puma.config 文件?它会提高这个答案的实用性 EB 默认使用 puma 2.16.0,这取决于旧版本的机架。如何为我的 EB 应用获取最新版本的 puma (3.11)?

以上是关于将 Rails + Puma + Postgres 应用程序部署到 Elastic beanstalk 的正确方法?的主要内容,如果未能解决你的问题,请参考以下文章

text Dockerize Rails(Puma + Postgres + Nginx)

如何让 puma 将日志发送到标准输出

Sinatra,Puma,ActiveRecord:没有找到“主要”的连接池

使用 Nginx、Puma 和 Redis 部署 Rails 5 Action Cable

谁在运行Puma或Passenger时设置RAILS_MAX_THREADS环境变量?

ruby rails中如何配置puma服务监听指定的IP地址