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:
my-app.localhost
tells Caddy to handle requests for this domaintls internal
automatically generates a self-signed certificate for HTTPSreverse_proxy localhost:3000
forwards all requests to your Rails server running on port 3000
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:
- Tool management: Automatically installs and manages the correct version of Caddy for your project
- Environment consistency: The
APP_HOST
environment variable ensures your Rails configuration matches your Caddy setup - Team coordination: Team members get the same tools and configuration when they run
mise install
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.