如何在 Elastic Beanstalk 容器中提供 Rails 应用程序的 webpack 资产?

Posted

技术标签:

【中文标题】如何在 Elastic Beanstalk 容器中提供 Rails 应用程序的 webpack 资产?【英文标题】:How to serve webpacked assets of Rails app in Elastic Beanstalk container? 【发布时间】:2018-08-12 06:12:30 【问题描述】:

我正在使用 Rails5 应用程序并成功将其部署到 EB 容器。

但是 webpacked 资产——直接在public/packs 中服务,在生产环境中返回 404。

在当前情况下,我设置了RAILS_SKIP_ASSET_COMPILATION = false,所以我每次在部署应用程序之前都会预编译资产。

我以前使用heroku作为生产环境,当时一切正常。

这是我的config/webpacker.yml

source_path: app/frontend/javascripts
  source_entry_path: packs
  public_output_path: packs # public/packs/filename-[hash].js
  cache_path: tmp/cache/webpacker

  # Additional paths webpack should lookup modules
  # ['app/assets', 'engine/foo/app/assets']
  resolved_paths: []

  # Reload manifest.json on all requests so we reload latest compiled packs
  cache_manifest: false

  extensions:
    - .js
    - .sass
    - .scss
    - .css
    - .png
    - .svg
    - .gif
    - .jpeg
    - .jpg

我尝试了什么...

我尝试将 public_output_path 从包更改为资产。但同样的错误仍然存​​在......

【问题讨论】:

【参考方案1】:

我也遇到了这个问题。我不确定您使用的是 nginx 还是Passenger。但如果是 Nginx,您可能需要向 /etc/nginx/conf.d/webapp_healthd.conf 添加一个位置块,如下所示:

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

然后运行sudo /etc/init.d/nginx restart

这应该足以让它工作。但是您需要使用这些自定义设置在您的项目中创建一个 .ebextensions/ 文件,这样它就不会被 Elastic Beanstalk 默认配置覆盖。

请参阅 Maria Luisa Carrion D. 的 this post,了解如何自动化 nginx 配置。

【讨论】:

如果您使用的是Amazon Linux 2 EB 平台,这里的答案是推荐的方法:***.com/a/69103413/1852005【参考方案2】:

借助 Amazon Linux 2 Elastic Beanstalk 平台,现在这一切变得容易得多。

nginx 的默认配置位于此处/etc/nginx/nginx.conf,如果您将eb ssh 连接到您的服务器,您可以查看它。

server ... 块中有一行代码:

# Include the Elastic Beanstalk generated locations
include conf.d/elasticbeanstalk/*.conf;

此包含在那里,因此您可以轻松地为您的服务器包含其他位置规则。如果您还没有在您的应用程序中创建一个.platform 文件夹,那么您在应用程序中要做的就是创建一个具有此路径的配置文件:.platform/nginx/conf.d/elasticbeanstalk/10_packs_location.conf (“10_packs_location”可以是任何你想要的名字)。

输入这些文件内容:

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

然后在下一次部署时,您将在/etc/nginx/conf.d/elasticbeanstalk/ 下看到新的“10_packs_location.conf”文件,该文件将包含在/etc/nginx/nginx.conf 中。 完成后,将应用新的位置规则。

更多详情请参见此处的文档:https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html

【讨论】:

【参考方案3】:

另一种解决方案是让 Rails 自己而不是 NGINX 为资产提供服务。

在您的config/environments/production.rb 中,您可能有以下内容:

# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present?

如果您在 AWS EB 中设置 RAILS_SERVE_STATIC_FILES = enabled,Rails 将为资产提供服务。

这是 Heroku 中的默认行为: https://devcenter.heroku.com/changelog-items/617

这是一篇关于它的好帖子: https://acuments.com/rails-serve-static-files-with-nginx.html

【讨论】:

【参考方案4】:

在不影响 Elasticbeanstalk 的情况下解决所有这些问题的最快方法是更改​​您的 webpacker.yml 文件以使用资产/包而不是已经正确提供的包。

production:
  <<: *default

  # Production requires the packs folder to be in assets for nginx
  public_output_path: assets/packs

【讨论】:

以上是关于如何在 Elastic Beanstalk 容器中提供 Rails 应用程序的 webpack 资产?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Amazon linux 2 在 Elastic beanstalk 中使用多容器 docker?

如何在 Elastic Beanstalk 上为特定容器设置文件夹权限

如何在 Elastic Beanstalk 容器中提供 Rails 应用程序的 webpack 资产?

AWS Elastic Beanstalk:如何更改节点命令?在最近的更新中删除了容器选项?

如何使用非默认运行参数在 AWS Elastic Beanstalk 中运行 Docker 容器?

如何在Elastic Beanstalk容器中提供Rails应用程序的webpacked资产?