Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem [Docker] komunikácia kontajnerov front-end - back-end nefunguje

Dobrý deň,

vytváram jednoduchu web. multikontajnerovu aplikáciu za pouzitia Docker Desktop. Celkovo je tvorená 4 kontajnermi:

- noSQL databaza MongoDb
- MongoDB admin rozhranie na zobrazenie obsahu databazy z nazvom mongo-express
- backend v Node.js (server vytvorený v Express.js) na komunikáciu z databazou a frontendom (používa vlastný obraz vytvorený cez Dockerfile založený na node)
- frontend je statická web. stránka HTML/CSS + Vanilla JS (používa vlastný obraz vytvorený cez Dockerfile založený na nginx)

všetky kontajneri sú v spoločnej sieti todo-net, problém je, že komunikácia medzi backendom a frontendom nefunguje. Porty vyzeraju nasledovne:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9275ff88b217 todo-nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:3000->80/tcp todo-client
569837f97ded todo-node "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 5000/tcp todo-server
92d1bcc3c6b2 mongo-express "tini -- /docker-ent…" 2 hours ago Up 2 hours 0.0.0.0:8081->8081/tcp mongodb-ui
6c327048c0c8 mongo "docker-entrypoint.s…" 2 hours ago Up 2 hours 27017/tcp mongodb

komunikácia medzi databazou a backendom, alebo databazou a mongo-express tiež funguje, t.j. že cez toho admin klienta vidím dáta, kt. sú v databáze. Problémové kontajneri spusťam príkazmi:

docker build -t todo-node .
docker run --name todo-server --network todo-net --rm -d todo-node
docker build -t todo-nginx .
docker run --name todo-client -p 3000:80 --network todo-net --rm -d todo-nginx

Kod v express.js vyzerá nasledovne:

const express = require('express');
const cors = require('cors');

const app = express();

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());

app.get('/todos', (req, res) => {
  ... // toto odosiela data na front-end
})

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server is running on port ${PORT}...`));

jeho Dockerfile:

FROM node
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 5000
CMD ["node", "server.js"]

na front-ende sa dáta volajú cez fetch:

fetch("http://todo-server:5000/todos").then(res => res.json()).then(data => console.log(data))

// chyba! (vid. screen z konzole)

Předmět Autor Datum
Frontend evidentně nezná "todo-server". A tomu se asi nedá divit, když ten kód běží u klienta, který…
Wikan 19.03.2021 11:21
Wikan
ved sú v spoločnej sieti, ako by som to mohol upravit aby todo-server poznal? Lebo viem ze express v…
lalalalalala 19.03.2021 11:25
lalalalalala
Klient (tedy ten, kdo si tu stránku otevře v browseru) je taky ve společné síti?
Wikan 19.03.2021 12:21
Wikan
myslel som v spoločnej Docker sieti --network todo-net. Pozri vieš mi napísať ako by sa to dalo opr…
lalalalalala 19.03.2021 13:00
lalalalalala
Tak jinak. Jakou adresu zadáváš do prohlížeče, když si chceš tu stránku otevřít? Protože stejnou adr…
Wikan 19.03.2021 13:08
Wikan
ten nginx teda vytvorí samostatný server (podobný tomu node.js) vnútri svojho kontajnera na vlastnom…
lalalalalala 19.03.2021 13:49
lalalalalala
Ano, jedna z funkcí nginxu je webový server. Ale tak to snad víš a proto sis ho tam dal, ne? Nicméně… poslední
Wikan 19.03.2021 15:03
Wikan

ved sú v spoločnej sieti, ako by som to mohol upravit aby todo-server poznal? Lebo viem ze express vie tiez vyrenderovat stranku cez views, no chcel som to mat takto... aby boli backend a frontend oddelene v samostatných kontajneroch.

myslel som v spoločnej Docker sieti --network todo-net.

Pozri vieš mi napísať ako by sa to dalo opraviť tak, aby to šlo ako som chcel, t.j. frontend a backend v samostatnom kontajneri, ktore vedia komunikovať.

Alebo proste napíš, že sa to takto nedá. Lebo ono ta apka je funkčna...funguje to ak backend pri spustení kontajnera nastavim ako -p 5000:5000, vtedy node.js beží normálne na localhoste a ide získať data ako fetch("http://localhost:5000/todos"), takto to funguje bez problemov...

Len mi natom kus vadí, že musím obsadit zbytočne jeden port 5000, ktorý sa realne nedá využiť len iba zobrazuje json.

Takže dá sa to tak či nie? Aby som zbytočne nezabíjal čas tým čo aj tak nepôjde... nikdy. To je aj dovod prečo sem píšem.

Tak jinak. Jakou adresu zadáváš do prohlížeče, když si chceš tu stránku otevřít? Protože stejnou adresu nejspíš budeš muset zadat do toho frontendového kódu. A v nginixu pak nastavit pravidlo, aby requesty na určitou adresu (tady třeba to "/todos") přesměrovával jinam.
Chápeš doufám, že JS kód v HTML stránce se vykonává v prohlížeči konkrétního uživatele a ne tam, kde je ten HTML soubor na serveru?

Zpět do poradny Odpovědět na původní otázku Nahoru