I have fronted in react and backend in java. I would like to call backend API in docker and indicate host properly in docker compose from frontend container.
docker-compose.yml
services:
app:
image: 'image1'
container_name: app
ports:
- "8080:8080"
volumes:
- app:/var/lib/app/data
client:
image: 'image2'
build:
context: .
args:
REACT_APP_API_BASE_URL: http://app:8080
container_name: client
depends_on:
- app
ports:
- "80:80"
volumes:
- client:/var/lib/client/data
Network is prepared. What should I put in REACT_APP_API_BASE_URL? http://app:8080 is not working. If I put http://localhost:8080 all is working fine but on prod environment localhost isn't correct.
Related
new to Docker and containers in general. Trying to containerize a simple MERN-based todo list application. Locally on my PC, I can successfully send HTTP post requests from my React frontend to my Nodejs/Express backend and create a new todo item. I use the 'proxy' field in my client folder's package.json file, as shown below:
React starts up on port 3000, my API server starts up on 3001, and with the proxy field defined, all is good locally.
My issue arises when I containerize the three services (i.e. React, API server, and MongoDB). When I try to make the same fetch post request, I receive the following console error:
I will provide the code for my docker-compose file; perhaps it is useful for helping provide me a solution?
version: '3.7'
services:
client:
depends_on:
- server
build:
context: ./client
dockerfile: Dockerfile
image: jlcomp03/rajant-client
container_name: container_client
command: npm start
volumes:
- ./client/src/:/usr/app/src
- ./client/public:/usr/app/public
# - /usr/app/node_modules
ports:
- "3000:3000"
networks:
- frontend
stdin_open: true
tty: true
server:
depends_on:
- mongo
build:
context: ./server
dockerfile: Dockerfile
image: jlcomp03/rajant-server
container_name: container_server
# command: /usr/src/app/node_modules/.bin/nodemon server.js
volumes:
- ./server/src:/usr/app/src
# - /usr/src/app/node_modules
ports:
- "3001:3001"
links:
- mongo
environment:
- NODE_ENV=development
- MONGODB_CONNSTRING='mongodb://container_mongodb:27017/todo_db'
networks:
- frontend
- backend
mongo:
image: mongo
restart: always
container_name: container_mongodb
volumes:
- mongo-data:/data/db
ports:
- "27017:27017"
networks:
- backend
volumes:
mongo-data:
driver: local
node_modules:
web-root:
driver: local
networks:
backend:
driver: bridge
frontend:
My intuition tells me the issue(s) lies in some configuration parameter I am not addressing in my docker-compose.yml file? Please help!
Your proxy config won't work with containers because of its use of localhost.
The Docker bridge network docs provide some insight why:
Containers on the default bridge network can only access each other by IP addresses, unless you use the --link option, which is considered legacy. On a user-defined bridge network, containers can resolve each other by name or alias.
I'd suggest creating your own bridge network and communicating via container name or alias.
{
"proxy": "http://container_server:3001"
}
Another option is to use http://host.docker.internal:3001.
I have two separate docker files, one for running nextjs on nginx web server and another for running Laravel on another nginx:
services:
frontendx:
container_name: next_appx
build:
context: ./frontend
dockerfile: Dockerfile
restart: unless-stopped
volumes:
- ./frontend:/var/www/html/frontend
networks:
- app
nginxy:
container_name: nginxy
image: nginx:1.19-alpine
restart: unless-stopped
ports:
- '8080:80'
volumes:
- ./frontend:/var/www/html/frontend
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- frontendx
networks:
- app
and:
services:
backendx:
container_name: laravelx
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
ports:
- '8000:8000'
volumes:
- ./:/var/www
- enlive-vendor:/var/www/vendor
- .//docker-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
depends_on:
- dbx
networks:
- appx
webserverx:
image: nginx:alpine
container_name: webserverx
restart: unless-stopped
tty: true
ports:
- "8090:80"
- "443:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- appx
I can connect to the backend container through axios and address like : http://localhost:8090/api/my/api/address
but when I try to get data through getStaticProps I've got the ECONNREFUSED connection error:
const res = await fetch(`http://localhost:8090/api/address`)
I tried to replace the localhost with container ip address like : 172.20.0.2
but I've got the 504 Gateway error.
That's expected.
With axios, you're calling from the browser which is making the request from your host machine network.
But getStaticProps being a SSR function, is run inside your nextjs container. Therefore it must be able to find your backend in your app network.
Now by your setup, the frontend and backend apps are in different isolated networks and you can't connect them like this. But if you put them all your services in the same network, lets say your app(instead of appx) network, you can easily use docker dns:
const res = await fetch(`http://webserverx/api/address`)
Docker knows how to resolve webserverx to your webserverx container.
I have a dockerized MERN application: React (Port 3000), Express (Port 4000) and MongoDB (Port 27017). I can access the MongoDB container with Express via "mongodb://root:root#database:27017" (database is the name of the container) but i can't access Express from React by "http://server:4000" or "http://localhost:4000" - i have to explicitly specify the ip address of my host system to access Express. This is my docker-compose.yml:
version: '3.9'
services:
database:
image: mongo:latest
container_name: database
ports:
- '27017:27017'
networks:
- mern
volumes:
- db_data:/data/db
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=root
restart: always
server:
build: ./server
depends_on:
- database
container_name: server
ports:
- '4000:4000'
networks:
- mern
volumes:
- ./server:/app
restart: always
client:
build: ./client
depends_on:
- server
container_name: client
ports:
- "3000:3000"
networks:
- mern
volumes:
- ./client:/app
stdin_open: true
restart: always
networks:
mern:
driver: bridge
volumes:
db_data:
driver: local
How can I use "http://server:4000" in my React application to access the Express API?
So I'm running a web app which consist of 3 services with docker-compose.
A mongodb database container.
A nodejs backend.
A nginx container with static build folder which serves a react app.
Locally it runs fine and I'm very happy, when trying to deploy to a vps I'm facing an issue.
I've set the vps' nginx to reverse proxy to port 8000 which serves the react app, it runs as expected but I can not send requests to the backend, when I'm logged in the vps I can curl it and it responds, but when the web app sends requests, they hang.
My docker-compose:
version: '3.7'
services:
server:
build:
context: ./server
dockerfile: Dockerfile
image: server
container_name: node-server
command: /usr/src/app/node_modules/.bin/nodemon server.js
depends_on:
- mongo
env_file: ./server/.env
ports:
- '8080:4000'
environment:
- NODE_ENV=production
networks:
- app-network
mongo:
image: mongo:4.2.7-bionic
container_name: database
hostname: mongo
environment:
- MONGO_INITDB_ROOT_USERNAME=...
- MONGO_INITDB_ROOT_PASSWORD=...
- MONGO_INITDB_DATABASE=admin
restart: always
ports:
- 27017:27017
volumes:
- ./mongo/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
networks:
- app-network
client:
build:
context: ./client
dockerfile: prod.Dockerfile
image: client-build
container_name: react-client-build
env_file: ./client/.env
depends_on:
- server
ports:
- '8000:80'
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
data-volume:
node_modules:
web-root:
driver: local
My application has three containers: db, frontend-web(React), backend-api
How can I get my backend-api address in frontend-web
Here is my compose file
version: '2'
services:
db:
image: postgres
ports:
- "5432:5432"
web:
build: .
stdin_open: true
volumes:
- .:/usr/src/app
ports:
- "3000:3000"
environment:
- API_URL=http://api:8080/
links:
- api
depends_on:
- api
api:
build: ./api
stdin_open: true
volumes:
- ./api:/usr/src/app
ports:
- "8080:3000"
links:
- db
depends_on:
- db
I can't get the address both api and process.env.API_URL
Add the container name to the service description as follows:
api:
build: ./api
container_name: api
stdin_open: true
volumes:
- ./api:/usr/src/app
ports:
- "8080:3000"
links:
- db
depends_on:
- db
You can then use the container name as a host name to connect to. See https://docs.docker.com/compose/compose-file/#/containername
I am admitting that your server at the web container is just providing the static htmls and not working as a proxy for the api container server.
So, once that you mapped the ports to the host machine, you could use the host machines name/ip to find the api server.
If your host machine name is app.myserver.dev, in your API_URL env var you can use the config below and docker will do the work for you:
web:
build: .
stdin_open: true
volumes:
- .:/usr/src/app
ports:
- "3000:3000"
environment:
- API_URL=http://app.myserver.dev:8080/
links:
- api
depends_on:
- api