Skip to content

feat: single-domain deployment mode for self-hosted/Docker#121

Merged
ManukMinasyan merged 15 commits intomainfrom
feat/single-domain-deployment
Feb 15, 2026
Merged

feat: single-domain deployment mode for self-hosted/Docker#121
ManukMinasyan merged 15 commits intomainfrom
feat/single-domain-deployment

Conversation

@ManukMinasyan
Copy link
Copy Markdown
Contributor

@ManukMinasyan ManukMinasyan commented Feb 15, 2026

Summary

Closes #69

  • Adds configurable domain/path routing for the app panel, enabling self-hosted and Docker deployments without subdomain requirements
  • Path mode (default): Panel serves at /app — zero config needed for Docker/self-hosted
  • Domain mode (opt-in): Set APP_PANEL_DOMAIN=app.example.com for subdomain routing (SaaS)
  • Mirrors the existing SystemAdminPanelProvider pattern (if domain → domain, else → path)

Changes

  • config/app.php — new app_panel_domain / app_panel_path config keys
  • AppPanelProvider.php — conditional domain/path using if/else (not both)
  • MacroServiceProvider.phpgetAppUrl() macro is now routing-mode-aware with port support
  • routes/web.phpredirect()->away()redirect()->to(), fix boot-time /dashboard evaluation
  • config/login-link.php — conditional allowed hosts
  • .env.example / docker-compose.prod.yml — document new env vars

SaaS migration

One line in production .env:

APP_PANEL_DOMAIN=app.relaticle.com

Test plan

  • 20 routing tests covering path mode, domain mode, edge cases (ports, IPs, nested paths, leading slashes)
  • Panel configuration tests verify getDomains() / getPath() match expected state
  • Integration tests verify login page reachable at panel path
  • Auth redirect tests verify /login, /register, /forgot-password, /dashboard
  • Full test suite: 685 passed, 0 failures
  • PHPStan: no errors
  • Pint: clean
  • Manual: verify APP_PANEL_DOMAIN=app.relaticle.test serves panel at subdomain root
  • Manual: verify default (no domain) serves panel at /app

Copilot AI review requested due to automatic review settings February 15, 2026 23:14
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds configurable domain/path routing for the application panel, enabling self-hosted and Docker deployments without subdomain requirements. The changes follow the existing pattern used by the SystemAdmin panel (if domain config exists, use ->domain(), else use ->path()).

Changes:

  • Adds path-based routing as the default mode (panel served at /app)
  • Adds optional domain-based routing via APP_PANEL_DOMAIN environment variable
  • Updates URL generation macros to be routing-mode-aware
  • Fixes route redirect behavior to work correctly in both modes
  • Adds comprehensive test coverage for both routing modes

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/Feature/Routing/AppPanelRoutingTest.php New comprehensive test suite covering path mode, domain mode, panel configuration, URL generation, and authentication redirects
tests/Feature/Public/PublicPagesTest.php Updates test descriptions from "subdomain" to "app panel" for clarity
routes/web.php Fixes redirects to use redirect()->to() instead of redirect()->away() and makes /dashboard redirect evaluate at request time
docker-compose.prod.yml Documents new APP_PANEL_DOMAIN environment variable
config/login-link.php Updates allowed hosts to include configurable app panel domain
config/app.php Adds app_panel_domain and app_panel_path configuration keys with documentation
app/Providers/MacroServiceProvider.php Updates getAppUrl() macro to support both domain and path routing modes
app/Providers/Filament/AppPanelProvider.php Implements conditional domain/path configuration following existing SystemAdmin pattern
.env.example Documents new APP_PANEL_DOMAIN and APP_PANEL_PATH configuration options
Comments suppressed due to low confidence (1)

app/Providers/MacroServiceProvider.php:32

  • The getPublicUrl macro doesn't preserve the port from APP_URL. If APP_URL is http://localhost:8080, the generated URL will be http://localhost/ instead of http://localhost:8080/.

The parsed URL components should include the port when building the final URL. Consider using the full parsed URL or explicitly handling the port component.

        URL::macro('getPublicUrl', function (string $path = ''): string {
            $baseUrl = config('app.url');
            $parsed = parse_url((string) $baseUrl);
            $scheme = $parsed['scheme'] ?? 'https';
            $host = $parsed['host'] ?? 'localhost';

            return $scheme.'://'.$host.'/'.ltrim($path, '/');

@ManukMinasyan ManukMinasyan merged commit 79afee3 into main Feb 15, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Single-Domain Deployment Mode for Relaticle

2 participants