DEV Community

Tuna Çağlar Gümüş
Tuna Çağlar Gümüş

Posted on

Rails 6 & Webpacker Settings for Production

Rails 6 Webpacker Settings for Production

Hello,

TLDR; Things got messed up when I went into production with my webpack installed Rails 6 codebase. I solved the case and learned a few new things along the way that I share below.

This -> 🌝

This is the face of a man who solved several problems that he faced in moving Rails 6 webpack into the production environment, yet hated every minute working on it.

Why do we lack a simple documentation on this procedure?
While the primary goal of developing a website is to deploy it, how come I cannot push my website to the public simply using webpacker. Furthermore, why one earth there is not any warnings.

No, probably there is documentation on going to production with webpack and Rails 6. The main reason is that Rails documentation pages still include lots of legacy resources from Rails 5.X releases, and it is hard to find one for Rail 6. Guess what, that is the documentation. 🌝

The Problem

It is simple. I want to go to production and serve my packs and assets from Rails.

I know it is not a good choice for production. But I want to first, set my environment; second, make sure it is working; and finally, go backend and install nginx or apache or any other server that serves assets.

The problem is getting several errors on the way. Now, let's go through errors one by one, and solve our problems to production.

Yarn.lock Settings

Yarn.lock file tells the system which yarn packages are needed for your website to work and what are their dependencies. But, when you work on your MAC or PC and develop your system there, and go to production with a Linux server, sometimes you get inconsistent yarn.lock file, because your systems are different.

Usually, you should push your yarn.lock file to your repo and use it on production. But if you are a lucky one like me, you can get the following message:

rails server -e production

ERROR: The engine "node" is incompatible with this module. Expected version ">=8.16.0". Got "8.10.0"
Enter fullscreen mode Exit fullscreen mode

You are getting this error because your node installations on your dev and production environments are different. You can always update your dev environment to be in sync with your production. I think this should be the best solution. To do that;

yarn install --ignore-engines
Enter fullscreen mode Exit fullscreen mode

This step updates your yarn.lock file for your production environment. Then, you can push it to your repo and use it from your dev environment. 👍

You can also update your node to a newer version, but this can break other things in production with a node dependency. So, be careful.

curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get install -y nodejs
Enter fullscreen mode Exit fullscreen mode

A better option would be to go with different yarn.lock files and yarn installation for production and development if you know what you are doing 😄. Unfortunately, that was not the case for me.

If you decide to go with two different yarn files, go to your webpacker.yml file and change the following line so that you should not get an error every time.

check_yarn_integrity: true 
to 
check_yarn_integrity: false
Enter fullscreen mode Exit fullscreen mode

Hosts for Production

When you can run rails server -e production successfully but you get;

Blocked host: turrsu.com
To allow requests to turrsu.com, add the following to your environment configuration:

config.hosts << "turrsu.com"
Enter fullscreen mode Exit fullscreen mode

This is a feature that comes with Rails 6. You need to define hosts for the app to work. So you go config/environments/production.rb file and add your host.

config.hosts << "www.turrsu.com"
Enter fullscreen mode Exit fullscreen mode

and also you need to go to your development.rb file and add this

config.hosts = nil
Enter fullscreen mode Exit fullscreen mode

and if you have dynamic URLs, you can use regex here like this

config.hosts << /[a-z0-9]+\.turrsu\.com/
Enter fullscreen mode Exit fullscreen mode

Serving assets from webpack with Rails and Puma

As long as you have nginx or apache installed as a server, they serve your assets, and you don't need to do anything. However, if you want to serve your assets from Puma and Rails, you have to do this.

Go to your config/environments/production.rb file and change the following line.

config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
to
config.public_file_server.enabled = true
Enter fullscreen mode Exit fullscreen mode

This serves your assets from your Puma/Rails.

You are all set but still can't access your assets from production

This usually happens because of two reasons. You either didn't set your bin/webpack for production, or you didn't compile your assets for production. Let's go one by one.

Set webpack for production

