Goal: Using my rails app with static images in assets in production environemt
Steps:
RAILS_ENV=production rails assets:precompile
RAILS_SERVE_STATIC_FILES
environemt variable to true
to enable public file server (in production.rb
- config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
config.serve_static_assets = true
to /config/application.rb
With this setup, I`ve started the server.
I have a few static images in /app/assets/images/
which precompiled versions with fingerprint filename are now in /public/assets
. Examples:
aussen-d2fb0029a12281121a1752c599e715a8e2b3db17f1e8e18248a79a7b1ca63b91.jpg
hintergrund-ca80e1ae5a697c86898f3a7e107694a76dc12e54320b8ac80c58eecbffe0414a.png
So far so great.
When I use background-image: url(<%= asset_path('hintergrund') %>);
in application.css.erb
it successfully loads the precompiled background-image from /public/assets
.
Problem: I can't access the precompiled images with my image_tags in the views! Example:
<%= image_tag("aussen") %>
Error Logs:
I, [2018-03-23T00:46:29.133381 #9289] INFO -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682] Started GET "/" for 46.142.136.81 at 2018-03-23 00:46:29 +0100
I, [2018-03-23T00:46:29.134466 #9289] INFO -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682] Processing by HomeController#index as HTML
I, [2018-03-23T00:46:29.136604 #9289] INFO -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682] Rendering home/index.html.erb within layouts/application
I, [2018-03-23T00:46:29.138267 #9289] INFO -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682] Rendered home/index.html.erb within layouts/application (1.5ms)
I, [2018-03-23T00:46:29.138482 #9289] INFO -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682] Completed 500 Internal Server Error in 4ms
F, [2018-03-23T00:46:29.139546 #9289] FATAL -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682]
F, [2018-03-23T00:46:29.139635 #9289] FATAL -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682] ActionView::Template::Error (The asset "aussen" is not present in the asset pipeline.):
F, [2018-03-23T00:46:29.139798 #9289] FATAL -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682] 1: <%= image_tag("aussen", id: "home-img", alt: "Aussenansicht von Simson-Seelig") %>
[f36ff000-6261-4c2c-bfcc-4a2f80cae682] 2: <div id="home" class="content">
[f36ff000-6261-4c2c-bfcc-4a2f80cae682] 3: <p>Alles für Simson von Simson-Seelig.</p>
[f36ff000-6261-4c2c-bfcc-4a2f80cae682] 4: <p>Für die legendären Schwalben und alle anderen SIMSON-Modelle bieten wir Ersatzteile und Service. </p>
F, [2018-03-23T00:46:29.139867 #9289] FATAL -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682]
F, [2018-03-23T00:46:29.139930 #9289] FATAL -- : [f36ff000-6261-4c2c-bfcc-4a2f80cae682] app/views/home/index.html.erb:1:in `_app_views_home_index_html_erb__177499641769
After hours of researching, I still don't get why I can access the precompiled image in the stylesheet, but not in the view with the image_tag.
Additional information:
$ ruby --version
ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-linux]
$ rails --version
Rails 5.1.4
/config/application.rb
:
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module SimsonSeelig
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.1
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Enable rails to serve my assets
config.serve_static_assets = true
end
end
production.rb
:
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Attempt to read encrypted secrets from `config/secrets.yml.enc`.
# Requires an encryption key in `ENV["RAILS_MASTER_KEY"]` or
# `config/secrets.yml.key`.
config.read_encrypted_secrets = true
# 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?
if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Mount Action Cable outside main process or domain
# config.action_cable.mount_path = nil
# config.action_cable.url = 'wss://example.com/cable'
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug
# Prepend all log lines with the following tags.
config.log_tags = [ :request_id ]
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Use a real queuing backend for Active Job (and separate queues per environment)
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "simson-seelig_#{Rails.env}"
config.action_mailer.perform_caching = false
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Use a different logger for distributed setups.
# require 'syslog/logger'
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
end
/config/initializers/assets.rb
:
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
# Add Yarn node_modules folder to the asset load path.
Rails.application.config.assets.paths << Rails.root.join('node_modules')
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
The asset "aussen" is not present in the asset pipeline.
Technically true because you have not aussen
but you have aussen.jpg
so it will be <%= image_tag("aussen.jpg") %>
Look, while you use <%= image_tag("aussen") %>
then it will be genarate HTML like this
<%= image_tag("aussen") %>
#=> <img alt="Aussen" src="/assets/aussen" />
While you use <%= image_tag("aussen.jpg") %>
then it will be genarate HTML like this
<%= image_tag("aussen.jpg") %>
#=> <img alt="Aussen" src="/assets/aussen.jpg" />
When it's going into production mode then it will be shown some encrypted key on the page source like this
aussen-d2fb0029a12281121a1752c599e715a8e2b3db17f1e8e18248a79a7b1ca63b91.jpg
image_tag
AssetTagHelper
see this for reference.
Update production.rb
file config.assets.compile
false
to true
# config/environments/production.rb
...
config.assets.compile = true
...
Not sure if you want to set config.assets.compile = true in production, this will slow down your server
config.assets.compile=true in Rails production, why not?
Instead of explicitly setting config.assets.compile = false. Comment it out that worked for me, this is probably a bug. After commenting this out images were correctly rendered using the precompiled asset pipeline.
# config.assets.compile = false
I had this same issue when working on a Rails 6 application in Ubuntu 20.04 .
The issue for me was that I had not precompiled the assets in production.
Here's how I fixed it :
First, I ran the command below to precompile the assets and make them available in the public
directory of my application:
rails assets:precompile RAILS_ENV=production
Note : In development this can be accomplished using webpacker
with the command: /bin/webpack-dev-server
Next, set up Nginx or Apache web server to serve the static files that are available in the public
directory of my application. For me I set up Nginx with the configuration below using Let's Encrypt for SSL:
upstream railsserver {
server 127.0.0.1:3000;
}
server {
# Replace 'localhost' with your FQDN if you want to use
# your app from remote or if you need to add a certificate
server_name my-website.com www.my-website.com;
root /home/deploy/my-website/public;
# Define where Nginx should write its logs
access_log /var/log/nginx/my-website/access.log;
error_log /var/log/nginx/my-website/error.log;
location / {
# First attempt to serve request as file, then
# the rails application directory
try_files $uri @railsserver;
}
location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico) {
expires max;
}
location @railsserver {
proxy_set_header Host $http_host;
proxy_set_header CLIENT_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300;
proxy_pass http://railsserver;
gzip on;
gzip_types text/plain text/xml text/css image/svg+xml application/javas$
gzip_proxied any;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/my-website.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/my-website.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
That's all.
I hope this helps
如果链接不明确,可以参考这个:
image_tag '#', skip_pipeline: true
This is the answer when none of the above work.
Are you referencing a .jpeg
file? .jpeg
files get compiled to .jpg
files and so if you reference .jpeg
you will get this error.
The solution is to rename the file to .jpg
and reference the image_tag
with the corresponding .jpg
extension.
It can also happen if your images are in the wrong place. For rails 6, place images inside /app/assets/images/
, then simply
<%= image_tag("logo1.png", alt: "My logo", size: '200x75') %>
If it happens when using video_tag
with ActiveStorage, this should work:
<%= video_tag url_for(@banner_video.file), size: "150x120", controls: true %>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.