Juanda

Setting Up Local HTTPS Development with Caddy and Rails

Modern web development often requires HTTPS even in local environments to properly test features like service workers, secure cookies, or third-party integrations. This guide shows you how to set up automatic HTTPS for your Rails application using Caddy as a reverse proxy.

Step 1: Configure Local Domain Resolution

Pick a localhost domain for your app. Anything that is *.localhost is resolved locally without the need to fiddle with the /etc/hosts file.

Step 2: Create Caddy Configuration

Create a Caddyfile at your project root to configure the reverse proxy:

# Caddyfile
my-app.localhost {
  tls internal
  reverse_proxy localhost:3000
}

Why this configuration works:

This setup means Caddy will handle SSL termination and pass clean HTTP requests to your Rails application.

Step 3: Update the Procfile

Modify your Procfile.dev to include Caddy:

web: bin/rails server
css: bin/rails tailwindcss:watch
caddy: caddy run

This ensures Caddy starts automatically alongside your Rails server when you run bin/dev (or your preferred process manager). Having all services start together creates a development experience where HTTPS is always available.

Step 4: Configure Rails Host Verification

Update your Rails application configuration to accept requests from your custom domain:

# config/application.rb
module MyApp
  class Application < Rails::Application
    # ... rest of the application.rb 
    config.hosts << ENV.fetch("APP_HOST")
  end
end

Why Rails needs this: Rails includes host header verification as a security feature to prevent DNS rebinding attacks. Since we're using a custom domain we need to explicitly allow it. Using an environment variable keeps this configuration flexible across different environments.

Step 5: Install Caddy and Set Environment Variables

Use mise (or your preferred tool manager) to install Caddy and configure the environment:

# mise.toml at the application root
[env]
APP_HOST = 'my-app.localhost'

[tools]
ruby = '3.4.3'
node = 'latest'
caddy = 'latest'

Why use mise for this setup:

Step 6: Trust the Caddy's CA root certificate

Caddy will ask for your password the first time you run it, so it can install the CA root in your system. This will eliminate any browser warnings regarding self-signed certificates. Alternatively, you can run caddy trust to install manually or caddy untrust to uninstall.

The Result

After completing these steps, you'll be able to access your Rails application at https://my-app.localhost with a valid SSL certificate. Your browser may show a security warning for the self-signed certificate, but you can safely proceed for development purposes.

This setup provides a production-like HTTPS environment that's essential for testing modern web features while maintaining the simplicity of local development.