Deploying to production

Deploying to the cloud

Deploying a Solidus application to production is no different from deploying any other Rails application. In this section we'll cover some popular options for deploying Solidus and a few additional caveats.

Heroku

Deploying a Solidus store to Heroku is extremely simple. All you'll need is an active Heroku account and the Heroku CLI on your machine.

Once you have those, you should first create a new app:

$ heroku create amazing-store

Now, push the code to your Heroku remote:

$ git push heroku master

Finally, set up the database schema and seeds:

$ heroku run rails db:schema:load db:seed

You're all set! Your Solidus store should now be running on Heroku.

AWS OpsWorks

This section still needs to be written.

Kubernetes

This section still needs to be written.

External dependencies

When deploying a Solidus store, there are a few external dependencies that must be installed. There are also some optional dependencies you may decide to install in order to make your application more resilient and easier to scale.

File storage

Paperclip has been deprecated in favor of Rails' native ActiveStorage library. Solidus already supports ActiveStorage, but due to limitations in ActiveStorage itself you will not be able to use it until Rails 6.1 is released with support for public URLs.

When you run Solidus locally or on a single node, any files you upload (product images, taxon icons etc.) are stored on the filesystem. While this works great in development, it's not a viable option when deploying to cloud platforms where clustering may cause files in one node not to be accessible by all other nodes. You may also find that files disappear when a node reboots because of ephemeral filesystems.

When running your store in production, you will have to rely on a file storage service such as Amazon S3 or Microsoft Azure Storage Service. Files will be uploaded to the storage service, which will also handle concerns such as high availability, security and distribution, and retrieval via a public URL.

Solidus supports storage services out of the box by integrating with the Paperclip gem. In order to configure Paperclip, just create an initializer like the following:

if Rails.env.production?
Paperclip::Attachment.default_options.merge!(
storage: :s3,
bucket: ENV.fetch('S3_BUCKET'),
s3_host_name: ENV.fetch('S3_HOST_NAME'),
s3_credentials: {
access_key_id: ENV.fetch('S3_ACCESS_KEY_ID'),
secret_access_key: ENV.fetch('S3_SECRET_ACCESS_KEY'),
s3_region: ENV.fetch('S3_REGION'),
}
)
end

Finally, put your S3 credentials in the environment variables used in the initializer.

If you're not using S3, Paperclip provides support for the most popular storage services, either natively or through third-party plugins.

Cache store

Solidus employs fragment caching and low-level caching extensively throughout the storefront and API views. By default, Rails uses an in-memory cache adapter in production. This essentially makes all caching useless if you are running Solidus across multiple nodes, since the cache is not shared across instances.

Therefore, instead of the default adapter you should instead rely on an actual caching system. Popular options in the Rails ecosystem are memcached and Redis.

The procedure for configuring your cache store with Solidus is no different from doing it in a regular Rails application. Refer to the Rails caching guide for more details and recommendations on how to properly set up your caching server.

Async operations

Solidus schedules certain time-intensive operations in the background. This provides faster feedback to the user and avoids blocking the Web process for too long. The most common examples are transactional emails. When an email needs to be delivered to the user, Solidus will enqueue the operation rather than executing it immediately. This operation will then be run in the background by ActiveJob.

The default ActiveJob adapter is Async, which uses an in-process thread pool to schedule jobs. While Async is a good choice for local development and testing, it is a poor option for production deployments, as any pending jobs are dropped when the process restarts (Heroku restarts dynos automatically every 24 hours, for instance).

Instead, you should use a production-grade queue such as Sidekiq, which uses Redis for storing and retrieving your application's jobs under the hood. Using Sidekiq with ActiveJob is simple. First of all, install Sidekiq by adding it to your Gemfile:

Gemfile
# ...
gem 'sidekiq'

Now install the bundle:

$ bundle install

Finally, tell ActiveJob to use Sidekiq for queueing and running jobs:

config/application.rb
module YourApp
class Application < Rails::Application
# ...
config.active_job.queue_adapter = :sidekiq
end
end

That's it! Solidus will now use Sidekiq and Redis for all asynchronous processing. You may refer to the Sidekiq documentation and ActiveJob documentation for advanced configuration.

Content delivery network

It is strongly recommended to serve static assets via a Content Delivery Network (CDN) rather than your own application. CDNs are a relatively simple and efficient way to instantaneously boost the performance of your application, and are widely used in Web development.

As with many other tasks, configuring a CDN for Solidus is the same as configuring it for a regular Rails application, so you can refer to the Rails guides on configuring a CDN.

There are many reliable CDNs, with the most popular being Amazon CloudFront.

Email delivery

In order to send emails, Solidus needs a valid SMTP server. While you could use your domain registrar's mail server, it is usually recommended to use a more robust and feature-complete solution that will also provide useful insights and business metrics like deliverability, open, and click-through rates.

‚ÄčSendGrid, Mailgun and Mailchimp are all very good, battle-tested solutions for delivering transactional emails to your customers, but you are free to use any other service you wish.

Most of these services provide a regular SMTP server you can use to deliver emails, which you can configure in Rails. Here's an example configuration for SendGrid:

config/application.rb
module YourApp
class Application < Rails::Application
# ...
config.action_mailer.smtp_settings = {
user_name: ENV.fetch('SENDGRID_USERNAME'),
password: ENV.fetch('SENDGRID_PASSWORD'),
domain: ENV.fetch('SENDGRID_DOMAIN'),
address: 'smtp.sendgrid.net',
port: 465,
authentication: :plain,
enable_starttls_auto: true,
}
end
end

You should then configure the SENDGRID_USERNAME, SENDGRID_PASSWORD and SENDGRID_DOMAIN environment variables with your SendGrid credentials.