Having a Rails local development environment with SSL/HTTPS support can be very handy. You can work with payment plaforms APIs, like Stripe or Apple Pay, without having to resort to tools like ngrok and you can increase development/production parity.

Puma configuration

You can configure Puma to use SSL only in development environment with a config/puma.rb file like this:

max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 5)
min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads min_threads_count, max_threads_count

nakayoshi_fork
wait_for_less_busy_worker
fork_worker

rails_env = ENV.fetch('RAILS_ENV', 'development')
rails_port = ENV.fetch('PORT', 3000)
environment rails_env
pidfile ENV.fetch('PIDFILE', 'tmp/pids/server.pid')

if rails_env == 'development'
  ssl_bind(
    '0.0.0.0',
    rails_port,
    key: ENV.fetch('SSL_KEY_FILE', 'config/certs/localhost-key.pem'),
    cert: ENV.fetch('SSL_CERT_FILE', 'config/certs/localhost.pem'),
    verify_mode: 'none'
  )
else
  port rails_port
end

plugin :tmp_restart

preload_app!

SSL certificates

To easily generate a self-signed and locally-trusted development SSL certificate for your Rails application, you can use mkcert.

Create and install a local Certification Authority:

mkcert -install

Create corresponding certificate and key files in the config/certs directory:

mkdir -p config/certs
mkcert -cert-file config/certs/localhost.pem -key-file config/certs/localhost-key.pem localhost

You can use mkcert to install the same development CA you’ve created on any other development box.

Copy the CA certificate to your application:

cp "$(mkcert -CAROOT)/rootCA.pem" config/certs

Install the same CA on another machine (you can add this step to your bin/setup script):

CAROOT=config/certs mkcert -install