Add subdirectory routing mode for public domain deployments

Apps can now be served at domain.com/appname/ instead of requiring
subdomain DNS records (appname.domain.com). Supports three subpath
modes per template: native (URL base env var), strip (handle_path),
and none (incompatible warning). Tested on Linux with deploy/removal
lifecycle verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 03:03:17 -08:00
parent f61e85d9a7
commit 77030931b7
13 changed files with 407 additions and 41 deletions

View File

@@ -104,6 +104,11 @@ window.populateTimezoneSelect = function(selectEl, selectedTz) {
} else if (currentConfigType === 'public') {
const domain = document.getElementById('setup-public-domain')?.value?.trim() || '';
const email = document.getElementById('setup-public-email')?.value?.trim() || '';
const routingMode = document.querySelector('input[name="routing-mode"]:checked')?.value || 'subdirectory';
const exampleUrls = routingMode === 'subdirectory'
? `https://${domain}/sonarr, https://${domain}/grafana`
: `https://sonarr.${domain}, https://grafana.${domain}`;
const routingLabel = routingMode === 'subdirectory' ? 'Subdirectory (domain.com/app)' : 'Subdomain (app.domain.com)';
html += `
<div>
@@ -112,7 +117,8 @@ window.populateTimezoneSelect = function(selectEl, selectedTz) {
<div><strong>Domain:</strong> ${domain}</div>
<div><strong>SSL:</strong> Let's Encrypt</div>
<div><strong>Email:</strong> ${email}</div>
<div><strong>Example URLs:</strong> https://app.${domain}, https://cloud.${domain}</div>
<div><strong>Routing:</strong> ${routingLabel}</div>
<div><strong>Example URLs:</strong> ${exampleUrls}</div>
</div>
</div>
`;
@@ -186,8 +192,9 @@ window.populateTimezoneSelect = function(selectEl, selectedTz) {
} else if (currentConfigType === 'public') {
config.domain = document.getElementById('setup-public-domain')?.value?.trim() || '';
config.email = document.getElementById('setup-public-email')?.value?.trim() || '';
config.routingMode = document.querySelector('input[name="routing-mode"]:checked')?.value || 'subdirectory';
config.defaults = {
dnsType: 'public',
dnsType: config.routingMode === 'subdirectory' ? 'none' : 'public',
sslType: 'letsencrypt',
targetIP: 'localhost'
};
@@ -311,6 +318,18 @@ window.populateTimezoneSelect = function(selectEl, selectedTz) {
};
}
// Public routing mode toggle — update requirement text
document.querySelectorAll('input[name="routing-mode"]').forEach(function(radio) {
radio.onchange = function() {
var note = document.getElementById('dns-requirement-note');
if (note) {
note.textContent = this.value === 'subdirectory'
? 'Only one DNS record needed (for the main domain)'
: 'You\'ll need to configure DNS manually for each subdomain';
}
};
});
// Public navigation
const publicBack = document.getElementById('setup-public-back');
if (publicBack) {