New to Docker here. I’ve been experiencing a confusing roadblock with my Nextjs app, which is running in its own container alongside API and database containers.
My Nextjs app consumes data from the API container. This works great server-side: the Nextjs app resolves the container hostname as it should. Client-side, however, the app breaks because the container hostname means nothing to the browser (I think?). I’m rather lost as to how I can handle this. Ideas?
Here’s my Docker Compose file, in the case that it helps elucidate my question. Note that I’m passing the hostname to the Nextjs app via the environment
field:
version: '3.8'
services:
# Redis
redis:
image: redis
command: redis-server --requirepass ${REDIS_PASSWORD} --bind redis
ports:
- "6379:6379"
networks:
- mywebappio
# Data Processing Service
mywebapp-api:
container_name: mywebapp-api
restart: always
build:
context: packages/dps-api
dockerfile: Dockerfile
command: npm run dev # npm start prod
working_dir: /usr/src/dps-api
env_file:
- .env
volumes:
- ./packages/dps-api:/usr/src/dps-api
ports:
- "5000:5000"
networks:
- mywebappio
depends_on:
- redis
# SSR 'client' app
nextjs:
container_name: mywebapp-client
build:
context: packages/next-server
dockerfile: Dockerfile
command: /bin/bash -c "./wait-for-it.sh mywebapp-api:5000 -- npm run build && npm run start"
environment:
- NEXT_PUBLIC_API_BASE=mywebapp-api:5000
volumes:
- ./packages/next-server:/usr/src/app
ports:
- "3000:3000"
networks:
- mywebappio
depends_on:
- mywebapp-api
- redis
networks:
mywebappio:
driver: bridge
Additional information:
-
Using
curl
on my API, as “localhost:5000”, works. -
In dev console, Nextjs app makes a call to “localhost:3000/” to fetch data server-side. This makes sense given how Nextjs works.
-
In dev console, Nextjs app makes call to “mywebapp-api:5000/” to fetch data client-side. Obviously, this doesn’t work.
2
Answers
Okay so i found a solution/workaround. I was reading online and i found only 1 way. And that’s to setup reverse-proxy to nextjs server sth like this: Proxy to backend with default Next.js dev server. But i fixed it differently: so nextjs has 2 types of env variables, the ones that are exposed only to SERVER(BACKEND_URL=http://servicename:port) and ones that are exposed to SERVER AND CLIENT(NEXT_PUBLIC_BACKEND_URL=http://localhost:port) – here i define localhost so the browser can read the api. And you only do this to setup axios:
Now on client side it will use http://localhost:port and on SSR will use http://servicename:port.
If you want to work in your computer(local environment), you can change the IP for the backend in next.config.js. For example if your computer has the IP 192.168.1.23 and the container for the backend is running in the port 3000, then you next.config.js must have the next:
Also for you axios configuration can look like the next: