When deploying a Rails application that is using Webpacker and Capistrano, there are a few configuration tweaks that optimize the experience.
Using capistrano-rails
capistrano-rails Show archive.org snapshot is a Gem that adds Rails specifics to Capistrano, i.e. support for Bundler, assets, and migrations. While it is designed for Asset Pipeline (Sprockets) assets, it can easily be configured for Webpacker. This brings these features to the Webpacker world:
- Automatic removal of expired assets
- Manifest backups
# config/deploy.rb
# No need to include public/packs here, but add the Webpacker cache dir (see link below)
set :linked_dirs, %w[… tmp/cache/webpacker]
# capistrano-rails config
set :assets_roles, %i[webpack] # Give the webpack role to a single server (see code block below)
set :assets_prefix, 'packs' # Assets are located in /packs/
set :keep_assets, 10 # Automatically remove stale assets
set :assets_manifests, lambda { # Tell Capistrano-Rails how to find the Webpacker manifests
[release_path.join('public', fetch(:assets_prefix), 'manifest.json*')]
}
set :conditionally_migrate, true # Only attempt migration if db/migrate changed - not related to Webpacker, but a nice thing
Give the webpack role to a single server:
# config/deploy/production.rb (analog to config/deploy/staging.rb)
...
server '<server url>', user: '<user name>', roles: %w(... webpack)
Make sure to read as well:
- Webpack(er): Serving identical assets from all servers.
- Capistrano: Speeding up asset compile during deploy .
Only compiling production packs on the server
Asset compilation takes quite some time, and slows down deployments. Let's only compile packs that are relevant, then. No need for specs and other development packs on the servers.
Create a directory "packs_production" right next to your "packs" directory. Next, symlink all packs that are required in production:
app/
...
webpack/
packs/
app/
test/
packs_production
app -> ../packs/app
Now tell Webpacker to use these for production (and staging):
# config/webpacker.yml
production: &production
<<: *default
# Only compile relevant packs
source_entry_path: packs_production
...
staging: *production
Disabling unused compression
Webpacker supports Brotli Show archive.org snapshot compression, and produces .br files whenever compiling zipped files. However, these are of no value when they are not used.
To prevent the generation of Brotli files:
# config/webpack/environment.js
const webpackConfig = environment.toWebpackConfig()
// Save compile time by disabling an unused compression
webpackConfig.plugins = webpackConfig.plugins.filter(plugin => {
const isBrotliCompression = plugin.constructor.name === 'CompressionPlugin' && plugin.options.algorithm === 'brotliCompress'
return !isBrotliCompression
})
Older Webpacker versions might need this instead:
// Save compile time by disabling an unused compression
if (environment.plugins.getIndex('Compression Brotli') >= 0) {
environment.plugins.delete('Compression Brotli')
}