Search code examples
postgresqldockernext.jsdockerfilefly

fly.io: next.js build fails on prerendering route with postgres


I'm just starting with fly.io. My environment:

  • next.js (app folder) with route that does simple SELECT * FROM test using pg package (any other package would be same).
  • used fly launch to create an app and postgres app. After that, local build wouldn't work because DATABASE_URL isn't available.
  • wasn't able to figure out how to pull secret from fly.io for local builds, so I just ssh'd into app and copied the DATABASE_URL. The fly proxy works fine.
  • fly secrets list displays DATABASE_URL just fine, so apps are attached.
  • standard Dockerfile is generated. It copies files and runs npm run build

When I do fly deploy I receive this:

Generating static pages (0/7) ...
12.16 
12.16 Error occurred prerendering page "/api/my-api-route". Read more: https://nextjs.org/docs/messages/prerender-error
12.16 
12.16 AggregateError [ECONNREFUSED]: 
12.16     at internalConnectMultiple (node:net:1114:18)
12.16     at afterConnectMultiple (node:net:1667:5)
12.16     at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17)

Which points to the postgres not connecting to the DATABASE_URL.

I tried:

  • there was a suggestion somewhere to put ENV DATABASE_URL="postgres://:memory:", didn't help.

  • put actual DATABASE_URL into Dockerfile, didn't help.

  • tried flyctl deploy --build-arg DATABASE_URL=$DATABASE_URL, didn't help. Same with --build-secret.

  • I tried this and it works, but since there are few more steps in Dockerfile to copy and move files, this is not ideal.

I don't think it should take that much time to deploy a simple next.js app, so I feel like I am missing something obvious.


Solution

  • Turns out I was able to send DATABASE_URL before, but npm run build from within the Docker cannot connect to the postgres app, localhost:5432 (specifics of Fly.io, you can either have a paid-for IP4 and use that, or you have to use proxy to connect to postgres app).

    I was able to connect using host “<app-name>.internal:5432”.