Azure Web App多容器,无论设置如何,都会与CORS冲突 docker-compose.yml 前端Dockerfile 前端Axios代码后端Dockerfile 后端FastAPI代码

如何解决Azure Web App多容器,无论设置如何,都会与CORS冲突 docker-compose.yml 前端Dockerfile 前端Axios代码后端Dockerfile 后端FastAPI代码

概述

我有一个使用Vue的前端和一个使用FastAPI的后端。

我已经制作了这两个容器和一个docker-compose.yml的Docker容器,以将它们全部挂钩。在我进行开发时,在本地一切正常。

将其移至Azure时,会收到CORS错误,特别是Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://<my-site>.azurewebsites.net:8080/login

我看过几个CORS questionshere is another)和Azure multi-container tutorialsanother oneyet anotherone last one)。没有任何建议可以解决问题,但是这些都不是我的确切情况:

  • Azure Web App
  • 使用多容器
  • 具有独立的前端(Vue)和后端(FastAPI)

代码

这是我代码的相关部分:

docker-compose.yml

version: "3.8"
services:
  frontend:
    image: <my-acr>.azurecr.io/<my-fe-image>:1
    networks:
      - fullstack
    ports:
      - "80:80"
  backend:
    image: <my-acr>.azurecr.io/<my-be-image>:1
    networks:
      - fullstack
    ports:
      - "8080:80"
networks:
  fullstack:

前端Dockerfile

# develop stage
FROM node:14.8-alpine3.12 as develop-stage

ENV CONTAINER_PATH /vue

WORKDIR $CONTAINER_PATH

COPY package*.json ./

RUN yarn install

COPY . .

# build stage
FROM develop-stage as build-stage
RUN ["yarn","build"]

# production stage
FROM nginx:1.19.2-alpine as production-stage
COPY --from=build-stage /vue/dist /usr/share/nginx/html
EXPOSE 8080 2222 80 443
CMD ["nginx","-g","daemon off;"]

前端Axios代码

import axios from "axios";

export default () => {
  return axios.create({
    baseURL: `https://<my-site>.azurewebsites.net:8080/`,headers: { "Access-Control-Allow-Origin": "*" },});
};

后端Dockerfile

FROM tiangolo/uvicorn-gunicorn:python3.8

RUN ["pip","install","--upgrade","pip"]

RUN ["pip","--ignore-installed",\
    "--use-feature=2020-resolver","--no-cache-dir","jwcrypto","fastapi","passlib",\
    "sqlalchemy","toml","topicaxis-opengraph","sqlalchemy_imageattach",\
    "email_validator","bcrypt"]

EXPOSE 8080 2222 80 443

COPY ./src /app

后端FastAPI代码

app = FastAPI()

app.add_middleware(
    CORSMiddleware,allow_origins=["*"],allow_credentials=True,allow_methods=["*"],allow_headers=["*"],)

我知道其中的大部分内容都太松散了……只要有任何可用的工作,我都会修复它。


Azure命令

首先,我read that仅识别端口80和8080,因此我将FE放在80上,将BE放在8080上。

接下来,一旦我将容器向上推,以下是与Azure相关的命令:

  1. az webapp create -g <my-rg> -p <my-plan> -n <app-name> --multicontainer-config-file ./docker-compose.yml --multicontainer-config-type COMPOSE --assign-identity /subscriptions/<my-subscription/resourceGroups/<my-rg>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<my-userid>
  2. az webapp config appsettings set -g <my-rg> -n <my-app> --settings WEBSITES_PORT=80
  3. az role assignment create --assignee <my-info> --scope /subscriptions/<my-subscription>/resourceGroups/<my-rg>/providers/Microsoft.ContainerRegistry/registries/<my-acr> --role "AcrPull"
  4. az webapp cors add -g <my-rg> -n <app-name> --allowed-origins "*"
  5. az webapp config container set -n <app-name> -g <my-rg> --multicontainer-config-file ./docker-compose.yml --multicontainer-config-type COMPOSE --docker-registry-server-url https://<my-site>.azurecr.io
  6. az webapp restart -n <app-name> -g <my-rg>

上面提到的docker-compose.yml与前面显示的相同。


