Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 3581

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 61k
Author
Asked: November 26, 20242024-11-26T04:03:07+00:00 2024-11-26T04:03:07+00:00

A gotcha with Next.js production builds in Docker Compose

  • 61k

This post discusses a gotcha or pitfall I ran into when learning Next.js and Docker. It's pretty elementary, but I couldn't find discussions of it online. ChatGPT wasn't especially helpful either, so hopefully this post saves another newb some time and frustration.

TL;DR: you can put npm run build in a command to run when the container starts, not when the image builds.

The problem: Docker builds succeed in dev but not prod

I had a Docker Compose file defining backend and frontend services, the latter a Next.js app. I was able to build the images and start the containers fine in a development environment. But in production it failed every single time!

The error was typically some version of:

FetchError: request to http://backend:4000/users failed reason: getaddrinfo ENOTFOUND backend 
Enter fullscreen mode Exit fullscreen mode

In plain English, the frontend was unable to fetch data from the backend when Next.js went to build the production version of the app.

But it worked fine in dev!!!

Right?

Riiiiight?…

But was it actually working in dev? Was the frontend fetching data from the backend at build time?

Hint: no.

SSG and npm run build

Next.js offers some great features like static-site generation (SSG). Static-site generation means that the server pre-fetches data so that it can use that data to generate completed HTML and then serve that HTML to web browsers in production. Now when is that data fetched? Answer: on running npm run build (or next build) prior to starting to the frontend server.

So building a production-ready SSG-enabled Next.js app requires access to backend data. Which means that the server supplying that data needs to be up and running first.

By contrast, in development, no static HTML is generated so there is no build step requiring data to be pre-fetched.

In essence, then, my error boils down to including RUN npm run build in my production frontend Dockerfile and then using Docker compose to build both services before starting either.

I was trying to tell Next.js to build a static site before the backend server was up and running to supply the necessary data.

How to fix it?

That explains why I was running into the error. But how to resolve it?

First, the problem is muddied by semantic confusion over the term build. Docker builds images and Next.js builds a statically generated site. It's natural at first to think these are similar operations that need to go together.

But there's no necessary connection between them. Building the Docker image is a matter of packaging an app together with its dependencies and runtime environment. Building a statically generated site is a matter of fetching data and compiling React and JavaScript into optimized HTML.

If the data is there to be fetched, the latter build can happen as part of the former. But, as in my case, if the data is not there, the Next.js build has to wait.

So the problem can be rephrased as: how to build the backend and frontend Docker images first, then start the backend server, then do the Next.js build, then start the frontend server.

Docker entrypoints

Can't we just use the depends_on directive in the Docker compose file? depends_on says “don't start A without first starting B.” And, yes, we want to make sure the backend service starts first. But there's a bit more to it.

We also need to make sure that the Next.js build happens after the backend starts. depends_on establishes a start dependency, not a build dependency. We could solve our problem if there were a Docker compose directive to say “don't build A without first starting B”, but as far as I know there isn't.

What we can do is separate building the frontend Docker image from building the statically generated site. That way depends_on will ensure that the Next.js build happens at the right time.

The easiest way I found to do this is with a simple docker-entrypoint.sh file. Entrypoints are scripts for specifying commands to run when a container starts up. Exactly what we need! The hard part was just realizing the Next.js build could happen on container start not on image build.

My docker-entrypoint.sh file looked like this:

#!/bin/bash  # Build the Next site including SSG npm run build  # Start the production server npm run start 
Enter fullscreen mode Exit fullscreen mode

Pretty straightforward.

And the final step was just invoking the entrypoint as the final lines in my frontend dockerfile, replacing the CMD ['npm', 'run', 'dev'] line that was there previously:

COPY docker-entrypoint.sh / RUN chmod +x /docker-entrypoint.sh ENTRYPOINT ["/bin/sh", "/docker-entrypoint.sh"] 
Enter fullscreen mode Exit fullscreen mode

The first line above copies the script into the Docker image, the second makes it executable, and the third executes it.

Final thought

Learning new technologies often means learning different uses of the same word, 'build' for example. Don't assume they mean the same thing! Be sensitive to what the words are doing in context–the concepts are likely different, maybe radically, maybe only very slightly. Once we clarify the underlying the concepts, the code usually follows.

beginnersdockernextjswebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 2k
  • Popular
  • Answers
  • Author

    ES6 - A beginners guide - Template Literals

    • 0 Answers
  • Author

    Understanding Higher Order Functions in JavaScript.

    • 0 Answers
  • Author

    Build a custom video chat app with Daily and Vue.js

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.