Unable to deploy Rails with Tailwindcss and Webpacker to Elastic Beanstalk

Viewed 426

After several hours of debugging, searching, and trying probable solutions, I'm still unable to deploy Rails application to Elastic Beanstalk and seeking for help. Deployment fails because Rails can't find Tailwindcss in production environment. I have attached the essential part of the deployment log, project configuration, and Elastic Beanstalk environment properties. Production environment compiles without errors on local machine.

Would be thankful for any insights which could solve this issue.

eb-engine.log shows the following error:

2020/11/28 00:39:19.602016 [INFO] Executing instruction: rake tasks
2020/11/28 00:39:19.602042 [INFO] Running command /bin/su webapp -c bundle exec /opt/elasticbeanstalk/config/private/checkforraketask.rb assets:precompile
2020/11/28 00:39:21.888082 [INFO] Found assets:precompile task in Rakefile
2020/11/28 00:39:21.888137 [INFO] Running command /bin/su webapp -c bundle exec rake assets:precompile
2020/11/28 00:39:23.310984 [ERROR] An error occurred during execution of command [app-deploy] - [rake tasks]. Stop running the command. Error: running rake task assets:precompile failed with error command bundle exec rake assets:precompile failed with error Command /bin/su webapp -c bundle exec rake assets:precompile failed with error exit status 1. Stderr:Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
rake aborted!
SassC::SyntaxError: Error: File to import not found or unreadable: tailwindcss/base.
        on line 1:1 of app/assets/stylesheets/application.scss
>> @import "tailwindcss/base";

   ^
/var/app/staging/app/assets/stylesheets/application.scss:1
/var/app/staging/vendor/bundle/ruby/2.7.0/gems/sassc-2.1.0-x86_64-linux/lib/sassc/engine.rb:49:in `render'

Elastic Beanstalk environment properties: https://i.stack.imgur.com/T3OKZ.png

package.json

{
  "name": "budgeteer",
  "private": true,
  "dependencies": {
    "@fortawesome/fontawesome-free": "^5.15.1",
    "@fullhuman/postcss-purgecss": "^3.0.0",
    "@rails/actioncable": "^6.0.0",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.0",
    "@rails/webpacker": "5.2.1",
    "flatpickr": "^4.6.6",
    "postcss": "^8.1.9",
    "stimulus": "^1.1.1",
    "stimulus-flatpickr": "^1.3.3",
    "tailwindcss": "^2.0.1",
    "turbolinks": "^5.2.0"
  },
  "version": "0.1.0",
  "devDependencies": {
    "eslint": "^7.14.0",
    "eslint-plugin-tailwind": "^0.2.0",
    "stylelint-config-recommended": "^3.0.0",
    "webpack-dev-server": "^3.11.0"
  }
}

postcss.config.js

let environment = {
  plugins: [
    require('autoprefixer'),
    require('tailwindcss')('./tailwind.config.js'),
    require('postcss-import'),
    require('postcss-flexbugs-fixes'),
    require('postcss-preset-env')({
      autoprefixer: {
        flexbox: 'no-2009'
      },
      stage: 3
    })
  ]
};

if (process.env.RAILS_ENV === "production") {
  environment.plugins.push(
    require('@fullhuman/postcss-purgecss')({
      content: [
        './app/**/*.html.erb',
        './app/helpers/**/*.rb',
        './app/javascript/**/*.js'
      ],
      defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
    })
  )
}

module.exports = environment

tailwind.config.js

module.exports = {
  future: {},
  purge: false,
  theme: {
    extend: {
      fontFamily: {},
  },
  variants: {},
  plugins: [],
}

app/assets/stylesheets/application.scss

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

...

app/javascript/packs/application.js

...

import "../../assets/stylesheets/application.scss"

...

config/environments/production.rb

Rails.application.configure do
  config.cache_classes = true

  config.eager_load = true

  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?

  config.assets.compile = false

  config.active_storage.service = :local

  config.log_level = :debug

  config.log_tags = [ :request_id ]

  config.action_mailer.perform_caching = false

  config.i18n.fallbacks = true

  config.active_support.deprecation = :notify

  config.log_formatter = ::Logger::Formatter.new

  if ENV["RAILS_LOG_TO_STDOUT"].present?
    logger           = ActiveSupport::Logger.new(STDOUT)
    logger.formatter = config.log_formatter
    config.logger    = ActiveSupport::TaggedLogging.new(logger)
  end

  config.active_record.dump_schema_after_migration = false
end

config/webpacker.yml

default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_root_path: public
  public_output_path: packs
  cache_path: tmp/cache/webpacker
  check_yarn_integrity: false
  webpack_compile_output: true

  resolved_paths: []

  cache_manifest: false

  extract_css: false

  static_assets_extensions:
    - .jpg
    - .jpeg
    - .png
    - .gif
    - .tiff
    - .ico
    - .svg
    - .eot
    - .otf
    - .ttf
    - .woff
    - .woff2

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

production:
  <<: *default

  compile: false

  extract_css: true

  cache_manifest: true

1 Answers
2020/11/28 00:39:23.310984 [ERROR] ...
1. Stderr:Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install

It's telling you to install yarn before the precompile. I achieved that adding a .ebextension with this file:

$ cat .ebextensions/10-node.config 
commands:
  command1:
    command: "curl -sL https://rpm.nodesource.com/setup_15.x | bash -"
  command2:
    command: "yum -y install nodejs"
  command3:
    command: "npm install -g yarn@1"

Double check more powerful usage of ebextensions here

Related