'How to send requests from one service to another in docker swarm?

I need a piece of advice regarding a docker swarm architecture. I have 2 nodes, a manager and a worker. In my swarm I have 3 replicas of my backend (Django), 3 replicas of my frontend (React) and 1 of my PostgreSQL database. I don't have nginx or traefik or anything else besides that. For some reason, the routing doesn't work. Sending POST requests from my frontend to my backend returns ERR_NAME_NOT_RESOLVED. I tried fetching for http://my_backend_service_name:8000/, relying on the swarm to do the load balancing. I am sure I am missing something. but from everything I read I understood this should be possible without traefik, nginx or anything else. This is my docker compose stack file:

services:
  frontend:
    image: xxxxxx
    command: npm start
    ports:
      - "3000:3000"
    stdin_open: true
    networks:
      - web_network
    env_file: xxxxx
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
  db:
    image: postgres:11
    ports:
      - "5432:5432"
    command: "-c logging_collector=on"
    volumes:
      - ./database/postgres_data:/var/lib/postgresql/data/
    networks:
      - data_network
    environment:
      - POSTGRES_USER=xxxxx
      - POSTGRES_PASSWORD=xxxxx
      - POSTGRES_DB=xxxx
    deploy:
      placement:
        constraints:
          - "node.role==manager"
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
  web:
    image: xxxxx
    depends_on:
      db:
        condition: service_started
    command: bash -c "python manage.py makemigrations && python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
    ports:
      - 8000:8000
    env_file:
      - xxxxx
    volumes:
      - migrations-volume:/elpaso/api/migrations/
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
    networks:
      - web_network
      - data_network

networks:
  web_network:
    driver: overlay
  data_network:
    driver: overlay
volumes:
  migrations-volume: 

If anyone has any piece of information or advice I could use on how I could send the requests from my backend container to the frontend one, I would be so, so grateful!

Edit: The Dockerfile for the frontend service is:

FROM node:13.12.0-alpine
WORKDIR /elpaso/frontend

COPY package.json package-lock.json ./
RUN npm install 
COPY . ./
EXPOSE 3000
CMD [ "npm", "start" ]

and for the backend

FROM python:3.8
WORKDIR /elpaso
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# dependencies for psycopg2 
RUN apt-get update \
    && apt-get install -y postgresql-server-dev-all gcc python3-dev musl-dev 

RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000

The frontend app sends requests as such:

fetch("http://my_backend_service_name:8000/app/login", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `${tok}`,
        },
      })

Both 8000 and 3000 ports are exposed and the Django allowed hosts include the manager IP.



Solution 1:[1]

Your react app front end runs in a browser. Assuming your swarm has a dns entry "swarm.example.com" you might access your site from your desktop using "http://swarm.example.com:3000".

In the following code networks: web_network is entirely redundant as react doesn't make server to server calls, its client (i.e. browser) to server, so you need to teach the react app that "http://swarm.example.com:8000" is the correct api base url. You'd want to add that as an env var, and/or ensure the react app can process environment variables at run time.

  frontend:
    image: xxxxxx
    command: npm start
    ports:
      - "3000:3000"
    stdin_open: true
    # remove this
    networks:
      - web_network
    # add something like this with an variable and node name appropriate to your environment
    environment:
      MY_API_URL: http://swarm:8000
    env_file: xxxxx
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chris Becke