[RUBY] I want to recreate the contents of assets from scratch in the environment built with capistrano

Why did you want to do that

EC2 ran out of memory while capistrano's assets: precompile was running, and as a result of restarting the instance, deploy ended halfway. If the web server runs based on the half-finished compilation result and a runtime error occurs, I can't see it, so I tried to get it back to a clean state.

version information

rails (5.2.4.2)
capistrano (3.11.0)
sprockets (3.7.2)
sprockets-rails (3.2.1)

Prerequisites

current_path is this path

shared_path should be this path

Conclusion first

In conclusion, this is what you need to do.

  1. Erase the contents of / var / www / app_name / shared / public / assets
  2. Erase the contents of / var / www / app_name / shared / tmp / cache / assets
  3. Deploy as usual

There is a caveat. Capistrano comes standard with commands like deploy: clobber_assets that seem to erase assets. It means that you can erase it by hand without using it. The reason will be described later.

Description

Directory structure of capistrano

First, inside the / var / www / app_name of the server deployed by capistrano, the structure is as follows.

├── current (symlink is attached to the latest directory in releases)
├── releases
│   ├── 20200601101105
│   ├── 20200601102714
│   └── 20200601105159
├── repo
├── revisions.log
└── shared

Under this current, that is, under releases / 2006001105159, it will be configured as in your project's repository. There should be app /, config /, and public /.

Under this public /, there are assets / packed with built static files ... pretending to be / var / www / app_name / current / public / assets is a symbolic link to / var / www / app_name / shared / assets.

And / var / www / app_name / current / tmp / cache is also a symbolic link to / var / www / app_name / shared / tmp / cache.

Assets: precompile cache mechanism

