How the `--abs-proxy-base-path` Mechanism Works for absproxy Requests in code-server
The --abs-proxy-base-path flag prepends a custom URL prefix to downstream requests in code-server's absproxy endpoint, enabling proxied applications to generate correct links when code-server runs under a non-root subpath.
When deploying coder/code-server behind a reverse proxy or under a nested URL path (e.g., https://example.com/user/123/workspace/), local services exposed via the absproxy feature must be aware of this external prefix to handle redirects and asset links properly. The --abs-proxy-base-path command-line flag injects this context into the proxy layer. This article traces the exact mechanism from CLI argument to target URL construction.
Route Registration and CLI Propagation
In src/node/routes/index.ts (lines 22–27), code-server registers the /absproxy/:port{/*path} route and forwards the flag value to the proxy handler. The route configuration uses passthroughPath: true to preserve the full request path while passing proxyBasePath derived directly from the CLI arguments:
app.router.all("/absproxy/:port{/*path}", async (req, res) => {
await pathProxy.proxy(req, res, {
passthroughPath: true,
proxyBasePath: args["abs-proxy-base-path"],
})
})
This registration ensures that every request matching the absproxy pattern carries the configured base path into the proxy logic.
Target URL Construction in pathProxy.ts
The actual URL assembly occurs in src/node/routes/pathProxy.ts within the getProxyTarget helper function (lines 14–20). This function constructs the downstream URL by inserting the optional proxyBasePath between the local port address and the request path.
The getProxyTarget Implementation
When passthroughPath is enabled, the function skips the base-stripping logic and directly appends the full req.originalUrl to the target, prepending the proxyBasePath if provided:
return `http://0.0.0.0:${port}${opts?.proxyBasePath || ""}/${req.originalUrl.slice(base.length)}`
Because passthroughPath is true, the base variable remains unset (the if (!opts?.passthroughPath) block is skipped). Consequently, the entire req.originalUrl is preserved, and the supplied proxyBasePath becomes the leading path segment sent to the internal service.
Runtime Request Flow
Consider code-server running at https://my-code-server.com/user/123/workspace/ with the following startup command, as documented in docs/guide.md (lines 55–57):
code-server --auth=none --abs-proxy-base-path=/user/123/workspace
When a client accesses:
https://my-code-server.com/user/123/workspace/absproxy/5173/api/data
The proxy forwards the request to:
http://0.0.0.0:5173/user/123/workspace/absproxy/5173/api/data
The downstream application sees /user/123/workspace as its base context and can generate URLs relative to that prefix.
Downstream Application Configuration
To utilize this mechanism correctly, the proxied service must align its internal routing with the absproxy endpoint. For example, a SvelteKit application running on port 5173 would configure its base path as:
export const kit = {
paths: {
base: "/absproxy/5173",
},
};
This ensures the application generates links relative to the absproxy route, while the --abs-proxy-base-path flag ensures the internal service receives the full external path context for server-side rendering and redirects.
Summary
- The
--abs-proxy-base-pathflag is captured from CLI arguments and passed to the absproxy route handler insrc/node/routes/index.ts. - In
src/node/routes/pathProxy.ts, thegetProxyTargetfunction prepends this prefix to the internal target URL construction. - When
passthroughPathis enabled, the original request URL is preserved and appended after the base path, ensuring the downstream service receives the complete external path context. - This mechanism allows applications behind reverse proxies to generate correct absolute URLs and handle redirects properly.
Frequently Asked Questions
What happens if I omit --abs-proxy-base-path when running code-server under a subpath?
If the flag is omitted, the proxied application receives requests at the root path (/), causing it to generate incorrect links that lack the subpath prefix. This results in broken assets, failed API calls, and invalid redirects because the application assumes it is running at the domain root.
Does this flag affect the standard proxy endpoint in code-server?
No, the --abs-proxy-base-path flag specifically affects the absproxy endpoint (/absproxy/:port). The standard proxy endpoint uses different path handling logic that strips the proxy prefix rather than preserving the full path, and it does not utilize the proxyBasePath option in the same manner.
How do I determine the correct value for --abs-proxy-base-path?
Set the flag to the external URL path where code-server is hosted, excluding the hostname and protocol. For example, if code-server is accessible at https://example.com/team/code/, the correct value is --abs-proxy-base-path=/team/code. This value should match the path configured in your reverse proxy.
Is the base path preserved for WebSocket connections through absproxy?
Yes, the path construction in getProxyTarget applies to all requests handled by the absproxy route, including WebSocket upgrade requests. The proxyBasePath is included in the target URL for WebSocket connections, ensuring the downstream service maintains consistent path context for both HTTP and WebSocket protocols.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →