Skip to content

feat: add support for custom URL paths via BASE_URL configuration#1451

Open
roberfi wants to merge 1 commit intoplankanban:masterfrom
roberfi:support-url-paths
Open

feat: add support for custom URL paths via BASE_URL configuration#1451
roberfi wants to merge 1 commit intoplankanban:masterfrom
roberfi:support-url-paths

Conversation

@roberfi
Copy link

@roberfi roberfi commented Dec 7, 2025

Summary

Fixes #1156 and #1323

This PR adds support for deploying Planka under custom URL paths by extracting the path from the BASE_URL environment variable and injecting it into the client at runtime.

Problem

Previously, Planka could only be deployed at the root path (/). Users wanting to deploy it under a subpath (e.g., /planka) behind a reverse proxy had to rebuild the Docker image with build-time environment variables, which is not feasible for users pulling pre-built images.

Solution

Architecture Changes

  1. Runtime Configuration Injection

    • Created a bash script (inject-config-template.sh) that converts the Vite-built index.html into an EJS template
    • Added a new controller (index/show) that injects baseUrlPath from server config into the template
    • Client reads configuration from window.PLANKA_CONFIG at runtime
  2. Path Handling

    • Replaced build-time SERVER_BASE_URL with runtime BASE_PATH throughout the client
    • Updated all route definitions (Paths.js) to use the dynamic base path
    • Modified API and WebSocket paths to include the base path prefix
  3. Cookie Path Fix

    • Fixed authentication cookie paths to handle both root (/) and subpath deployments
    • Added fallback to '/' when baseUrlPath is empty to ensure valid cookie paths
    • Applied fix to both server-side (httpOnlyToken) and client-side (accessToken) cookies

Technical Details

Server changes:

  • server/config/custom.js: Extract and strip trailing slash from BASE_URL pathname
  • server/inject-config-template.sh: AWK script to inject EJS template into HTML (new file)
  • server/api/controllers/index/show.js: Controller that passes baseUrlPath to the view (new file)
  • server/config/routes.js: Changed index from direct view rendering to controller action
  • server/config/views.js: Changed extension from .html to .ejs
  • server/config/policies.js: Added public access policy for index/show controller
  • server/api/helpers/utils/set-http-only-token-cookie.js: Added || '/' fallback for cookie path

Client changes:

  • client/src/constants/Config.js: Read BASE_PATH from window.PLANKA_CONFIG.baseUrlPath at runtime
  • client/src/constants/Paths.js: Prepend BASE_PATH to all route definitions
  • client/src/api/http.js: Use BASE_PATH instead of SERVER_BASE_URL for API calls
  • client/src/api/socket.js: Configure Socket.IO path with BASE_PATH prefix
  • client/src/utils/access-token-storage.js: Set proper cookie paths with fallback to '/'
  • client/vite.config.js: Set base: './' for relative asset paths

Build changes:

  • Dockerfile: Transform index.html to index.ejs template during image build

Testing

Tested with the following nginx configuration:

server {
    listen      80;
    server_name localhost;

    location /planka/ {
        rewrite ^/planka(.*)$ $1 break;
        proxy_pass http://127.0.0.1:3000/;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Prefix /planka;
    }
}

And this BASE_URL environment variable in docker-compose.yml:

environment:
  - BASE_URL=http://localhost/planka  # or any custom path

Breaking Changes

None. Existing deployments at root path continue to work without any configuration changes.

Additional note

This is my first contribution to the project. If something is wrong, missing or anyone has a better idea to implement this, please let me know and I'll adapt my changes to your needs.

Enable Planka to be deployed under custom URL paths (e.g., /planka) by
implementing runtime configuration injection from the BASE_URL
environment variable. This allows deployment behind reverse proxies
with path-based routing without requiring image rebuilds.
@CLAassistant
Copy link

CLAassistant commented Dec 7, 2025

CLA assistant check
All committers have signed the CLA.

@meltyshev
Copy link
Member

Hey! Thanks for your PR 🙏 I'll definitely check and test it soon. We're in the middle of preparing the final v2 release, so it might take a bit of time to get to everything.

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.

[Bug]: Planka >v2.0 https://example.com/planka

3 participants