我能够看到所有前端,但无论何时前端尝试到达后端,它都会挂起一段时间,然后返回Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://<my-site>.azurewebsites.net:8080错误。

我也无法直接访问后端,无论是看原始API还是使用FastAPI的自动生成的docs页面。

解决方法

我必须承认,我从来没有在App Service中运行带有前端和后端的多容器部署,只有自包含的应用程序或单个容器的应用程序。话虽如此...

我认为这里有几个问题。

第一个是为什么您无法从外部连接到后端服务。

根据Azure documentation,如果您使用基于Linux的Azure App Service,则在多容器部署中,只有一个容器可以打开以通过Internet访问。哪一个?规则如下:

以下是确定可访问哪个容器的规则-按优先顺序:

  • 将应用程序设置WEBSITES_WEB_CONTAINER_NAME设置为容器名称
  • 第一个定义端口80或8080的容器
  • 如果以上两个都不成立,则文件中定义的第一个容器将可访问(公开)

(对不起,我无法正确设置列表格式)。

这可能是无法从外部访问backend容器的原因,并且,如果应该从Internet访问这两个容器,则这是更改两个单一容器的部署的很好的理由代替。

另一个问题是为什么出现CORS错误。

有几件事可能会导致问题。

一方面,只要不需要以这种方式消耗前端,就无需 为您的Web应用配置CORS。因此,此配置不是必需的:

az webapp cors add -g <my-rg> -n <app-name> --allowed-origins "*"

出于相同的原因,您无需在Axios中配置CORS,因此可以安全地从代码中删除以下配置行:

headers: { "Access-Control-Allow-Origin": "*" },

还有一个问题:如何通过backendfrontend服务联系?

首先,看来您的FastAPI配置正确。

正如我的评论中所建议的那样,我最好的建议是,将Axios客户端配置为利用docker内部网络,并配置Axios使用backend作为向其发送请求的主机。

如果您查看指示的第一个多容器示例(https://docs.microsoft.com/en-us/azure/app-service/tutorial-multi-container-app),则当他们配置Wordpress容器时,他们在其配置属性中将db引用为主机名,即{ {1}}公开服务:

db

简而言之,我认为多容器设置最适合使用案例,当您拥有一项服务以及该服务正常运行所需的多个资源(SQL数据库,Kafka,Redis)时。

如果您不需要仅通过前端从外部访问后端,这也可能是合适的。

在任何其他情况下,具有两个单个容器Web应用程序的部署应该更合适。

最后一个想法...如果您需要实现一个多容器解决方案,也许您可​​以包括某种网络服务器,例如nginx,这是反向代理的想法,正如@timur的评论中所建议的那样,您可以公开在WORDPRESS_DB_HOST: db:3306 端口上,并定义访问前端和后端服务的规则。应该对其进行测试,但这可以帮助您极大地简化CORS设置,甚至避免使用它。

,

在远程机器上使用Docker部署应用程序时,我们在前端遇到这些问题,即使后端工作正常,前端也会返回CORS问题。 为了解决这个问题,我们在响应中允许以下标头

        $("#content_details").on("change",function(){
            
            var i = 0;
            var price = 0;
            var format_value = [];
            var count_format = $("input[id='length']").length;
            
            for (i = 1; i <= count_format; i++) {
                
                var format = [];
                
                $.each($("input[name='format__" + i + "[]']:checked"),function(){
                    format.push($(this).val());
                });
                var format_select = format.join(",");
        
                if (format_select.includes("SEO") == true) {
                    var format_value_seo = 0.5;
                } else {
                    var format_value_seo = 0;
                };
                    
                if (format_select.includes("PR") == true) {
                    var format_value_pr = 1.5;
                } else {
                    var format_value_pr = 0;
                };
                    
                if (format_select.includes("Review") == true) {
                    var format_value_review = 2;
                } else {
                    var format_value_review = 0;
                };
                
                format_value[i] = format_value_seo + format_value_pr + format_value_review;
                
                
                // Set price
                    var format_basic = 12;

            };

                    var sum = format_value.reduce(function(a,b){
                        return a + b;
                    },0);
                    
                price = sum;

                $("input[name=price]").val(price);
                
                return false;
        
    });

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-