Rails 6 图片上传到数字海洋空间

问题描述

我有一个上传横幅和缩略图博客。我最初将它设置为使用carrierwave gem上传到本地目录,我想尝试使用digitalocean空间,因为该应用程序已部署到digitalocean应用程序平台。我能够让它在 localhost:3000 上运行,但是当我将它部署到 digitalocean 时,它不断恢复到之前的部署,说运行状况检查失败但不是真正的错误

我决定将它部署到 heroku,因为我能够得到实际的错误。这是我从 heroku 得到的当前错误

2021-03-09T22:41:10.466080+00:00 heroku[web.1]: Starting process with command `bin/rails server -p ${PORT:-5000} -e production`
2021-03-09T22:41:20.121636+00:00 app[web.1]: => Booting Puma
2021-03-09T22:41:20.121679+00:00 app[web.1]: => Rails 6.1.3 application starting in production
2021-03-09T22:41:20.121679+00:00 app[web.1]: => Run `bin/rails server --help` for more startup options
2021-03-09T22:41:31.105804+00:00 app[web.1]: [fog][WARNING] Unable to fetch credentials: Connection refused - connect(2) for 169.254.169.254:80 (Errno::ECONNREFUSED)
2021-03-09T22:41:31.108732+00:00 app[web.1]: Exiting
2021-03-09T22:41:31.110380+00:00 app[web.1]: /app/vendor/bundle/ruby/3.0.0/gems/fog-core-2.2.3/lib/fog/core/service.rb:244:in `validate_options': Missing required arguments: aws_access_key_id,aws_secret_access_key (ArgumentError)
2021-03-09T22:41:31.110386+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/fog-core-2.2.3/lib/fog/core/service.rb:268:in `handle_settings'
2021-03-09T22:41:31.110391+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/fog-core-2.2.3/lib/fog/core/service.rb:98:in `new'
2021-03-09T22:41:31.110426+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/fog-core-2.2.3/lib/fog/core/services_mixin.rb:30:in `new'
2021-03-09T22:41:31.110427+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/carrierwave-2.2.0/lib/carrierwave/storage/fog.rb:68:in `eager_load'
2021-03-09T22:41:31.110431+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/carrierwave-2.2.0/lib/carrierwave.rb:77:in `block in <class:Railtie>'
2021-03-09T22:41:31.110435+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.3/lib/active_support/lazy_load_hooks.rb:68:in `block in execute_hook'
2021-03-09T22:41:31.110467+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.3/lib/active_support/lazy_load_hooks.rb:61:in `with_execution_control'
2021-03-09T22:41:31.110472+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.3/lib/active_support/lazy_load_hooks.rb:66:in `execute_hook'
2021-03-09T22:41:31.110473+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.3/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
2021-03-09T22:41:31.110508+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.3/lib/active_support/lazy_load_hooks.rb:51:in `each'
2021-03-09T22:41:31.111096+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.3/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
2021-03-09T22:41:31.111100+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/application/finisher.rb:129:in `block in <module:Finisher>'
2021-03-09T22:41:31.111101+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/initializable.rb:32:in `instance_exec'
2021-03-09T22:41:31.111127+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/initializable.rb:32:in `run'
2021-03-09T22:41:31.111132+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/initializable.rb:61:in `block in run_initializers'
2021-03-09T22:41:31.111132+00:00 app[web.1]: from /app/vendor/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:228:in `block in tsort_each'
2021-03-09T22:41:31.111164+00:00 app[web.1]: from /app/vendor/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
2021-03-09T22:41:31.111168+00:00 app[web.1]: from /app/vendor/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:431:in `each_strongly_connected_component_from'
2021-03-09T22:41:31.111169+00:00 app[web.1]: from /app/vendor/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:349:in `block in each_strongly_connected_component'
2021-03-09T22:41:31.111201+00:00 app[web.1]: from /app/vendor/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:347:in `each'
2021-03-09T22:41:31.111202+00:00 app[web.1]: from /app/vendor/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:347:in `call'
2021-03-09T22:41:31.111772+00:00 app[web.1]: from /app/vendor/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:347:in `each_strongly_connected_component'
2021-03-09T22:41:31.111777+00:00 app[web.1]: from /app/vendor/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:226:in `tsort_each'
2021-03-09T22:41:31.111777+00:00 app[web.1]: from /app/vendor/ruby-3.0.0/lib/ruby/3.0.0/tsort.rb:205:in `tsort_each'
2021-03-09T22:41:31.111781+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/initializable.rb:60:in `run_initializers'
2021-03-09T22:41:31.111808+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/application.rb:384:in `initialize!'
2021-03-09T22:41:31.111809+00:00 app[web.1]: from /app/config/environment.rb:5:in `<main>'
2021-03-09T22:41:31.111813+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
2021-03-09T22:41:31.111839+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
2021-03-09T22:41:31.111844+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
2021-03-09T22:41:31.111844+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
2021-03-09T22:41:31.111845+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
2021-03-09T22:41:31.111845+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:34:in `require'
2021-03-09T22:41:31.111848+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.3/lib/active_support/dependencies.rb:332:in `block in require'
2021-03-09T22:41:31.111851+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.3/lib/active_support/dependencies.rb:299:in `load_dependency'
2021-03-09T22:41:31.111884+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.3/lib/active_support/dependencies.rb:332:in `require'
2021-03-09T22:41:31.112296+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:53:in `require_relative'
2021-03-09T22:41:31.112301+00:00 app[web.1]: from config.ru:3:in `block in <main>'
2021-03-09T22:41:31.112302+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/builder.rb:116:in `eval'
2021-03-09T22:41:31.112334+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/builder.rb:116:in `new_from_string'
2021-03-09T22:41:31.112339+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/builder.rb:105:in `load_file'
2021-03-09T22:41:31.112340+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/builder.rb:66:in `parse_file'
2021-03-09T22:41:31.112367+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/server.rb:349:in `build_app_and_options_from_config'
2021-03-09T22:41:31.112368+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/server.rb:249:in `app'
2021-03-09T22:41:31.112372+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/server.rb:422:in `wrapped_app'
2021-03-09T22:41:31.112398+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/server.rb:312:in `block in start'
2021-03-09T22:41:31.112403+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/server.rb:379:in `handle_profiling'
2021-03-09T22:41:31.112809+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/rack-2.2.3/lib/rack/server.rb:311:in `start'
2021-03-09T22:41:31.112813+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/server/server_command.rb:39:in `start'
2021-03-09T22:41:31.112841+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/server/server_command.rb:144:in `block in perform'
2021-03-09T22:41:31.112845+00:00 app[web.1]: from <internal:kernel>:90:in `tap'
2021-03-09T22:41:31.112846+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/server/server_command.rb:135:in `perform'
2021-03-09T22:41:31.112877+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
2021-03-09T22:41:31.112881+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
2021-03-09T22:41:31.112882+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch'
2021-03-09T22:41:31.112912+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/command/base.rb:69:in `perform'
2021-03-09T22:41:31.114191+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/command.rb:50:in `invoke'
2021-03-09T22:41:31.114195+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands.rb:18:in `<main>'
2021-03-09T22:41:31.114196+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
2021-03-09T22:41:31.114229+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
2021-03-09T22:41:31.114234+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
2021-03-09T22:41:31.114234+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
2021-03-09T22:41:31.114261+00:00 app[web.1]: from /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.7.2/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
2021-03-09T22:41:31.114262+00:00 app[web.1]: from bin/rails:5:in `<main>'
2021-03-09T22:41:31.238223+00:00 heroku[web.1]: Process exited with status 1
2021-03-09T22:41:31.311694+00:00 heroku[web.1]: State changed from starting to crashed

服务器启动后崩溃,说雾无法获取凭据。

这是我的初始化程序/carrierwave.rb 文件

CarrierWave.configure do |config|
  config.fog_credentials = {
    provider:              'AWS',# required
    aws_access_key_id:     Rails.application.credentials.aws(:digitalocean_spaces_key),# required unless using use_iam_profile
    aws_secret_access_key: Rails.application.credentials.aws(:digitalocean_spaces_secret),# required unless using use_iam_profile
    use_iam_profile:       true,# optional,defaults to false
    region:                'nyc3',defaults to 'us-east-1'
    host:                  'nyc3.digitaloceanspaces.com',defaults to nil
    endpoint:              'https://nyc3.digitaloceanspaces.com' # optional,defaults to nil
  }


  config.fog_directory  = 'judo'                                      # required
  config.fog_public     = true                                                 # optional,defaults to true
  #config.fog_attributes = { cache_control: "public,max-age=#{365.days.to_i}" } # optional,defaults to {}
  # For an application which utilizes multiple servers but does not need caches persisted across requests,# uncomment the line :file instead of the default :storage.  Otherwise,it will use AWS as the temp cache store.
  # config.cache_storage = :file
end

这是对carrierwave.rb 文件的另一种尝试:

CarrierWave.configure do |config|
  config.fog_credentials = {
    provider:              'AWS',# required
    digitalocean_spaces_key_id:     Rails.application.credentials.digitalocean_spaces_key,# required unless using use_iam_profile
    digitalocean_spaces_secret: Rails.application.credentials.digitalocean_spaces_secret,digitalocean_spaces_bucket: Rails.application.credentials.digitalocean_spaces_bucket,use_iam_profile:       true,it will use AWS as the temp cache store.
  # config.cache_storage = :file
end

这是我的凭据.yml 文件

production:
  digitalocean_spaces_key: <%= ENV["DIGITALOCEAN_SPACES_KEY"] %>
  digitalocean_spaces_secret: <%= ENV["DIGITALOCEAN_SPACES_SECRET"] %>
  digitalocean_spaces_bucket: <%= ENV["DIGITALOCEAN_SPACES_BUCKET"] %>

development:
  digitalocean_spaces_key: my_key
  digitalocean_spaces_secret: my_secret
  digitalocean_spaces_bucket: judo

我在 digitalocean 上的应用程序中输入了空格键、秘密和存储桶作为应用程序级变量。

这是我的上传者/banner_uploader.rb 文件

class BannerUploader < CarrierWave::Uploader::Base
  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  #include CarrierWave::MiniMagick

  # Choose what kind of storage to use for this uploader:
  # storage :file
  storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}"
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  # def default_url(*args)
  #   # For Rails 3.1+ asset pipeline compatibility:
  #   # ActionController::Base.helpers.asset_path("fallback/" + [version_name,"default.png"].compact.join('_'))
  #
  #   "/images/fallback/" + [version_name,"default.png"].compact.join('_')
  # end

  # Process files as they are uploaded:
  # process scale: [200,300]
  #
  # def scale(width,height)
  #   # do something
  # end

  # Create different versions of your uploaded files:
  # version :thumb do
  #   process resize_to_fit: [50,50]
  # end

  # Add an allowlist of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  def extension_allowlist
    %w(jpg jpeg gif png)
  end

  # Override the filename of the uploaded files:
  # Avoid using model.id or version_name here,see uploader/store.rb for details.
  # def filename
  #   "something.jpg" if original_filename
  # end
end

这是我的帖子.rb:

class Post < ApplicationRecord
  belongs_to :user
  has_many :comments,as: :commentable,dependent: :destroy
  # Active Storage from Rails 5
  #has_one_attached :thumbnail
  #has_one_attached :banner
  # Action Text from Rails 6
  has_rich_text :body
  
  mount_uploader :banner,BannerUploader
 
  validates :title,length: { minimum: 5 }
  validates :body,length: { minimum: 25 }

  self.per_page = 10
  extend FriendlyId
  friendly_id :title,use: :slugged

end

这是我的 Gemfile:

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.0.0'

# Bundle edge Rails instead: gem 'rails',github: 'rails/rails',branch: 'main'
gem 'rails','~> 6.1.3'

# Use Puma as the app server
gem 'puma','~> 5.0'
# Use SCSS for stylesheets
gem 'sass-rails','>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker','~> 5.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks','~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder','~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis','~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt','~> 3.1.7'

# Use Active Storage variant
gem 'image_processing','~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap','>= 1.4.4',require: false

group :development,:test do
  # Use sqlite3 as the database for Active Record
  gem 'sqlite3','~> 1.4'
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug',platforms: [:mri,:mingw,:x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console','>= 4.1.0'
  # display performance information such as sql time and flame graphs for each request in your browser.
  # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
  # gem 'rack-mini-profiler','~> 2.0'
  gem 'listen','~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

group :production do 
  gem 'pg'
end 

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara','>= 3.26'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files,so bundle the tzinfo-data gem
gem 'tzinfo-data',platforms: [:mingw,:mswin,:x64_mingw,:jruby]

gem 'devise'
gem 'simple_form'
gem 'faker'
gem 'will_paginate'
gem 'friendly_id'
gem "carrierwave"
gem "mime-types"
gem "fog-aws"

解决方法

似乎服务器无法访问credentials.yml 的内容。这个文件是加密的,Rails 使用 master.key 文件中的主密钥存储来读取它。因此,鉴于 master.key 未签入版本控制,您需要在服务器上手动提供它。请查看这篇文章https://medium.com/cedarcode/rails-5-2-credentials-9b3324851336

本节:

部署主密钥

当您将代码移动到服务器时,您需要确保您的 config/credentials.yml.enc 文件可以被解密。这意味着你需要以某种方式向 Rails 提供你的主密钥,因为它没有被签入版本控制。

有两种方法:

选项 1:将 config/master.key 文件放在服务器中。您通常希望将此文件符号链接到服务器文件系统中的共享文件夹。同样,不要版本化您的 config/master.key 文件。

选项 2:创建 RAILS_MASTER_KEY ENV 变量。 Rails 会检测到它并将其用作您的主密钥,例如在heroku中:heroku config:set RAILS_MASTER_KEY=.

您应该能够模糊地使用其中任何一个。

如果你使用 RBENV 作为你的 ruby​​ 管理器,你可以存储你的环境变量这样做:

您将在您的项目文件夹中创建 .rbenv-vars,而不是您的 rails 项目文件夹,而是您的项目文件夹所在的文件夹,如果您愿意,可以在父文件夹中创建。

之后,您将 env var 放入文件中,如下所示:

DATABASE_PWD=*****

没有引号,在“=”之后的 ou 之前也没有空格

有关更多信息,请查看 goRails 上的此链接:https://gorails.com/deploy/ubuntu/18.04#capistrano

希望能帮到你

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...