首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于Vue Vite和后端容器的Docker Nginx反向代理意外结果

用于Vue Vite和后端容器的Docker Nginx反向代理意外结果
EN

Stack Overflow用户
提问于 2022-06-08 15:53:23
回答 1查看 3.2K关注 0票数 3

如下图所示,我已经设置了带有码头容器的环境。之所以如此,是因为我只有一个VPS,可以同时运行前端和后端。

我想解决这个问题的方法是将Nginx放入一个码头容器中,使用certbot进行验证(这已经起作用了),然后根据用户请求的位置将代理反转到前端或后端。

如图所示,我不确定Nginx应该如何与前端或后端通信。

当我试图做的时候

代码语言:javascript
复制
upstream docker-frontend {
    server frontend:8081;
}

upstream docker-backend {
    server backend:8080;
}

给我一个502 bad gateway错误。我在Stackoverflow的某个地方发现,与其在8080->8080/tcp或8081->8081/tcp上运行后端或前端,不如在80/tcp上同时运行。我还确保把所有的容器放在同一个网络上,这似乎有点帮助。

然后,如下所示编写Nginx配置

代码语言:javascript
复制
upstream docker-frontend {
    server frontend:80;
}

upstream docker-backend {
    server backend:80;
}

然而,通过这样做,我现在有了一个完全空白的页面,什么也没有出现。我可以向您保证,前面没有空白页(它是用Vue 3.0 vite构建的)。

nginx.conf

代码语言:javascript
复制
user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] :$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;
    sendfile on;
    keepalive_timeout 65;

    upstream docker-frontend {
        server frontend:80;
    }

    upstream docker-backend {
        server backend:80;
    }
 
    server {
        listen 8081;
 
        location / {
            proxy_pass         http://docker-frontend/;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }
 
    server {
        listen 8080;
 
        location / {
            proxy_pass         http://docker-backend/example/;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }

    server {
        listen 80;
        listen [::]:80;
        server_name www.example.com;

        include letsencrypt-acme-challenge.conf;

        return 301 https://www.example.com;
    }

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name example.com;

        ssl_certificate fullchain.pem;
        ssl_certificate_key privkey.pem;
        ssl_trusted_certificate chain.pem;
        return 301 https://www.example.com;
    }

    server {
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name www.example.com;
        ssl_certificate fullchain.pem;
        ssl_certificate_key privkey.pem;
        ssl_trusted_certificate chain.pem;
        root /usr/share/nginx/html/;

        location / {
            gzip off;
            root /usr/share/nginx/html/;
            index index.html;
            try_files $uri $uri/ /index.html;

            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
            add_header X-Frame-Options DENY;
            add_header X-Content-Type-Options nosniff;
            add_header X-XSS-Protection "1; mode=block";
            add_header Referrer-Policy "origin";

            proxy_pass http://docker-frontend/;
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $server_name;
        }

        location /example/ {
            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
            add_header X-Frame-Options DENY;
            add_header X-Content-Type-Options nosniff;
            add_header X-XSS-Protection "1; mode=block";
            add_header Referrer-Policy "origin";

            proxy_pass http://docker-backend/example/;
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $server_name;
        }
    }
}

nginx.conf是在试图了解反向代理如何工作的过程中创建的,但我似乎不明白为什么它仍然显示空白页。任何帮助都将不胜感激。

编辑:看起来确实显示了index.html,但我没有在页面中看到任何css或javascript。现在,Vue应用程序的dockerfile配置如下

Dockerfile

代码语言:javascript
复制
FROM node:lts-alpine as build-stage
RUN mkdir -p /app
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:stable-alpine as production-stage
COPY ./nginx.conf /etc/nginx/nginx.conf
RUN rm -rf /usr/share/nginx/html/*
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

但是,我仍然不知道为什么它不加载javascript或css。是否有一种特殊的方法来为Vue建立一个反向代理?还是我的nginx.conf设置不正确?

编辑:添加热重加载后的

代码语言:javascript
复制
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

它仍然不想显示任何东西,只显示一个空白页。

当我检查Vue应用程序的坞容器时

码头主管-it示例/bin/sh

/html文件夹中,它显示的是偏好图标、资产和index.html,但是没有css或js文件夹?然而,在资产文件夹中有一个奇怪的index.a6f56555.jsindex.1212255f.css。以前有没有人经历过这件事?还是只有我一个人?

编辑:我发现Vue没有正确地使用/html文件夹构建自己,因为某种原因它只将index.html放在那里,而不是javascript或css?

vite.config.js

代码语言:javascript
复制
import { fileURLToPath, URL } from 'url'
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import svgLoader from 'vite-svg-loader'

export default defineConfig({
  server: {
    port: 8081
  },
  plugins: [vue(), svgLoader()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
  publicPath: process.env.NODE_ENV === 'production'
    ? ''
    : '/',
  css: {
    loaderOptions: {
      sass: {
        prependData: `@import "@/styles/_variables.scss";`
      },
    },
    preprocessorOptions: {
      scss: {
        implementation: require('sass'),
        additionalData: `
            @import "./src/assets/scss/main.scss";
        `
      }
    }
  },
  base: './'
})

即使设置了由多个源推荐的Vite配置文件和包含

npm运行构建和vite预览-端口8081 -主机

命令,它仍然用空白页显示,有人能告诉我我做错了什么吗?因为我现在不知道.

EN

回答 1

Stack Overflow用户

发布于 2022-06-12 12:43:14

由于您没有多个BE或FE容器,我认为您不需要upstream。(参见负载平衡usecase解释的here

您需要的是nginx有一个服务器,侦听端口80 (通常)并将调用重定向到不同的位置。就像这样

代码语言:javascript
复制
server {
        listen 80;
        server_name  your.url.com;

        location /api {
            proxy_pass         http://backend_container_name:8080;
            ...
        }
 
        location / {
            proxy_pass         http://frontend_container_name:8081;
            ...
        }
    }

我们需要server name知道基本网址。然后,当请求转到some.url.com/some.url.com/a-page时,它将被重定向到FE容器,当您的代码向some.url.com/api/some_endpoint发出请求时,它将被重定向到be容器。

它们必须从浏览器到同一个url:port,否则就会遇到cors问题,这就是为什么我们要做反向代理。

从容器到另一个容器,只要它们是:

  1. 在同一个码头网络中。或者
  2. 有一些发现服务url (例如,在使用AWS等时)

为了使容器位于同一个网络中,您所需要做的就是要么将一个网络单独链接到容器,要么将它们放在同一个docker-compose.yaml中并使用docker-compose up

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72548750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档