feat(site): display warning messages when wildcard is not configured (#19660)

Closes https://github.com/coder/coder/issues/19606

This PR adds warnings to alert uses when workspace applications with
subdomain access won't work due to missing wildcard access url
configuration.

### Workspace Page warning

This warning is shown when wildcard hostname is not configured and agent
has subdomain applications.

User:
<img width="1230" height="488" alt="image"
src="https://github.com/user-attachments/assets/66ead7b1-690c-4195-a560-2c5e9ecdf521"
/>

Administrator:

<img width="1231" height="492" alt="image"
src="https://github.com/user-attachments/assets/96f7d6fc-a993-4bbb-bd97-80a750caf3fa"
/>


### Template Editor Warning:

This warning is shown in the output panel (after the user clicks build)
when wildcard hostname is not configured and template contains coder_app
resource and subdomain is set to true.

<img width="1446" height="186" alt="image"
src="https://github.com/user-attachments/assets/ba8e0c8e-1b7f-4722-8cee-24be21b8fc69"
/>
This commit is contained in:
Kacper Sawicki
2025-09-15 10:26:48 +02:00
committed by GitHub
parent d238480c7a
commit 7c8f8f449b
3 changed files with 99 additions and 2 deletions
+9 -1
View File
@@ -41,6 +41,7 @@ import { TerminalLink } from "./TerminalLink/TerminalLink";
import { useAgentContainers } from "./useAgentContainers";
import { useAgentLogs } from "./useAgentLogs";
import { VSCodeDesktopButton } from "./VSCodeDesktopButton/VSCodeDesktopButton";
import { WildcardHostnameWarning } from "./WildcardHostnameWarning";
interface AgentRowProps {
agent: WorkspaceAgent;
@@ -155,6 +156,10 @@ export const AgentRow: FC<AgentRowProps> = ({
// Check if any devcontainers have errors to gray out agent border
const hasDevcontainerErrors = devcontainers?.some((dc) => dc.error);
const hasSubdomainApps = agent.apps?.some((app) => app.subdomain);
const shouldShowWildcardWarning =
hasSubdomainApps && !proxy.proxy?.wildcard_hostname;
return (
<Stack
key={agent.id}
@@ -164,7 +169,8 @@ export const AgentRow: FC<AgentRowProps> = ({
styles.agentRow,
styles[`agentRow-${agent.status}`],
styles[`agentRow-lifecycle-${agent.lifecycle_state}`],
hasDevcontainerErrors && styles.agentRowWithErrors,
(hasDevcontainerErrors || shouldShowWildcardWarning) &&
styles.agentRowWithErrors,
]}
>
<header css={styles.header}>
@@ -226,6 +232,8 @@ export const AgentRow: FC<AgentRowProps> = ({
</section>
)}
{shouldShowWildcardWarning && <WildcardHostnameWarning />}
{shouldDisplayAppsSection && (
<section css={styles.apps}>
{shouldDisplayAgentApps && (
@@ -0,0 +1,84 @@
import AlertTitle from "@mui/material/AlertTitle";
import type { WorkspaceResource } from "api/typesGenerated";
import { Alert, AlertDetail } from "components/Alert/Alert";
import { Link } from "components/Link/Link";
import { useProxy } from "contexts/ProxyContext";
import { useAuthenticated } from "hooks/useAuthenticated";
import type { FC } from "react";
import { docs } from "utils/docs";
interface WildcardHostnameWarningProps {
// If resources are provided, show template-focused warning
resources?: WorkspaceResource[];
}
export const WildcardHostnameWarning: FC<WildcardHostnameWarningProps> = ({
resources,
}) => {
const { proxy } = useProxy();
const { permissions } = useAuthenticated();
const hasResources = Boolean(resources);
const canEditDeploymentConfig = Boolean(permissions.editDeploymentConfig);
if (proxy.proxy?.wildcard_hostname) {
return null;
}
if (hasResources) {
const hasSubdomainCoderApp = resources!.some((resource) => {
return resource.agents?.some((agent) =>
agent.apps?.some((app) => app.subdomain),
);
});
if (!hasSubdomainCoderApp) {
return null;
}
}
return (
<Alert
severity="warning"
className={
hasResources
? "rounded-none border-0 border-l-2 border-l-warning border-b-divider"
: undefined
}
>
<AlertTitle>Some workspace applications will not work</AlertTitle>
<AlertDetail>
<div>
{hasResources
? "This template contains coder_app resources with"
: "One or more apps in this workspace have"}{" "}
<code className="py-px px-1 bg-surface-tertiary rounded-sm text-content-primary">
subdomain = true
</code>
{canEditDeploymentConfig ? (
<>
, but subdomain applications are not configured. Users won't be
able to access these applications until you configure the{" "}
<code className="py-px px-1 bg-surface-tertiary rounded-sm text-content-primary">
--wildcard-access-url
</code>{" "}
flag when starting the Coder server.
</>
) : (
", which requires a Coder deployment with a Wildcard Access URL configured. Please contact your administrator."
)}
</div>
<div className="pt-2">
<Link
href={docs("/admin/networking/wildcard-access-url")}
target="_blank"
>
<span className="font-semibold">
Learn more about wildcard access URL
</span>
</Link>
</div>
</AlertDetail>
</Alert>
);
};
@@ -37,6 +37,7 @@ import {
ProvisionerAlert,
} from "modules/provisioners/ProvisionerAlert";
import { ProvisionerStatusAlert } from "modules/provisioners/ProvisionerStatusAlert";
import { WildcardHostnameWarning } from "modules/resources/WildcardHostnameWarning";
import { isBinaryData } from "modules/templates/TemplateFiles/isBinaryData";
import { TemplateFileTree } from "modules/templates/TemplateFiles/TemplateFileTree";
import { TemplateResourcesTable } from "modules/templates/TemplateResourcesTable/TemplateResourcesTable";
@@ -203,7 +204,7 @@ export const TemplateVersionEditor: FC<TemplateVersionEditorProps> = ({
if (logsContentRef.current) {
logsContentRef.current.scrollTop = logsContentRef.current.scrollHeight;
}
}, [buildLogs]);
}, [buildLogs, resources]);
useLeaveSiteWarning(dirty);
@@ -630,6 +631,10 @@ export const TemplateVersionEditor: FC<TemplateVersionEditorProps> = ({
logs={buildLogs}
/>
)}
{resources && (
<WildcardHostnameWarning resources={resources} />
)}
</div>
)}