Я создаю приложение, используя подход, основанный на webpack / vue для внешнего интерфейса (обслуживается с использованием nginx после сборки) и приложение Flask в качестве внутреннего интерфейса. Оба содержатся в отдельных контейнерах Docker и могут обмениваться данными посредством построения сети с использованием файла docker-compose.
Все работает хорошо, за исключением одной вещи: контейнеры Docker имеют разные порты и, следовательно, относятся к разным источникам, что означает, что ответы из внутреннего интерфейса могут быть прочитаны, только если для Access-Control-Allow-Origin
установлено значение *
. Я делаю это во Flask используя:
@app.after_request
def after_request(response):
header = response.headers
header['Access-Control-Allow-Origin'] = '*'
header['Access-Control-Allow-Headers'] = 'content-type, session_id'
header['Access-Control-Allow-Methods'] = 'DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT'
return response
Что работает отлично: когда я запускаю бэкэнд-интерфейс вне их Docker-контейнеров, заголовки ответа фактически содержат мой заголовок set.
Но в контейнере Docker каким-то образом Access-Control-Allow-Origin
удаляется из ответа Flask.
Вот мои файлы docker и файл docker-compose:
Backend:
FROM python:3.6
RUN pip install --upgrade pip && pip install pipenv
COPY ./backend /app
# Pipfile and Pipfile.lock needed with --system flag
COPY ./backend/Pipfile /app
WORKDIR /app
RUN mkdir -p /app/uploads
# RUN pipenv lock && pipenv install --system --deploy --ignore-pipfile
RUN pipenv install --system --deploy --skip-lock
EXPOSE 5000
# Run the app
CMD ["python", "app.py"]
Frontend:
# Stage 1: Build
FROM node AS build
WORKDIR /usr/src/app
# Install all dependencies for production
COPY frontend/package.json .
RUN npm install
ENV NODE_ENV="production"
# Bundle app source
COPY frontend/ .
RUN npm run build
# Stage 2: Production environment
FROM nginx:alpine
# Copy built VUE app to be served by nginx
COPY --from=build /usr/src/app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Docker compose:
version : '3'
services:
frontend:
image: ***
build:
context: .
dockerfile: Dockerfile.frontend
image: ***
ports:
- "9080:80"
networks:
- app_net
backend:
image: ***
build:
context: .
dockerfile: Dockerfile.backend
image: ***
networks:
- app_net
ports:
- "6852:6852"
expose:
- "6852"
# Build internal network, otherwise frontend and backend
# can't communicate on MacOS
networks:
app_net:
driver: "bridge"
Есть идеи, как установить заголовок CORS вручную или убедиться, что он не удален?