junep
junep

Reputation: 2164

Calling API in a docker-compose container to another container

I'm making an web service using docker-compose environment. But I face to the calling API issue. I'm using nextjs and here is my code.

import { GetServerSideProps } from 'next';

export default function Home() {
  return (
    ...
  );
}

export const getServerSideProps: GetServerSideProps = async ({ req }) => {
  fetch('http://localhost:7070/api/users') // <-- error occurred !
    .then((r) => r.json())
    .then((result) => console.log('######## shoot in getServerSideProps', result));

  return {
    props: {},
  };
};

This is sample code. When I access to this page, the following error comes up

/app/node_modules/node-fetch/lib/index.js:1461
            reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
                   ^
FetchError: request to http://localhost:7070/api/users failed, reason: connect ECONNREFUSED 127.0.0.1:7070

How can I call the fetch API? My docker setting is following.

docker-compose

version: "3"
services:
  servicebackend:
    container_name: seiwhale-backend
    build:
      dockerfile: Dockerfile.dev
      context: ./services/server
    volumes:
      - /app/node_modules
      - ./services/server:/app
  servicefrontend:
    container_name: seiwhale-frontend
    build:
      dockerfile: Dockerfile.dev
      context: ./services/webapp
    volumes:
      - /app/node_modules
      - ./services/webapp:/app
  serviceredis:
    container_name: seiwhale-redis
    image: "redis"
  nginx:
    container_name: seiwhale-nginx
    restart: always
    build:
      dockerfile: Dockerfile
      context: ./services/nginx
    ports:
      - "7070:80"

nginx

upstream upstreamfrontend {
  server servicefrontend:8080;
}

upstream upstreambackend {
  server servicebackend:3000;
}

server {
  listen 80;

  location / {
    proxy_pass http://upstreamfrontend;
  }

  location /api {
    proxy_pass http://upstreambackend;
  }

  location /sockjs-node {
    proxy_pass http://upstreamfrontend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
  }
}

Additionally, when the error was occurred, the frontend container is automatically exited like following

seiwhale-frontend exited with code 1

How can I re-run the frontend container after exit?

Upvotes: 0

Views: 6225

Answers (1)

eshaan7
eshaan7

Reputation: 1068

2 mistakes:

  • You are missing the expose key from your docker-compose.yml config in which you define a list of ports that you want to expose to other services in the same docker network (or in this case, services defined in the same docker-compose file).
  • The frontend code running as a docker service and not from the host, so again you need to use expose and not port. (port is used for mapping ports from HOST:CONTAINER so applications outside the docker network can call it, for example, if something is listening on port 4200 of servicebackend and you define 8000:4200 then it is accessible on your host at localhost:8000.)

Please try again after making the following changes:

docker-compose.yml

version: "3"
services:
  servicebackend:
    container_name: seiwhale-backend
    build:
      dockerfile: Dockerfile.dev
      context: ./services/server
    volumes:
      - /app/node_modules
      - ./services/server:/app
    expose:
      - "3000"
  servicefrontend:
    container_name: seiwhale-frontend
    build:
      dockerfile: Dockerfile.dev
      context: ./services/webapp
    volumes:
      - /app/node_modules
      - ./services/webapp:/app
    expose:
      - "8080"
  serviceredis:
    container_name: seiwhale-redis
    image: "redis"
  nginx:
    container_name: seiwhale-nginx
    restart: always
    build:
      dockerfile: Dockerfile
      context: ./services/nginx
    ports:
      - "7070:80"
    expose:
      - "80"

and in the frontend,

export const getServerSideProps: GetServerSideProps = async ({ req }) => {
  fetch('http://localhost:80/api/users') // <-- error occurred !
    .then((r) => r.json())
    .then((result) => console.log('######## shoot in getServerSideProps', result));
    .error((err) => console.error(err))

  return {
    props: {},
  };
};

Upvotes: 3

Related Questions