'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 |
