rails-nginx 1.0.0.pre.alpha
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 +7 -0
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +72 -0
- data/lib/puma/plugin/rails_nginx.rb +69 -0
- data/lib/rails/nginx/nginx.conf.erb +104 -0
- data/lib/rails/nginx/version.rb +7 -0
- data/lib/rails/nginx.rb +63 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 15c1730eca41e2227f246633756a27130a5e4c5bf87796a9a88893357be441a4
|
4
|
+
data.tar.gz: a372053d911522bf503522ebed38b8a2605bd91032541210a5ffd8092d02d88d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 83d060932d2b1c76be3081b280525e893f918e0d10350827e67add23352d0c0da1eb25a8d2ccfb7c3e47626154b4199000ef0913a0744952f5696b78b09f86f4
|
7
|
+
data.tar.gz: a4314d08cbb951387f5a20420187f91916f841aa355752e55180c11e2a66fd3e5042a6124630ab44302d0e8cfafeb02c3bbc0af6795af53fd384a625b3704f4b
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 Bert McCutchen
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# Rails NGINX
|
2
|
+
|
3
|
+
Automatically configure NGINX with SSL upon boot for Rails applications.
|
4
|
+
|
5
|
+
1. ERB for NGINX configuration templating.
|
6
|
+
2. Mkcert for SSL certificate generation.
|
7
|
+
3. Tried and true NGINX for reverse proxying.
|
8
|
+
|
9
|
+
This gem is intended to be an aid to your development environment. **Don't use this in production.**
|
10
|
+
|
11
|
+
[](https://ko-fi.com/M4M76DVZR)
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Install via Bundler:
|
16
|
+
```bash
|
17
|
+
bundle add rails-nginx
|
18
|
+
```
|
19
|
+
|
20
|
+
Or install it manually:
|
21
|
+
```bash
|
22
|
+
gem install rails-nginx
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
### config/puma.rb
|
28
|
+
```ruby
|
29
|
+
port ENV.fetch('PORT') { 3000 } unless Rails.env.development?
|
30
|
+
|
31
|
+
plugin :rails_nginx if Rails.env.development?
|
32
|
+
|
33
|
+
# All configuration is entirely optional, the following blocks are not required.
|
34
|
+
rails_nginx_config(:primary) do |config|
|
35
|
+
config[:domain] = 'route1.spline-reticulator.test' # default eg. rails-app-name.test
|
36
|
+
config[:host] = '0.0.0.0' # default '127.0.0.1'
|
37
|
+
config[:root_path] = './public' # default `Rails.public_path`
|
38
|
+
config[:ssl] = false # default true
|
39
|
+
config[:log] = false # default true
|
40
|
+
|
41
|
+
# default location Rails.root + tmp/nginx/
|
42
|
+
config[:ssl_certificate_path] = './tmp/certs/_spline-reticulator.test.pem'
|
43
|
+
config[:ssl_certificate_key_path] = './tmp/certs/_spline-reticulator-key.test.pem'
|
44
|
+
|
45
|
+
# default location Rails.root + log/nginx/
|
46
|
+
config[:access_log_path] = './log/route1.nginx.access.log'
|
47
|
+
config[:error_log_path] = './log/route1.nginx.error.log'
|
48
|
+
end
|
49
|
+
|
50
|
+
# You can define multiple configurations and all will be created on puma boot.
|
51
|
+
rails_nginx_config(:secondary) do |config|
|
52
|
+
config.merge!(rails_nginx_config(:primary))
|
53
|
+
|
54
|
+
config[:domain] = 'route2.spline-reticulator.test'
|
55
|
+
config[:access_log_path] = './log/route2.nginx.access.log'
|
56
|
+
config[:error_log_path] = './log/route2.nginx.error.log'
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
## Development
|
61
|
+
|
62
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
63
|
+
|
64
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
65
|
+
|
66
|
+
## Contributing
|
67
|
+
|
68
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/bert-mccutchen/rails-nginx.
|
69
|
+
|
70
|
+
## License
|
71
|
+
|
72
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "puma/plugin"
|
4
|
+
require_relative "../../rails/nginx"
|
5
|
+
|
6
|
+
# The Puma team recommends this approach to extend the Puma DSL.
|
7
|
+
# @see https://github.com/puma/puma/discussions/3173
|
8
|
+
module Puma
|
9
|
+
class DSL
|
10
|
+
def rails_nginx_configs
|
11
|
+
@rails_nginx_configs ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def rails_nginx_config(name = :primary)
|
15
|
+
rails_nginx_configs[name] ||= {}
|
16
|
+
yield rails_nginx_configs[name] if block_given?
|
17
|
+
rails_nginx_configs[name]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# The Rails server command's port will override ENV['PORT'] out of the box.
|
23
|
+
# However, Rails itself does not reasign back to ENV['PORT'].
|
24
|
+
def rails_port!
|
25
|
+
rails_port = Rails::Command::ServerCommand.new([], ARGV).options[:port]
|
26
|
+
ENV["PORT"] = rails_port.to_s if rails_port
|
27
|
+
end
|
28
|
+
|
29
|
+
Puma::Plugin.create do
|
30
|
+
def config(puma_config) # rubocop:disable Metrics/MethodLength
|
31
|
+
rails_port!
|
32
|
+
|
33
|
+
puma_config.port Rails::Nginx.port
|
34
|
+
|
35
|
+
puma_config.on_booted do
|
36
|
+
if puma_config.rails_nginx_configs.empty?
|
37
|
+
Rails::Nginx.start!
|
38
|
+
else
|
39
|
+
puma_config.rails_nginx_configs.each_value do |options|
|
40
|
+
Rails::Nginx.start!(options)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
puma_config.on_restart do
|
46
|
+
if puma_config.rails_nginx_configs.empty?
|
47
|
+
Rails::Nginx.stop!
|
48
|
+
Rails::Nginx.start!
|
49
|
+
else
|
50
|
+
puma_config.rails_nginx_configs.each_value do |options|
|
51
|
+
Rails::Nginx.stop!(options)
|
52
|
+
Rails::Nginx.start!(options)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if defined?(puma_config.on_stopped) # rubocop:disable Style/GuardClause
|
58
|
+
puma_config.on_stopped do
|
59
|
+
if puma_config.rails_nginx_configs.empty?
|
60
|
+
Rails::Nginx.stop!
|
61
|
+
else
|
62
|
+
puma_config.rails_nginx_configs.each_value do |options|
|
63
|
+
Rails::Nginx.stop!(options)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# Generic and NGINX configuration file for a Rails application.
|
2
|
+
# https://www.digitalocean.com/community/tools/nginx
|
3
|
+
|
4
|
+
map $http_upgrade $connection_upgrade {
|
5
|
+
default upgrade;
|
6
|
+
'' close;
|
7
|
+
}
|
8
|
+
|
9
|
+
map $remote_addr $proxy_forwarded_elem {
|
10
|
+
# IPv4 addresses can be sent as-is
|
11
|
+
~^[0-9.]+$ "for=$remote_addr";
|
12
|
+
|
13
|
+
# IPv6 addresses need to be bracketed and quoted
|
14
|
+
~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\"";
|
15
|
+
|
16
|
+
# Unix domain socket names cannot be represented in RFC 7239 syntax
|
17
|
+
default "for=unknown";
|
18
|
+
}
|
19
|
+
|
20
|
+
map $http_forwarded $proxy_add_forwarded {
|
21
|
+
# If the incoming Forwarded header is syntactically valid, append to it
|
22
|
+
"~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*([ \\t]*,([ \\t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*)?)*$" "$http_forwarded, $proxy_forwarded_elem";
|
23
|
+
|
24
|
+
# Otherwise, replace it
|
25
|
+
default "$proxy_forwarded_elem";
|
26
|
+
}
|
27
|
+
|
28
|
+
upstream <%= name %> {
|
29
|
+
server 127.0.0.1:<%= options[:port] %> fail_timeout=0;
|
30
|
+
}
|
31
|
+
|
32
|
+
server {
|
33
|
+
listen 80;
|
34
|
+
server_name <%= options[:domain] %>;
|
35
|
+
root <%= options[:root_path] %>;
|
36
|
+
try_files $uri/index.html $uri @<%= name %>;
|
37
|
+
|
38
|
+
<% if options[:ssl] %>
|
39
|
+
# ssl
|
40
|
+
listen 443 ssl;
|
41
|
+
http2 on;
|
42
|
+
ssl_certificate <%= options[:ssl_certificate_path] %>;
|
43
|
+
ssl_certificate_key <%= options[:ssl_certificate_key_path] %>;
|
44
|
+
<% end %>
|
45
|
+
|
46
|
+
<% if options[:log] %>
|
47
|
+
# logging
|
48
|
+
access_log <%= options[:access_log_path] %> combined buffer=512k flush=1m;
|
49
|
+
error_log <%= options[:error_log_path] %> warn;
|
50
|
+
<% end %>
|
51
|
+
|
52
|
+
# ect.
|
53
|
+
large_client_header_buffers 4 16k;
|
54
|
+
client_max_body_size 4G;
|
55
|
+
keepalive_timeout 75s;
|
56
|
+
|
57
|
+
# reverse proxy
|
58
|
+
location @<%= name %> {
|
59
|
+
proxy_pass http://<%= name %>;
|
60
|
+
proxy_http_version 1.1;
|
61
|
+
proxy_cache_bypass $http_upgrade;
|
62
|
+
|
63
|
+
<% if options[:ssl] %>
|
64
|
+
# proxy SSL
|
65
|
+
proxy_ssl_server_name on;
|
66
|
+
<% end %>
|
67
|
+
|
68
|
+
# proxy headers
|
69
|
+
proxy_set_header Host $host;
|
70
|
+
proxy_set_header Upgrade $http_upgrade;
|
71
|
+
proxy_set_header Connection $connection_upgrade;
|
72
|
+
proxy_set_header X-Real-IP $remote_addr;
|
73
|
+
proxy_set_header Forwarded $proxy_add_forwarded;
|
74
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
75
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
76
|
+
proxy_set_header X-Forwarded-Host $host;
|
77
|
+
proxy_set_header X-Forwarded-Port $server_port;
|
78
|
+
}
|
79
|
+
|
80
|
+
location ^~ /assets/ {
|
81
|
+
proxy_pass http://<%= name %>;
|
82
|
+
proxy_http_version 1.1;
|
83
|
+
proxy_cache_bypass $http_upgrade;
|
84
|
+
|
85
|
+
<% if options[:ssl] %>
|
86
|
+
# proxy SSL
|
87
|
+
proxy_ssl_server_name on;
|
88
|
+
<% end %>
|
89
|
+
|
90
|
+
# proxy headers
|
91
|
+
proxy_set_header Host $host;
|
92
|
+
proxy_set_header Upgrade $http_upgrade;
|
93
|
+
proxy_set_header Connection $connection_upgrade;
|
94
|
+
proxy_set_header X-Real-IP $remote_addr;
|
95
|
+
proxy_set_header Forwarded $proxy_add_forwarded;
|
96
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
97
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
98
|
+
proxy_set_header X-Forwarded-Host $host;
|
99
|
+
proxy_set_header X-Forwarded-Port $server_port;
|
100
|
+
|
101
|
+
add_header Cache-Control public;
|
102
|
+
add_header Access-Control-Allow-Origin *;
|
103
|
+
}
|
104
|
+
}
|
data/lib/rails/nginx.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "socket"
|
4
|
+
require "ruby/nginx"
|
5
|
+
|
6
|
+
module Rails
|
7
|
+
module Nginx
|
8
|
+
class Error < StandardError; end
|
9
|
+
|
10
|
+
def self.port
|
11
|
+
ENV["PORT"] ||= Addrinfo.tcp("127.0.0.1", 0).bind { |s| s.local_address.ip_port }.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.start!(options = {}, &block)
|
15
|
+
return unless rails_server?
|
16
|
+
|
17
|
+
config = Ruby::Nginx.add!(options.reverse_merge(defaults(options)), &block)
|
18
|
+
|
19
|
+
puts start_message(config.options) # rubocop:disable Rails/Output
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.stop!(options = {}, &block)
|
23
|
+
return unless rails_server?
|
24
|
+
|
25
|
+
Ruby::Nginx.remove!(options.reverse_merge(defaults(options)), &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def self.rails_server?
|
31
|
+
defined?(Rails::Server)
|
32
|
+
end
|
33
|
+
private_class_method :rails_server?
|
34
|
+
|
35
|
+
def self.defaults(options)
|
36
|
+
domain = options[:domain] || "#{Rails.application.class.module_parent.name.underscore.dasherize}.test"
|
37
|
+
|
38
|
+
{
|
39
|
+
domain: domain,
|
40
|
+
port: port,
|
41
|
+
root_path: Rails.public_path,
|
42
|
+
ssl: true,
|
43
|
+
log: true,
|
44
|
+
ssl_certificate_path: Rails.root.join("tmp/nginx/_#{domain}.pem"),
|
45
|
+
ssl_certificate_key_path: Rails.root.join("tmp/nginx/_#{domain}-key.pem"),
|
46
|
+
access_log_path: Rails.root.join("log/nginx/#{domain}.access.log"),
|
47
|
+
error_log_path: Rails.root.join("log/nginx/#{domain}.error.log")
|
48
|
+
}
|
49
|
+
end
|
50
|
+
private_class_method :defaults
|
51
|
+
|
52
|
+
def self.start_message(config)
|
53
|
+
message = ["* Rails NGINX version: #{Rails::Nginx::VERSION}"]
|
54
|
+
message << "* HTTP Endpoint: http://#{config[:domain]}"
|
55
|
+
message << "* HTTPS Endpoint: https://#{config[:domain]}" if config[:ssl]
|
56
|
+
message << "* Access Log: #{config[:access_log_path]}" if config[:log]
|
57
|
+
message << "* Error Log: #{config[:error_log_path]}" if config[:log]
|
58
|
+
message << "* Upstreaming to http://#{config[:host]}:#{config[:port]}"
|
59
|
+
message.join("\n")
|
60
|
+
end
|
61
|
+
private_class_method :start_message
|
62
|
+
end
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails-nginx
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.pre.alpha
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bert McCutchen
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-11-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: puma
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ruby-nginx
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Automatically configure NGINX with SSL upon boot for Rails applications.
|
56
|
+
email:
|
57
|
+
- mail@bertm.dev
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- CHANGELOG.md
|
63
|
+
- LICENSE.txt
|
64
|
+
- README.md
|
65
|
+
- lib/puma/plugin/rails_nginx.rb
|
66
|
+
- lib/rails/nginx.rb
|
67
|
+
- lib/rails/nginx/nginx.conf.erb
|
68
|
+
- lib/rails/nginx/version.rb
|
69
|
+
homepage: https://github.com/bert-mccutchen/rails-nginx
|
70
|
+
licenses:
|
71
|
+
- MIT
|
72
|
+
metadata:
|
73
|
+
homepage_uri: https://github.com/bert-mccutchen/rails-nginx
|
74
|
+
source_code_uri: https://github.com/bert-mccutchen/rails-nginx
|
75
|
+
changelog_uri: https://github.com/bert-mccutchen/rails-nginx/blob/main/CHANGELOG.md
|
76
|
+
rubygems_mfa_required: 'true'
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 3.0.0
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubygems_version: 3.5.22
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Automatic NGINX+SSL configuration for Rails.
|
96
|
+
test_files: []
|