slatermorgan
slatermorgan

Reputation: 155

Which API URL should I be using in react application running in docker compose?

So I have the following running in docker-compose:

version: "3.7"
services:
    api:
        stdin_open: true
        build:
            context: ../hikrr_API
            dockerfile: Dockerfile
        image: hikrr_api
        ports:
            - "4000:4000"
        volumes:
            - ../hikrr_API:/usr/src/
    gui:
        stdin_open: true
        build:
            context: ../hikrr_GUI
            dockerfile: Dockerfile
        image: hikrr_gui
        ports:
            - "3000:3000"
        volumes:
            - ../hikrr_GUI:/usr/src/

api is just an express application and gui is a simple react application.

From the context of my simple react application, I want to make an axios request to my api.

However I am unable to get at the URL correct.

Following the docs (https://docs.docker.com/compose/networking/) I concluded that the axios call should be the following

axios({
            method: 'GET',
            url: 'http://hikrr_api://api:4000',
            params: {
                search: search,
                take: take,
                skip: skip
            },
            cancelToken: new CancelToken(c => {
                cancel = c;
            })
        })

As the image is called 'hikrr_api', the service is called 'api' and its exposed on port 4000.

However, when using the browser, the request fails with error: "Error: getaddrinfo ENOTFOUND hikrr_api"

The Curl of this request is:

curl 'http://hikrr_api//api:4000?search=&take=50&skip=0' \
  -H 'Accept: application/json, text/plain, */*' \
  -H 'Referer: http://localhost:3000/' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36' \
  --compressed

What am I missing here?

Upvotes: 0

Views: 1122

Answers (1)

David Maze
David Maze

Reputation: 159005

React applications generally run in a Web browser; they do not run in Docker, even if they're served up from a container-based application.

+------------------------------------+
|               Browser              |
|   Fetches...and runs it...calling  |
+------------------------------------+
       | http://server:3000    | http://server:4000
+------|-----------------------|-----+
|      v         Docker        v     |
|  +-------+              +-------+  |
|  |  gui  |              |  api  |  |
|  +-------+              +-------+  |
+------------------------------------+

Since both calls are from outside Docker, both need to connect to the server's DNS name and the published ports: of the two services. If the browser and the containers are running on the same host (and you're not using Docker Toolbox or another VM-based solution) you can use localhost as the server's host name here.

You could imagine a setup where one service directly called the other; perhaps the gui container makes a call to the api container to produce some seeded data that's prerendered into HTML before being served to the browser. In this case you need the Compose service name and the port the process inside the container listens on, http://api:4000. ports: are ignored here and the image name is not part of the URL. You do not explicitly need to set container_name: or hostname: or to assign the containers to non-default networks:.

Upvotes: 2

Related Questions