Custom domain redirect issues

I have my custom domain at Cloudflare. I now redirect myapp.fly.dev to the mycustomdomain.com.
And, allow myapp.fly.dev/healthcheck to pass through so myapp.fly.dev/healthcheck returns an ok.

But, when I deploy from my local box using flyctl deploy, I get the following error.

:heavy_check_mark: [1/2] Cleared lease for 080xxxxxxxxxx
:heavy_check_mark: [2/2] Cleared lease for 32xxxxxxxxxx

Error: failed to update machine 080xxxxxxxx: Unrecoverable error: timeout reached waiting for health checks to pass for machine 080xxxxxxxx: failed to get VM 080xxxxxxxx: Get “https://api.machines.dev/v1/apps/myappname/machines/080xxxxxxxxxx”: net/http: request canceled

The only change in my app is that it now redirects from myapp.fly.dev to mycustomdomain.com. This is in a entry.server.tx file.

Here’s a snippet of that code

  const allowedHost = "mycustomdomain.com";
  const host = request.headers.get("host")?.toLowerCase();
  const url = new URL(request.url);

  // Paths that should bypass host verification
  const allowedPaths = ["/healthcheck"];

  // Allow requests to specified paths regardless of host
  if (allowedPaths.includes(url.pathname)) {
    return null; // Skip host verification for allowed paths
  }

  // Allow requests in development mode or from localhost
  if (process.env.NODE_ENV === "development" || isLocalHost(host)) {
    return null; // Skip host verification
  }

  if (host !== allowedHost.toLowerCase()) {
    // Option 1: Redirect to the custom domain
    url.hostname = allowedHost;
    return redirect(url.toString(), { status: 301 });

    // Option 2: Return 404 Not Found
    // return new Response("Not Found", { status: 404 });
  }

  // Proceed with the request
  return null;
}

On the fly web interface when you go to app instance and overview, on the top right corner it says “deployed” and on hovering over it, it says “the app is deployed and running”, but on clicking that button it says Release #114 Status: failed.

When I look at the live logs then I see

