Skip to content

Instantly share code, notes, and snippets.

@creadone
Last active August 5, 2021 19:02
Show Gist options
  • Save creadone/97daafc59219edb823b2fff739240b9d to your computer and use it in GitHub Desktop.
Save creadone/97daafc59219edb823b2fff739240b9d to your computer and use it in GitHub Desktop.
Ruby on Rails 6: using servers.com cloud as CDN for static assets
# app/config/deploy.rb
# [...]
namespace :deploy do
# [...]
desc 'Clear previous assets on server'
task :clear_shared_assets do
on roles(:app), in: :sequence, wait: 5 do
as user: fetch(:user) do
execute :rm, '-rf', "#{shared_path}/public/assets/*"
execute :touch, "#{shared_path}/public/assets/manifest"
end
end
end
desc "Publish assets to CDN"
task :publish_assets do
on roles(:app), in: :sequence, wait: 5 do
within release_path do
execute(:rails, 'runner lib/services/open_stack/sync.rb', "#{shared_path}/public/assets")
end
end
end
before :compile_assets, :clear_shared_assets
after :compile_assets, :publish_assets
# [...]
end
# [...]
gem 'fog-openstack' # driver for OpenStack Swift v2.0
gem 'non-digest-assets' # build assets without digest
# [...]
# app/config/environments/production.rb
Rails.application.configure do
# [...]
# It's magical set of string that worked
config.action_controller.asset_host = "your.cnamed.domain"
config.public_file_server.enabled = false
config.serve_static_assets = false
config.assets.compile = false
config.assets.prefix = '/assets'
config.assets.compress = true
config.assets.digest = false
config.assets.gzip = false
# [...]
end
# app/lib/services/open_stack/sync.rb
path = ARGV.last
uploader = Services::OpenStack::Uploader.new(path)
uploader.call
# app/lib/services/open_stack/uploader.rb
require 'fog/openstack'
module Services
module OpenStack
class Uploader
def initialize(assets_path)
@connection = Fog::OpenStack::Storage.new({
:openstack_username => 123456,
:openstack_project_name => 123456,
:openstack_api_key => 'qwerty123456',
:openstack_auth_url => 'https://[some_url]:5000/v3',
:connection_options => {}
})
@server_assets_path = assets_path
@server_assets_list = Dir[File.join(@server_assets_path, "**/*")].select do |f|
# If not directory & not *.gz & without digest (need gem 'non-digest-assets')
File.file?(f) && !f.end_with?('.gz') && !f.match?(/-[0-9a-z]{64}/)
end
# Bucket/directory (In the Rails is very hard to change default /assets directory)
@cdn_root_path = 'static/assets'
@cdn_root_dir = @connection.directories.create :key => @cdn_root_path
end
def upload! server_file_path
server_file_path_ary = server_file_path.split('/')
server_assets_path_ary = @server_assets_path.split('/')
cdn_file_path = (server_file_path_ary - server_assets_path_ary).join('/')
@cdn_root_dir.files.create :key => cdn_file_path, :body => File.read(server_file_path)
end
def call
@server_assets_list.each do |item|
upload! item
puts "Uploaded: #{item}"
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment