rails_caddy_dev 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +22 -8
- data/bin/rails_caddy_dev +47 -3
- data/lib/rails_caddy_dev/commands.rb +4 -4
- data/lib/rails_caddy_dev/update_config.rb +16 -12
- data/lib/rails_caddy_dev/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a8fe9678c7487626f988b63e3b205916e386179605835d7eed6699ee9be9aff4
|
|
4
|
+
data.tar.gz: ace04b2d24135e1b3d121a5af921ce68eb1186888b77857d9fecc8c733fbf9df
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7b56f5687870f5e41ff56523508ed1a968068f75b8b6baebd4b75c2c0513feac58e2ea8106893ca67de61f20cc69263d8393b7ceb070e49bf3fec26e472aa85
|
|
7
|
+
data.tar.gz: cf9046f2aa1d912fb3a37c48ee7a04cc173f164a22088931caf99f7721311fee3b228ff75a66559512212aa664a95617b2692fea84c423f6ddf1501f6f728555
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# RailsCaddyDev
|
|
2
2
|
|
|
3
|
-
Automatically configures [Caddy](https://caddyserver.com/) as a local reverse proxy for Rails development. When you start `rails server`, it registers routes via the Caddy admin API so that `<
|
|
3
|
+
Automatically configures [Caddy](https://caddyserver.com/) as a local reverse proxy for Rails development. When you start `rails server`, it registers routes via the Caddy admin API so that `<domain>.localhost` proxies to your locally running Rails server with HTTPS.
|
|
4
4
|
|
|
5
5
|
## Prerequisites
|
|
6
6
|
|
|
@@ -32,27 +32,31 @@ require "rails/commands"
|
|
|
32
32
|
with this:
|
|
33
33
|
|
|
34
34
|
```ruby
|
|
35
|
-
require "rails_caddy_dev/commands"
|
|
35
|
+
require ENV.key?('RAILS_CADDY_DEV') ? "rails_caddy_dev/commands" : "rails/commands"
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
This will ensure your Caddy configuration is updated each time you start your Rails server in development.
|
|
39
39
|
|
|
40
40
|
## Usage
|
|
41
41
|
|
|
42
|
-
Start your Rails server with the `
|
|
42
|
+
Start your Rails server with the `RAILS_CADDY_DEV` environment variable set:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
-
|
|
45
|
+
RAILS_CADDY_DEV=1 rails server
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
This will configure Caddy to proxy
|
|
48
|
+
This will configure Caddy to proxy `<dirname>.localhost` (where `<dirname>` is the basename of your Rails root) to your Rails server, accessible over HTTPS. To use a different hostname, set `RAILS_CADDY_DEV_DOMAIN`:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
RAILS_CADDY_DEV=1 RAILS_CADDY_DEV_DOMAIN=myapp rails server
|
|
52
|
+
```
|
|
49
53
|
|
|
50
54
|
### Environment Variables
|
|
51
55
|
|
|
52
56
|
| Variable | Description | Default |
|
|
53
57
|
|---|---|---|
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
58
|
+
| `RAILS_CADDY_DEV` | Enables Caddy configuration (must be set) | — |
|
|
59
|
+
| `RAILS_CADDY_DEV_DOMAIN` | Used to derive the `.localhost` hostname | Basename of the current working directory |
|
|
56
60
|
| `PORT` | Rails server port to proxy to | Auto-detected available port (falls back to `3000`) |
|
|
57
61
|
| `CADDY_HOST` | Caddy admin API host | `localhost` |
|
|
58
62
|
| `CADDY_PORT` | Caddy admin API port | `2019` |
|
|
@@ -69,7 +73,17 @@ export PORT=$(bundle exec rails_caddy_dev port)
|
|
|
69
73
|
|
|
70
74
|
### Subdomains
|
|
71
75
|
|
|
72
|
-
Subdomains are also supported due to a wildcard Caddy route that will be configured. For example, if
|
|
76
|
+
Subdomains are also supported due to a wildcard Caddy route that will be configured. For example, if the resolved domain is `myapp`, then `api.myapp.localhost` will also proxy to your Rails server.
|
|
77
|
+
|
|
78
|
+
### Removing a Route
|
|
79
|
+
|
|
80
|
+
To remove the Caddy route for the current project, run:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
bundle exec rails_caddy_dev delete
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This deletes the route registered for `RAILS_CADDY_DEV_DOMAIN` (or the current directory's basename if unset).
|
|
73
87
|
|
|
74
88
|
## Development
|
|
75
89
|
|
data/bin/rails_caddy_dev
CHANGED
|
@@ -1,11 +1,55 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
require 'net/http'
|
|
5
|
+
require 'socket'
|
|
6
|
+
|
|
7
|
+
def resolve_domain
|
|
8
|
+
domain = ENV.fetch('RAILS_CADDY_DEV_DOMAIN') { File.basename(Dir.pwd) }
|
|
9
|
+
domain = File.basename(Dir.pwd) if domain.strip.empty?
|
|
10
|
+
domain.downcase
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
case ARGV[0]
|
|
14
|
+
when 'port'
|
|
6
15
|
puts(Addrinfo.tcp('', 0).bind { |s| s.local_address.ip_port })
|
|
7
16
|
exit 0
|
|
17
|
+
when 'delete'
|
|
18
|
+
domain = resolve_domain
|
|
19
|
+
caddy_host = ENV.fetch('CADDY_HOST', 'localhost')
|
|
20
|
+
caddy_port = ENV.fetch('CADDY_PORT', '2019').to_i
|
|
21
|
+
|
|
22
|
+
if !ARGV[1..].intersect?(%w[-y --yes])
|
|
23
|
+
print "Delete Caddy route for '#{domain}'? [y/N] "
|
|
24
|
+
answer = $stdin.gets&.strip&.downcase
|
|
25
|
+
if !%w[y yes].include?(answer)
|
|
26
|
+
puts 'Aborted.'
|
|
27
|
+
exit 1
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
uri = URI("http://#{caddy_host}:#{caddy_port}/id/#{domain}")
|
|
32
|
+
begin
|
|
33
|
+
response = Net::HTTP.start(uri.host, uri.port) do |http|
|
|
34
|
+
http.request(Net::HTTP::Delete.new(uri.path))
|
|
35
|
+
end
|
|
36
|
+
rescue Errno::ECONNREFUSED
|
|
37
|
+
puts "⚠️ Caddy admin API not available at #{caddy_host}:#{caddy_port}. Is caddy running?"
|
|
38
|
+
exit 1
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
case response
|
|
42
|
+
when Net::HTTPSuccess
|
|
43
|
+
puts "=> Caddy config for '#{domain}' deleted"
|
|
44
|
+
when Net::HTTPNotFound
|
|
45
|
+
puts "=> No Caddy config found for '#{domain}'"
|
|
46
|
+
else
|
|
47
|
+
puts "=! Failed to delete Caddy config: #{response.body}"
|
|
48
|
+
exit 1
|
|
49
|
+
end
|
|
8
50
|
else
|
|
9
|
-
puts 'Usage:
|
|
51
|
+
puts 'Usage:'
|
|
52
|
+
puts ' rails_caddy_dev port # print an available TCP port'
|
|
53
|
+
puts ' rails_caddy_dev delete [-y|--yes] # remove the Caddy route'
|
|
10
54
|
exit 1
|
|
11
55
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# This file is responsible for loading the Caddy configuration update logic when the Rails server is
|
|
4
|
-
# started in development mode with the
|
|
5
|
-
# the application's 'bin/rails' file, as a replacement for the default
|
|
6
|
-
# line, making it look something like this:
|
|
4
|
+
# started in development mode with the RAILS_CADDY_DEV environment variable set. It should be
|
|
5
|
+
# required from the application's 'bin/rails' file, as a replacement for the default
|
|
6
|
+
# 'require "rails/commands"' line, making it look something like this:
|
|
7
7
|
#
|
|
8
8
|
# #!/usr/bin/env ruby
|
|
9
9
|
#
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# require "rails_caddy_dev/commands" # <-- This line is added to load the Caddy config logic
|
|
15
15
|
#
|
|
16
16
|
if ENV.fetch('RAILS_ENV', 'development') == 'development' &&
|
|
17
|
-
ENV.key?('
|
|
17
|
+
ENV.key?('RAILS_CADDY_DEV') &&
|
|
18
18
|
%w[s server].include?(ARGV.first)
|
|
19
19
|
require 'rails_caddy_dev/update_config'
|
|
20
20
|
end
|
|
@@ -3,18 +3,20 @@
|
|
|
3
3
|
# Configures Caddy as a local reverse proxy to your Rails server during development.
|
|
4
4
|
#
|
|
5
5
|
# Uses the Caddy admin API to register a 'route' configuration that proxies requests for
|
|
6
|
-
# `<
|
|
6
|
+
# `<domain>.localhost` to the locally running Rails server.
|
|
7
7
|
#
|
|
8
8
|
# This file is intended to be run as part of the `rails server` startup process, and will only
|
|
9
|
-
# execute in the development environment, and when the `
|
|
9
|
+
# execute in the development environment, and when the `RAILS_CADDY_DEV` environment variable is
|
|
10
|
+
# set.
|
|
10
11
|
#
|
|
11
12
|
# The script checks if a Caddy config for the project already exists by querying the admin API. If
|
|
12
13
|
# it does, it sends a PATCH request to update it; if not, it attempts to append a new route to the
|
|
13
14
|
# existing config or initialize a new config structure if necessary.
|
|
14
15
|
#
|
|
15
16
|
# The script accepts the following environment variables:
|
|
16
|
-
# -
|
|
17
|
-
#
|
|
17
|
+
# - RAILS_CADDY_DEV_DOMAIN: Used to derive subdomain hostnames (e.g. "my_project" →
|
|
18
|
+
# my_project.localhost). Defaults to the basename of the current working directory when unset
|
|
19
|
+
# or blank.
|
|
18
20
|
# - PORT: Rails server port (defaults to an available port if not set, or 3000 if port detection
|
|
19
21
|
# fails)
|
|
20
22
|
# - CADDY_HOST: Caddy admin API host (default: localhost)
|
|
@@ -27,7 +29,7 @@ require 'net/http'
|
|
|
27
29
|
require 'json'
|
|
28
30
|
require 'socket'
|
|
29
31
|
|
|
30
|
-
return if ENV.fetch('RAILS_ENV', 'development') != 'development' || !ENV.key?('
|
|
32
|
+
return if ENV.fetch('RAILS_ENV', 'development') != 'development' || !ENV.key?('RAILS_CADDY_DEV')
|
|
31
33
|
|
|
32
34
|
PORT = ENV['PORT'] = ENV.fetch('PORT') do
|
|
33
35
|
Addrinfo.tcp('', 0).bind { |s| s.local_address.ip_port }&.to_s || '3000'
|
|
@@ -35,15 +37,17 @@ end
|
|
|
35
37
|
|
|
36
38
|
CADDY_HOST = ENV.fetch('CADDY_HOST', 'localhost')
|
|
37
39
|
CADDY_PORT = ENV.fetch('CADDY_PORT', '2019').to_i
|
|
38
|
-
|
|
40
|
+
domain = ENV.fetch('RAILS_CADDY_DEV_DOMAIN') { File.basename(Dir.pwd) }
|
|
41
|
+
domain = File.basename(Dir.pwd) if domain.strip.empty?
|
|
42
|
+
DOMAIN = ENV['RAILS_CADDY_DEV_DOMAIN'] = domain.downcase
|
|
39
43
|
|
|
40
44
|
domains = [
|
|
41
|
-
"#{
|
|
42
|
-
"*.#{
|
|
45
|
+
"#{DOMAIN}.localhost",
|
|
46
|
+
"*.#{DOMAIN}.localhost"
|
|
43
47
|
]
|
|
44
48
|
|
|
45
49
|
# Check if config already exists via Caddy API
|
|
46
|
-
uri = URI("http://#{CADDY_HOST}:#{CADDY_PORT}/id/#{
|
|
50
|
+
uri = URI("http://#{CADDY_HOST}:#{CADDY_PORT}/id/#{DOMAIN}")
|
|
47
51
|
config_exists = false
|
|
48
52
|
begin
|
|
49
53
|
response = Net::HTTP.get_response(uri)
|
|
@@ -54,7 +58,7 @@ rescue Errno::ECONNREFUSED
|
|
|
54
58
|
end
|
|
55
59
|
|
|
56
60
|
config = {
|
|
57
|
-
'@id':
|
|
61
|
+
'@id': DOMAIN,
|
|
58
62
|
handle: [
|
|
59
63
|
{
|
|
60
64
|
handler: 'subroute',
|
|
@@ -87,7 +91,7 @@ http = Net::HTTP.new(CADDY_HOST, CADDY_PORT)
|
|
|
87
91
|
|
|
88
92
|
if config_exists
|
|
89
93
|
# Update existing config via @id endpoint
|
|
90
|
-
request = Net::HTTP::Patch.new("/id/#{
|
|
94
|
+
request = Net::HTTP::Patch.new("/id/#{DOMAIN}", 'Content-Type' => 'application/json')
|
|
91
95
|
request.body = config.to_json
|
|
92
96
|
action = 'updated'
|
|
93
97
|
else
|
|
@@ -121,7 +125,7 @@ end
|
|
|
121
125
|
response = http.request(request)
|
|
122
126
|
|
|
123
127
|
if response.is_a?(Net::HTTPSuccess)
|
|
124
|
-
puts "=> Caddy config for '#{
|
|
128
|
+
puts "=> Caddy config for '#{DOMAIN}:#{PORT}' #{action}"
|
|
125
129
|
else
|
|
126
130
|
puts "=! Failed to #{action.chomp('d')} Caddy config: #{response.body}"
|
|
127
131
|
exit 1
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_caddy_dev
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joel Moss
|
|
@@ -62,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
62
62
|
- !ruby/object:Gem::Version
|
|
63
63
|
version: '0'
|
|
64
64
|
requirements: []
|
|
65
|
-
rubygems_version:
|
|
65
|
+
rubygems_version: 3.6.9
|
|
66
66
|
specification_version: 4
|
|
67
67
|
summary: Automatic Caddy config for Rails development.
|
|
68
68
|
test_files: []
|