2024-10-31T23:46:27.771 app[08xxxxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 5.054 ms
2024-10-31T23:46:29.446 app[32xxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 3.178 ms
2024-10-31T23:46:29.764 app[08xxxxxxxxxxxxxxxxx] iad [info] GET /healthcheck - - - - ms
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] healthcheck :x: {
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] error: Response2 [Response] {
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] size: 0,
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Body internals)]: {
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] body: [ReadableStream3 [ReadableStream]],
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] type: null,
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] size: null,
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] boundary: null,
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] disturbed: false,
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] error: null
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] },
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Response internals)]: {
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] url: ‘http://www.mycustomdomain.com:8080/’,
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] status: 520,
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] statusText: ‘’,
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] headers: [Object],
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] counter: 1,
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] highWaterMark: 16384
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:31.203 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:31.441 app[32xxxxxxxxxxxxxxx] iad [info] GET /healthcheck - - - - ms
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] healthcheck :x: {
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] error: Response2 [Response] {
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] size: 0,
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] [Symbol(Body internals)]: {
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] body: [ReadableStream3 [ReadableStream]],
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] type: null,
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] size: null,
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] boundary: null,
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] disturbed: false,
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] error: null
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] },
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] [Symbol(Response internals)]: {
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] url: ‘http://www.mycustomdomain.com:8080/’,
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] status: 520,
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] statusText: ‘’,
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] headers: [Object],
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] counter: 1,
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] highWaterMark: 16384
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:32.957 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:39.791 app[08xxxxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 5.609 ms
2024-10-31T23:46:41.447 app[32xxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 2.955 ms
2024-10-31T23:46:41.766 app[08xxxxxxxxxxxxxxxxx] iad [info] GET /healthcheck - - - - ms
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] healthcheck :x: {
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] error: Response2 [Response] {
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] size: 0,
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Body internals)]: {
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] body: [ReadableStream3 [ReadableStream]],
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] type: null,
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] size: null,
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] boundary: null,
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] disturbed: false,
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] error: null
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] },
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Response internals)]: {
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] url: ‘http://www.mycustomdomain.com:8080/’,
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] status: 520,
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] statusText: ‘’,
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] headers: [Object],
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] counter: 1,
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] highWaterMark: 16384
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:43.205 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:43.444 app[32xxxxxxxxxxxxxxx] iad [info] GET /healthcheck - - - - ms
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] healthcheck :x: {
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] error: Response2 [Response] {
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] size: 0,
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] [Symbol(Body internals)]: {
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] body: [ReadableStream3 [ReadableStream]],
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] type: null,
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] size: null,
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] boundary: null,
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] disturbed: false,
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] error: null
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] },
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] [Symbol(Response internals)]: {
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] url: ‘http://www.mycustomdomain.com:8080/’,
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] status: 520,
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] statusText: ‘’,
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] headers: [Object],
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] counter: 1,
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] highWaterMark: 16384
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:44.913 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:51.772 app[08xxxxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 2.957 ms
2024-10-31T23:46:53.450 app[32xxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 4.120 ms
2024-10-31T23:46:53.767 app[08xxxxxxxxxxxxxxxxx] iad [info] GET /healthcheck - - - - ms
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] healthcheck :x: {
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] error: Response2 [Response] {
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] size: 0,
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Body internals)]: {
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] body: [ReadableStream3 [ReadableStream]],
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] type: null,
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] size: null,
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] boundary: null,
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] disturbed: false,
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] error: null
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] },
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Response internals)]: {
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] url: ‘http://www.mycustomdomain.com:8080/’,
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] status: 520,
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] statusText: ‘’,
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] headers: [Object],
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] counter: 1,
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] highWaterMark: 16384
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:55.174 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:55.444 app[32xxxxxxxxxxxxxxx] iad [info] GET /healthcheck - - - - ms
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] healthcheck :x: {
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] error: Response2 [Response] {
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] size: 0,
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] [Symbol(Body internals)]: {
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] body: [ReadableStream3 [ReadableStream]],
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] type: null,
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] size: null,
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] boundary: null,
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] disturbed: false,
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] error: null
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] },
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] [Symbol(Response internals)]: {
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] url: ‘http://www.mycustomdomain.com:8080/’,
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] status: 520,
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] statusText: ‘’,
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] headers: [Object],
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] counter: 1,
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] highWaterMark: 16384
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:46:56.780 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:47:03.775 app[08xxxxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 4.643 ms
2024-10-31T23:47:05.456 app[32xxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 3.587 ms
2024-10-31T23:47:05.768 app[08xxxxxxxxxxxxxxxxx] iad [info] GET /healthcheck - - - - ms
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] healthcheck :x: {
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] error: Response2 [Response] {
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] size: 0,
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Body internals)]: {
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] body: [ReadableStream3 [ReadableStream]],
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] type: null,
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] size: null,
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] boundary: null,
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] disturbed: false,
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] error: null
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] },
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Response internals)]: {
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] url: ‘http://www.mycustomdomain.com:8080/’,
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] status: 520,
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] statusText: ‘’,
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] headers: [Object],
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] counter: 1,
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] highWaterMark: 16384
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:47:07.150 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:47:07.446 app[32xxxxxxxxxxxxxxx] iad [info] GET /healthcheck - - - - ms
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] healthcheck :x: {
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] error: Response2 [Response] {
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] size: 0,
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] [Symbol(Body internals)]: {
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] body: [ReadableStream3 [ReadableStream]],
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] type: null,
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] size: null,
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] boundary: null,
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] disturbed: false,
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] error: null
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] },
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] [Symbol(Response internals)]: {
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] url: ‘http://www.mycustomdomain.com:8080/’,
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] status: 520,
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] statusText: ‘’,
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] headers: [Object],
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] counter: 1,
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] highWaterMark: 16384
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:47:08.793 app[32xxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:47:15.778 app[08xxxxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 6.140 ms
2024-10-31T23:47:17.453 app[32xxxxxxxxxxxxxxx] iad [info] HEAD / 301 - - 3.716 ms
2024-10-31T23:47:17.770 app[08xxxxxxxxxxxxxxxxx] iad [info] GET /healthcheck - - - - ms
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] healthcheck :x: {
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] error: Response2 [Response] {
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] size: 0,
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Body internals)]: {
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] body: [ReadableStream3 [ReadableStream]],
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] type: null,
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] size: null,
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] boundary: null,
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] disturbed: false,
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] error: null
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] },
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] [Symbol(Response internals)]: {
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] url: ‘http://www.mycustomdomain.com:8080/’,
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] status: 520,
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] statusText: ‘’,
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] headers: [Object],
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] counter: 1,
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] highWaterMark: 16384
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] }
2024-10-31T23:47:18.961 app[08xxxxxxxxxxxxxxxxx] iad [info] }

The app is running just fine and in fact thanks to the redirect my average data out has fallen dramatically from almost 20 kB/s to 3kB/s.

If I remove the middleware that handles the redirect from myapp.fly.dev to mycustomdomain.com all the above errors disappear but my average data out then climbs back to 20kB/s.

Don’t quote me on this, but my understanding is fly does the healthcheck internally, so it doesn’t go through yourapp.fly.dev/healthcheck. Add a log to the snippet up there to ensure that the behavior is expected.

If I had to guess, the internal request is going through your middleware and hitting the redirect block.

Thanks!, but there must be some best practices around this, one shouldn’t have to guess, since my app is behind Cloudflare, I don’t want the https://my-app.fly.dev/ to be publicly available.

On azure websites, it’s very easy to have myapp.azurewebsites.net to return a 403.

Surely, other folks must have needed to do this too when they have a custom domain…

1 Like

I think @khuezy is mainly just guessing about your code, but you do have a good point overall… The health-check mechanism is a little underdocumented at present, given how important it now is.

@scottohara is drafting the magnum opus of doc requests, if you’d maybe like to chime in with your own perspective:

https://community.fly.io/t/http-service-checks-random-questions/22424

There have been multiple asks to remove the default <app>.fly.dev domain for production app but it’s been mostly ignored. What I do is omit the /api/health endpoint from my middleware and reroute all request to the conical domain if I detect that the request contains fly.dev in the host.

@khuezy @mayailurus Thank you both for your inputs. I wasn’t meaning to find fault with @khuezy suggestion, just that we should probably have an out of the box solution. Any serious app (which will/should have a custom domain) must know how to return a 403 for default domain of a hosting service.

Anyways, I think we’ve beaten this dead horse enough…

If you have a few minutes to spare, can you please share snippet of your code so I can do something similar in my app.

I’ve modified my code, as shown below, such that I now return a 403 from myapp.fly.dev but that is now causing the myapp.fly.dev/healthcheck endpoint to return an error. So, I really don’t want any request to myapp.fly.dev to be routed to mycustomdomain.com

 const host = request.headers.get("host")?.toLowerCase();
 const url = new URL(request.url);

  // Paths that should bypass host verification
  const allowedPaths = ["/healthcheck"];

  // Allow requests to specified paths regardless of host
  if (allowedPaths.includes(url.pathname)) {
    return null; // Skip host verification for allowed paths
  }

  // Allow requests in development mode or from localhost
  if (process.env.NODE_ENV === "development" || isLocalHost(host)) {
    return null; // Skip host verification
  }

  if (host !== allowedHost.toLowerCase()) {
    // Option 1: Redirect to the custom domain
    // url.hostname = allowedHost;
    // return redirect(url.toString(), { status: 301 });

    // Option 2: Return 404 Not Found
    return new Response("Not Found", { status: 404 });
  }

I’m using nextjs for my framework so it has a configuration to ignore /api/health.
The gist is:

  if (request.headers.get('host')?.includes('fly.dev')) {
    const u = new URL(request.nextUrl.pathname, 'mydomain.com')
    return NextResponse.redirect(u)
  }

You can return 403 here or w/e.

What middleware framework are you using? Usually it has something like next() to proceed to the next request… returning null seems unconventional? I could be wrong.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.