To compile your packs, you do for your app.

bin/webpack
Enter fullscreen mode Exit fullscreen mode

But it doesn't do it for production because in default, it's set for the development environment, and you need to change that in production.

Go your bin/webpack from your production env.

Change these lines

ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"] ||= "development"
Enter fullscreen mode Exit fullscreen mode

to this

ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "production"
ENV["NODE_ENV"] ||= "production"
Enter fullscreen mode Exit fullscreen mode

or define RAILS_ENV, RACK_ENV and NODE_ENV environment variables to production.

Now, when you do bin/webpack this compile your packs for production.

Lets compile for production

In Rails, you need to compile your assets to serve them. Compile doesn't always re-write your files. Sometimes you get this error:

Webpacker can't find application in /Users/tcgumus/Documents/rails/pikseladam-with-ror/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
 unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Enter fullscreen mode Exit fullscreen mode

To make it a clean and straightforward compile job, you need to delete public/assets and public/packs folder.

RAILS_ENV=production rake assets:precompile
bin/webpack
Enter fullscreen mode Exit fullscreen mode

or if you didn't update your bin/webpack file, you do this

RAILS_ENV=production rake assets:precompile
RAILS_ENV=production RACK_ENV=production NODE_ENV=production bin/webpack
Enter fullscreen mode Exit fullscreen mode

After this, I was able to run my app from my Puma/Rails and access my assets from it. This article solves some problems you will face when you go to production with Rails 6 and webpack, but I'm pretty sure this is just a beginning.

Defining a production environment is a tough job. It includes lots of decisions to make, and it changes quickly when requirements change, when developers change. I wish this article will help some of you, but please consider that it includes my decisions for my production environment right now. It can change through time and space. This is still a work in progress. 👨‍💻

Please let me know if I can help.
Best regards,
Tuna

Top comments (9)

Collapse
 
thomasconnolly profile image
Tom Connolly

I learned that I had to remove from my linux box the system version of node.js (i.e., the one you get thusly: sudo apt install node) and replace it with npm install node. I can't tell you why, but that is what fixed the incompatibility issue for me and I don't have to use the "--ignore-engines" flag.

Collapse
 
mtancoigne profile image
Manuel Tancoigne

--ignore-engines was something I faced too, and was due to i-dont-remember-which node package dependency having incorrect node version dependency leading to this error when the package requiring it was installed.

Version errors are unfortunately too common in the ecosystem...

Collapse
 
mtancoigne profile image
Manuel Tancoigne • Edited

sometimes you get inconsistent yarn.lock file, because your systems are different.

To avoid this, I have the same Node and Ruby version on the server and on the dev computers:

  • Node Version Manager (nvm), or N are great to have multiple node versions in userland (not system wide). With a .node-version file in the project and Automatic Version Switching (avn), the proper node version is used when you cd to your project.
  • RBEnv works the same for Ruby, with a .ruby-version file in the project.

It may be a burden to setup, but once it's done, it's done, and changing projects and required versions becomes a breeze.

Example of contents for the .xxx-version files

  • .ruby-version should be the exact version, as far as I remember:
    • 2.5.1
    • 2.6.6
  • .node-version has any level; avn will pick what matches:
    • 12
    • 10.2
    • 10.6.5
Collapse
 
tcgumus profile image
Tuna Çağlar Gümüş

thank you for your comment. I will try that :)

Collapse
 
tcgumus profile image
Tuna Çağlar Gümüş

Addition; Please add this variables to environment if you don’t want to change code. This is a better option. Add

RAILS_ENV=production ,  NODE_ENV=production, 
RAKE_ENV=production 
Collapse
 
altruist2692 profile image
Altruist

You made my day! A Big Thank you! :)

Collapse
 
tcgumus profile image
Tuna Çağlar Gümüş

Happy to help :)

Collapse
 
davidgay profile image
David Gay

Big thanks for the tip on serving webpack assets with puma.

Collapse
 
tcgumus profile image
Tuna Çağlar Gümüş

Glad to help 🙂