I cannot seem to get my node:alpine Docker image for a react/next.js to build.
I can get it to build fine locally, but I never see the traffic in my API logs when the Docker build reaches out to the API endpoint, which is itself running in a Docker container (nginx, headless craft cms, etc.).
The build does not seem to like localhost at all, as I've tried:
http://localhost:9000/api
...and this is the message I get in the logs:
#15 13.76 > Build error occurred
#15 13.76 FetchError: request to http://localhost:9000/api failed, reason: connect ECONNREFUSED 127.0.0.1:9000
I've heard that I can use the hostname in place of "localhost", so in my MacOS terminal I've typed "hostname" and I've swapped out the localhost for this value. This doesn't outright error out, but the build hangs on the "Generating pages..." step of the build.
How can I get the Docker build to recognize localhost, or put another way, how can I set my API URL to an endpoint hosted by a local Docker container?
Here is my Dockerfile:
# Install dependencies only when needed
FROM node:alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn --frozen-lockfile
# Rebuild the source code only when needed
FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN yarn static
# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# You only need to copy next.config.js if you are NOT using the default configuration
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
USER nextjs
EXPOSE 3000
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
# ENV NEXT_TELEMETRY_DISABLED 1
CMD ["yarn", "start"]
Okay, I figured out the solution, or a solution rather.
After digging around, I found that I needed to connect to the "bridge network".
I found out what the bridge network IP was by first typing in "docker network ls":
This gave me the name of the network I needed to get the IP for, I did this by typing "docker network inspect craftcms_default":
This outputs quite a bit in my case, but the only thing I need is "Gateway" IP, which here is 172.19.0.1
My nginx server is mapped 9000:80, so the headless Craft CMS API is at:
http://172.19.0.1:9000/api
...however, as a quick sanity check I entered this into the browser and the result was an ever spinning/loading page. Undeterred, I entered this into env.local as the PUBLIC_NEXT_API_URL and the static site generation completed fine during the Docker build.
I'm still experimenting with an elegant way to set this env var within the Docker build, so if anyone has any suggestions I'd love to hear!
This is was an interesting challenge considering I couldn't find any answers/Google results specifically for a process running as a result of a Docker build being unable to make a fetch to a URL hosted within another locally running container. Hopefully this helps anyone else struggling with this issue!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With