Веб-контейнер не может вызвать внутренний контейнер из docker compose - PullRequest
0 голосов
/ 02 апреля 2020

Я все еще нахожусь в мире docker. Я пытаюсь докернизировать мой маленький любимый проект. Фронтенд - это приложение vue -cli, которое взаимодействует с бэкэндом, содержащим успокоительные API, созданные весенней загрузкой.

Таким образом, мой подход состоял в том, чтобы объявить два отдельных файла dockerfile для backend и frontend и объединить их через один docker compose файл. Таким образом, структура папок -

backend/
       - Dockerfile
frontend/
       - Dockerfile
docker-compose.yml

Поскольку внешний интерфейс должен иметь возможность вызывать внутренние службы, я создал мостовую сеть и разделил сеть между ними. Это мой docker составной файл -

version: "2"
services:
  backend:
    build: backend/.
    networks:
      - movie-network
    ports:
      - "8098:8098"
  frontend:
    build: frontend/.
    ports:
      - "8812:8080"
    networks:
      - movie-network

networks:
  movie-network:
    driver: bridge

У меня есть конечная точка на бэкэнде под названием /api/findAll. Теперь, если служба внешнего интерфейса вызывает API через http://localhost:8098:/api/findAll (хост-сеть), я могу просмотреть его из своего браузера (http://localhost: 8812 ), все работает нормально.

Но если интерфейс вызывает тот же API, используя backend:8098/api/findAll; использование мостовой сети - в моем браузере выдается ошибка -

error

Если я сделаю docker exec во внешнем интерфейсе и ping-бэкенде, пинг пройдет успешно

Итак, почему он выдает ошибку в моем браузере (http://localhost: 8812 )? Я концептуально делаю что-то не так? Поиск предложений.

Фронтенд Dockerfile -

FROM node:lts-alpine

# install simple http server for serving static content
RUN npm install -g http-server

# make the 'app' folder the current working directory
WORKDIR /app

# copy both 'package.json' and 'package-lock.json' (if available)
COPY package*.json ./

# install project dependencies
RUN npm install

# copy project files and folders to the current working directory (i.e. 'app' folder)
COPY . .

# build app for production with minification
RUN npm run build

EXPOSE 8080

Бэкэнд Dockerfile -

FROM openjdk:11-jre-slim
# Creating app directory
WORKDIR /usr/src/movies
# Copying Jar (didn't use FROM maven to save some time)
COPY target/movies*.jar movies.jar

RUN pwd

RUN ls -la
# Exposing Port
EXPOSE 8098
# Running App
ENTRYPOINT ["java","-jar","/usr/src/movies/movies.jar"]

Ответы [ 2 ]

2 голосов
/ 02 апреля 2020

Важным для этой настройки является то, что ваш реальный интерфейсный код не работает в Docker, он работает в вашем браузере. Это означает, что он понятия не имеет о Docker сетях, контейнерах или чем-то еще; URL, который вы даете, должен быть тем, который достигает опубликованного порта на вашем хосте. Вот почему localhost работает здесь (если браузер и контейнеры работают на одном и том же хосте), а backend - нет.

Типичный подход к этому - настроить некоторый обратный прокси, который может оба размещают код внешнего приложения и прокси для внутреннего приложения. (Например, установите Nginx, где его /api маршрут proxy_pass http://backend:8098, а его / маршрут либо try_files предварительно настроенное Javascript приложение, либо proxy_pass http://frontend:8080.)

Если вы это сделаете это, тогда например http://localhost:8900 - это внешний интерфейс, а http://localhost:8900/api - это внутренний, с точки зрения браузера. Это позволяет избежать выдачи CORS подсказок @coedycode в их ответе ; но это также означает, что код переднего плана может использовать относительный URL /api (без имени хоста) и избежать всей этой проблемы.

+-------------+                  | Docker >           /     +----------+
+-------------+                  |                 /------> | frontend |
|             |  localhost:8900  |    +-------+    |        +----------+
|   Browser   | ---------------> | -> | nginx | -> +
|             |                  |    +-------+    | /api   +----------+
|             |                  |                 \------> | backend  |
+-------------+                  |                          +----------+
1 голос
/ 02 апреля 2020

Это на самом деле не проблема конфигурации docker, это проблема CORS. Когда браузер отправляет HTTP-запрос от http://localhost до http://backend, это перекрестный запрос, и серверная часть его не разрешает. Пинг до бэкэнда работает, потому что на эхо-запросы не влияет CORS.

В ситуации разработки веб-сервер в бэкэнд-контейнере может быть настроен так, чтобы разрешать CORS с локального хоста, в производственном процессе я не уверен, как бы вы это сделали go о безопасной настройке, чтобы разрешить CORS, возможно, использовать псевдоним сети субдомена api для бэкэнда и разрешить запросы от псевдонима сети основного домена?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...