Skip to content

Commit f5ef3f0

Browse files
kcdragonclaude
andauthored
Resolve org subdomains under the community-foundations apex (#32)
Production fell back to Rails' default tld_length = 1, so it treated rowhomelabs.com as the domain and mis-parsed every request: the apex became request.subdomain "community-foundations" (404 instead of the landing page) and "arlington.community-foundations.rowhomelabs.com" became "arlington.community-foundations" (no matching org). Set tld_length = 2 so the apex is the domain and org subdomains resolve correctly, enable config.hosts for the apex plus org subdomains (with a /up health-check exclusion), and list each org host in the kamal proxy so it issues a per-host Let's Encrypt cert. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent ed9ddcb commit f5ef3f0

2 files changed

Lines changed: 21 additions & 9 deletions

File tree

config/deploy.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@ servers:
2020
#
2121
# Don't use this when deploying to multiple web servers (then you have to terminate SSL at your load balancer).
2222
#
23+
# Each org is served from its own subdomain of the apex. List every host so the proxy
24+
# requests a Let's Encrypt cert for each. Add a new line here when an org is onboarded.
2325
proxy:
2426
ssl: true
25-
host: community-foundations.rowhomelabs.com
27+
hosts:
28+
- community-foundations.rowhomelabs.com
29+
- arlington.community-foundations.rowhomelabs.com
2630

2731
# Where you keep your container images.
2832
registry:

config/environments/production.rb

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@
5757
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
5858
# config.action_mailer.raise_delivery_errors = false
5959

60+
# The app's apex (community-foundations.rowhomelabs.com) is itself two labels below the
61+
# registered domain (rowhomelabs.com), so treat those two labels plus the TLD as the domain.
62+
# Then "arlington.community-foundations.rowhomelabs.com" → request.subdomain == "arlington",
63+
# and the bare apex → "" (no tenant). Mirrors tld_length = 0 used for "localhost" in dev/test.
64+
config.action_dispatch.tld_length = 2
65+
6066
# Set host to be used by links generated in mailer templates.
6167
config.action_mailer.default_url_options = { host: "community-foundations.rowhomelabs.com" }
6268

@@ -79,12 +85,14 @@
7985
# Only use :id for inspections in production.
8086
config.active_record.attributes_for_inspect = [ :id ]
8187

82-
# Enable DNS rebinding protection and other `Host` header attacks.
83-
# config.hosts = [
84-
# "example.com", # Allow requests from example.com
85-
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
86-
# ]
87-
#
88-
# Skip DNS rebinding protection for the default health check endpoint.
89-
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
88+
# Enable DNS rebinding protection and other `Host` header attacks. Allow the apex (landing
89+
# page) plus any org subdomain like "arlington.community-foundations.rowhomelabs.com".
90+
config.hosts = [
91+
"community-foundations.rowhomelabs.com",
92+
/\A[a-z0-9-]+\.community-foundations\.rowhomelabs\.com\z/, # org subdomains
93+
]
94+
95+
# Skip DNS rebinding protection for the default health check endpoint (kamal-proxy hits
96+
# "/up" directly on the container, without the public Host header).
97+
config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
9098
end

0 commit comments

Comments
 (0)