Connect a custom domain to an Aiven App Limited availability
Connect a custom domain to an Aiven App using Cloudflare. Cloudflare receives traffic for your custom domain at its edge, and a Cloudflare Worker forwards each request to the Aiven-generated app hostname.
This approach adds an extra network hop and a Worker subrequest before traffic reaches Aiven. This can increase latency slightly. Worker usage and pricing depend on your Cloudflare plan.
Limitations and security considerations
This approach fronts your app's existing public URL. It doesn't replace the URL, and you cannot rely on the Worker as a security boundary.
- The Aiven App URL stays publicly reachable: Traffic reaches your container with
the public
*.aiven.apphost. Anyone who knows that URL can bypass your custom domain and any Cloudflare-layer protections you configure on it. - The app must be host-aware: Requests reach your app with the
Hostset to the Aiven hostname. To avoid leaking that hostname in redirects, links, and cookies, configure your app to trustX-Forwarded-HostandX-Forwarded-Proto. Only theLocationresponse header is rewritten for you. - Streaming and WebSockets need validation: Server-sent events usually work with this proxy pattern. WebSockets need explicit upgrade handling in the Worker. Test both paths before production use.
Prerequisites
- An Aiven App with a publicly accessible URL.
- A domain that is managed by Cloudflare and uses Cloudflare nameservers.
- The domain record is set to Proxied in Cloudflare.
- Universal SSL covers your root domain and first-level subdomains. Use Advanced Certificate Manager for deeper subdomains.
Connect a custom domain managed by Cloudflare
-
To get the Aiven App URL, in the Aiven Console, click Applications and open your app.
-
In the Connection information section, copy the Application URL.
-
In Cloudflare, open your domain and click DNS Records.
-
Click Add Record.
-
For the Type, select CNAME.
-
Enter the Name.
-
For the Target, enter the Aiven App URL without
https://. -
Set the Proxy status to Proxied, and TTL to Auto.
-
Click Back to Domains, and in the sidebar, click Compute > Workers & Pages.
-
Click Create application > Worker. You can also use an existing Worker or deploy with Wrangler.
noteEach exposed port has its own Aiven hostname. Front each one with its own Worker/route, or map hostnames to upstreams within a single Worker.
-
Configure the Worker. The following example forwards requests to an Aiven App host while preserving the original request method, body, and headers:
const AIVEN_HOST = "AIVEN_APP_HOSTNAME";
export default {
async fetch(request, env, ctx) {
const incomingUrl = new URL(request.url);
const upstreamUrl = new URL(request.url);
upstreamUrl.protocol = "https:";
upstreamUrl.hostname = AIVEN_HOST;
upstreamUrl.port = "";
const headers = new Headers(request.headers);
headers.delete("Host"); // Host/SNI are taken from the fetch URL automatically
headers.set("X-Forwarded-Host", incomingUrl.host);
headers.set("X-Forwarded-Proto", "https");
const init = {
method: request.method,
headers,
redirect: "manual",
};
if (request.method !== "GET" && request.method !== "HEAD") {
init.body = request.body;
}
const response = await fetch(upstreamUrl.toString(), init);
const responseHeaders = new Headers(response.headers);
rewriteLocationHeader(responseHeaders, incomingUrl);
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: responseHeaders,
});
},
};
function rewriteLocationHeader(headers, incomingUrl) {
const location = headers.get("Location");
if (!location) {
return;
}
const publicOrigin = `${incomingUrl.protocol}//${incomingUrl.host}`;
const upstreamOrigin = `https://${AIVEN_HOST}`;
if (location.startsWith(upstreamOrigin)) {
headers.set("Location", location.replace(upstreamOrigin, publicOrigin));
}
} -
Click Deploy.
-
Open your domain and click Workers Routes.
-
Click Add route.
-
Add the Route using the pattern that matches the hostname you configured:
- Root domain:
example.com/* wwwsubdomain:www.example.com/*- Other subdomain:
app.example.com/*
- Root domain:
-
Select the Worker and click Save.
-
Open the custom domain in a browser to confirm the app loads.