[Rails Guide Asset Cache Store](https://railsguides.jp/asset_pipeline.html#%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%81% AE% E3% 82% AD% E3% 83% A3% E3% 83% 83% E3% 82% B7% E3% 83% A5% E3% 82% B9% E3% 83% 88% E3% 82% A2)

The default Sprockets cache assets in tmp / cache / assets in development and production environments.

As it is written, there is a cache of the compilation result in tmp / cache / assets, so delete it. If it is capistrano, / var / www / app_name / shared / tmp / cache / assets corresponds to this, so delete it.

How Sprockets deploy results are cached

Apart from the assets: precompile cache, Sprockets also keeps the deployment result files. The code for Sprockets says something like this:

module Sprockets
  module Exporters
    # Writes a an asset file to disk
    class FileExporter < Exporters::Base
      def skip?(logger)
        if ::File.exist?(target)
          logger.debug "Skipping #{ target }, already exists"
          true
        else
          logger.info "Writing #{ target }"
          false
        end
      end

      def call
        write(target) do |file|
          file.write(asset.source)
        end
      end
    end
  end
end

When deploy: assets: precompile, have you seen a bunch of logs in standard output? It is probably the above code that realizes that. See logger.info" Writing .

Like this:

      01 I, [2020-06-01T08:56:09.691790 #10361]  INFO -- : Writing /var/www/app_name/releases/20200601085319/public/assets/develop/application-232387090aed00e6b038…
      01 I, [2020-06-01T08:56:09.692557 #10361]  INFO -- : Writing /var/www/app_name/releases/20200601085319/public/assets/develop/application-232387090aed00e6b038…
      01 I, [2020-06-01T08:56:17.418572 #10361]  INFO -- : Writing /var/www/app_name/releases/20200601085319/public/assets/lb-0002/application-d1bedc9937772b59211a…
      01 I, [2020-06-01T08:56:17.418856 #10361]  INFO -- : Writing /var/www/app_name/releases/20200601085319/public/assets/lb-0002/application-d1bedc9937772b59211a…
      01 I, [2020-06-01T08:56:21.414096 #10361]  INFO -- : Writing /var/www/app_name/releases/20200601085319/public/assets/lb-0003/application-5a60e0a26af1e40a9188…
      01 I, [2020-06-01T08:56:21.414368 #10361]  INFO -- : Writing /var/www/app_name/releases/20200601085319/public/assets/lb-0003/application-5a60e0a26af1e40a9188…

If you get stuck in this skip? Judgment. In other words, in this example, if the file with digest of / var / www / app_name / releases / 20200601085319 / public / assets / develop / application-232387090aed00e6b038… already exists, Sprockets does not export files.

So, with capistrano, if the same file exists in / var / www / app_name / shared / assets, it will be skipped by this skip ?. You need to erase it.

Oh? There seems to be a convenient command ...?

capistrano will display all commands with cap -T. You can find such a command in relation to assets.

cap deploy:cleanup_assets          # Cleanup expired assets
cap deploy:clobber_assets          # Clobber assets

Isn't the command deploy: clobber_assets prepared by default? clobber means to hit. It seems that they will force you to make new assets! This is good! If you think about it and use it, it will not actually behave as you expected.

$ bundle exec cap review deploy:clobber_assets

00:00 deploy:clobber_assets
      01 bundle exec rake assets:clobber
      01 I, [2020-06-01T11:22:46.062204 #6756]  INFO -- : Removed /var/www/app_name/releases/20200601094959/public/assets
      01 Removed webpack output path directory /var/www/app_name/releases/20200601094959/public/packs

It seems that the assets are deleted together with the directory, but if you look closely, it is just a symbolic link that is removed, and the essential contents are not deleted. Really? And, in the first place, tmp / cache, which is the cache at compile time, is not deleted.

It seems that issue has also been raised about this.

So, as I wrote in the "Conclusion", it seems better to manually execute the command to delete it, or to define the command yourself.

Recommended Posts

I want to recreate the contents of assets from scratch in the environment built with capistrano
I want to var_dump the contents of the intent
I want to be aware of the contents of variables!
I want to fetch another association of the parent model from the intermediate table with has_many
[Beginner] Procedure to log in to the virtual environment built with Vagrant
I tried to build the environment of PlantUML Server with Docker
I want to display the images under assets/images in the production environment
I want to change the value of Attribute in Selenium of Ruby
[Android] I want to get the listener from the button in ListView
I want to mess with Permission of Windows directory from WSL (ubuntu)
After all I wanted to preview the contents of mysql with Docker ...
[Rails + Webpacker] I want to use images of assets! Until you can view the image in Vue.js
I want to output the day of the week
I want to get the value in Ruby
I want to control the start / stop of servers and databases with Alexa
I want to see the contents of Request without saying four or five
[Java] I want to calculate the difference from the date
I want to embed any TraceId in the log
Tokoro I rewrote in the migration from Wicket 7 to 8
I want to know the answer of the rock-paper-scissors app
I want to display the name of the poster of the comment
I want to dark mode with the SWT app
If you want to recreate the instance in cloud9
I want to return the scroll position of UITableView!
I want to redirect sound from Ubuntu with xrdp
For those who want to use MySQL for the database in the environment construction of Rails6 ~.
I want to change the path after new registration after logging in with multiple devises.
How to use git with the power of jgit in an environment without git commands
Use the --build-arg option of docker-compose to pass environment variables to the container built with Dockerfile
[Rails] I want to display the link destination of link_to in a separate tab
I want to reduce the number of unnecessary queries. From considering counter_cache to introducing counter_culture.
I want to get the information of the class that inherits the UserDetails class of the user who is logged in with Spring Boot.
Even if I want to convert the contents of a data object to JSON in Java, there is a circular reference ...
[Ruby on Rails] I want to get the URL of the image saved in Active Storage
In Java, I want to trim multiple specified characters from only the beginning and end.
After posting an article with Rails Simple Calendar, I want to reflect it in the calendar.
I want to expand the clickable part of the link_to method
I want to change the log output settings of UtilLoggingJdbcLogger
How to manage the difference in each environment with yml without increasing the number of RAILS_ENV
What I did in the version upgrade from Ruby 2.5.2 to 2.7.1
I want to get a list of the contents of a zip file and its uncompressed size
I want to change the color of the upper control navigation bar (Control menu) in Liferay 7 / DXP
I tried using Docker because I don't want to pollute the local environment in Microsoft Teams tab development of MS Learn
I tried to build the environment of WSL2 + Docker + VSCode
I want to distinct the duplicated data with has_many through
I tried to develop the cache function of Application Container Cloud Service in the local environment
I want to return a type different from the input element with Java8 StreamAPI reduce ()
I want to transition to the same screen in the saved state
I want to narrow down the display of docker ps
[Ruby] I want to reverse the order of the hash table
I want to temporarily disable the swipe gesture of UIPageViewController
I tried upgrading from CentOS 6.5 to CentOS 7 with the upgrade tool
I want to pass the startup command to postgres with docker-compose.
I want to simplify the conditional if-else statement in Java
[Controller] I want to retrieve the numerical value of a specific column from the DB (my memo)
What I was addicted to when updating the PHP version of the development environment (Docker) from 7.2.11 to 7.4.x
I tried to take a look at the flow of Android development environment construction with Android Studio
I want to know the Method of the Controller where the Exception was thrown in the ExceptionHandler of Spring Boot
I tried to solve the problem of "multi-stage selection" with Ruby
I want to understand the flow of Spring processing request parameters
I want to return to the previous screen with kotlin and java!