Nuxt.js SSR w/Nest API部署到Docker容器中的AWS

Nuxt.js SSR w/Nest API部署到Docker容器中的AWS,docker,axios,nuxt.js,nestjs,Docker,Axios,Nuxt.js,Nestjs,我在这里尝试了大约500万个主题变体,并且花了大量时间仔细阅读Nuxt文档,当部署在AWS的docker容器中时,我无法使用Nest后端的Nuxt SSR。下面是我当前的设置。如果我遗漏了什么,请告诉我 以下是我得到的错误: 此路由向POST请求页面元https://www.noticeeverythingcreative.com/api/contact/meta在组件的asyncData方法中。这会从Axios产生一个很大的旧错误。以下是我认为相关的部分,但如果您需要更多,请告诉我 {

我在这里尝试了大约500万个主题变体,并且花了大量时间仔细阅读Nuxt文档,当部署在AWS的docker容器中时,我无法使用Nest后端的Nuxt SSR。下面是我当前的设置。如果我遗漏了什么,请告诉我

以下是我得到的错误:

此路由向
POST
请求页面元https://www.noticeeverythingcreative.com/api/contact/meta在组件的
asyncData
方法中。这会从Axios产生一个很大的旧错误。以下是我认为相关的部分,但如果您需要更多,请告诉我

{
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: 'xxx.xx.x.x', // IP Address of the docker container
  port: 443,
  config: {
    url: 'https://www.noticeeverythingcreative.com/api/contact/meta',
    method: 'post',
    headers: {
      Accept: 'application/json, text/plain, */*',
      connection: 'close',
      'x-real-ip': 'xx.xxx.xxx.xxx', // My IP
      'x-forwarded-for': 'xx.xxx.xxx.xxx', // My IP
      'x-forwarded-proto': 'https',
      'x-forwarded-ssl': 'on',
      'x-forwarded-port': '443',
      pragma: 'no-cache',
      'cache-control': 'no-cache',
      'upgrade-insecure-requests': '1',
      'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
      'sec-fetch-user': '?1',
      'sec-fetch-site': 'same-origin',
      'sec-fetch-mode': 'navigate',
      'accept-encoding': 'gzip, deflate',
      'accept-language': 'en-US,en;q=0.9',
      'Content-Type': 'application/json'
    },
    baseURL: 'https://www.noticeeverythingcreative.com'
  }
下面是我的
numxt.config.js
的相关部分:

mode: 'universal',
srcDir: './src',
rootDir: './',
modules: ['@nuxtjs/axios'],
// NOTE: I get the same errors if I leave this block out
server: {
    host: '0.0.0.0',
    port: 3002
},
// The server and axios blocks simply serve to set the port as something other than the default 3000
server: {
    port: 3002, // default: 3000,
},
axios: {
    baseURL: 'http://localhost:3002'
},
env: {
    apiHost: process.env.NODE_ENV === 'production' ?
        'https://www.noticeeverythingcreative.com/api' :
        'http://localhost:3002/api'
} 
当我部署时,我使用一个
Dockerfile
将所有需要的文件从我的项目目录复制到容器中,运行
warn install
,公开端口3002,运行
warn build.prod
,并以
CMD[“warn”,“start”]
结束(有关
package.json
脚本,请参见下文)

docker映像在本地构建并推送到ECR回购。然后,我使用SSH连接到我的服务器,并使用此撰写文件运行
docker compose up-d

version: '3.2'

services:
  my_service:
  image: link/to/my/image:${TAG:-prod}
  container_name: my_container
  hostname: www.noticeeverythingcreative.com
  restart: unless-stopped

ports:
  # Http Port
  - 3002:3002

networks:
  - web-network # External (the actual compose file also has the corresponding networks block at the bottom)

environment:
  - NODE_ENV=production
  - API_URL=https://www.noticeeverythingcreative.com
  - HOST=www.noticeeverythingcreative.com
  - PORT=3002
  - VIRTUAL_PORT=3002 
下面是我处理Nuxt渲染的服务器端控制器:

src/server/app/numxt.controller.ts

import { Controller, Get, Request, Response } from '@nestjs/common';
import { join, resolve } from 'path';
import * as config from 'config';

const { Builder, Nuxt } = require('nuxt');
const nuxtConfig = require(join(resolve(), 'nuxt.config.js'));

@Controller()
export class NuxtController
{
    nuxt:any;

    constructor()
    {
        this.nuxt = new Nuxt(nuxtConfig);
        const Env = config as any;

        // Build only in dev mode
        if (Env.name === 'development')
        {
            const builder = new Builder(this.nuxt);
            builder.build();
        }
        else
        {
            this.nuxt.ready();
        }

    }

    @Get('*')
    async root(@Request() req:any, @Response() res:any)
    {
        if (this.nuxt)
        {
            return await this.nuxt.render(req, res);
        }
        else
        {
            res.send('Nuxt is disabled.');
        }
    }
}
以下是客户端联系人组件的
asyncData
head
实现:

async asyncData(ctx:any)
{
    // fetch page meta from API
    try
    {
        const meta = await ctx.$axios(<any>{
            method: 'post',
            url: `${ ctx.env.apiHost }/contact/meta`,
            headers: { 'Content-Type': 'application/json' }
        });

        return { meta: meta.data };
    }
    catch (error)
    {
        // Redirect to error page or 404 depending on server response
        console.log('ERR: ', error);
    }
}

head()
{
    return this.$data.meta;
}
并将请求更改为:

const meta = await ctx.$axios(<any>{
    method: 'post',
    // NOTE: relative path here instead of the absolute path above
    url: `/api/contact/meta`,
    headers: { 'Content-Type': 'application/json' }
});

return { meta: meta.data };
const meta=wait ctx.$axios(呈现良好。可以通过查看页面源代码并查看标题已更新且没有控制台错误来确认。但是,如果加载主页()然后单击导航中的联系人链接,您将看到
POSThttp://localhost:3002/api/contact/meta 网络::错误连接被拒绝


注意:这是这个问题最后一次编辑时部署的版本。

我提出了一个解决方案,但我不喜欢它,所以如果有人有更好的,请发布

我允许Nuxt应用程序在docker容器内的localhost上运行,但向实际主机发出http请求(例如,
https://www.noticeeverythingcreative.com/whatever

因此,在
numxt.config.js
中:

mode: 'universal',
srcDir: './src',
rootDir: './',
modules: ['@nuxtjs/axios'],
// NOTE: I get the same errors if I leave this block out
server: {
    host: '0.0.0.0',
    port: 3002
},
// The server and axios blocks simply serve to set the port as something other than the default 3000
server: {
    port: 3002, // default: 3000,
},
axios: {
    baseURL: 'http://localhost:3002'
},
env: {
    apiHost: process.env.NODE_ENV === 'production' ?
        'https://www.noticeeverythingcreative.com/api' :
        'http://localhost:3002/api'
} 
docker compose.yml
中,我删除了除localhost之外的任何主机,以及nuxt所依赖的任何env变量(主要是因为我不太清楚这些变量在nuxt中是如何工作的,只是这不是我所期望的):

提出api请求时:

// NOTE: ctx.env.apiHost is https://www.noticeeverythingcreative.com/api
const meta = await ctx.$axios(<any>{
    method: 'post',
    url: `${ ctx.env.apiHost }/contact/meta`,
    headers: { 'Content-Type': 'application/json' }
});

return { meta: meta.data };
//注意:ctx.env.apiHost是https://www.noticeeverythingcreative.com/api
常量元=等待ctx.$axios({
方法:“post”,
url:`${ctx.env.apiHost}/contact/meta`,
标题:{'Content-Type':'application/json'}
});
返回{meta:meta.data};

刚刚测试并得到错误:>错误:enoint:没有这样的文件或目录,打开“/app/.nuxt/server/app/email/img/gh.png”,根据错误可能是nest控制器路径匹配不正确,请求试图从nuxt应用程序而不是nest API端点加载内容呈现Nuxt错误页面而不是404或预期的API错误的行为。您可以分享控制器规则的详细信息吗?抱歉,我应该更清楚地说明表单提交不是问题。只是呈现页面,特别是对/API/contact/meta的POST请求。没有任何GET请求的服务器端处理程序而不是上面代码段中NuxtController中的代码。换句话说,我很确定这是一个网络问题,而不是一个逻辑问题。如果不清楚的话,很抱歉。我明白了-你能分享这个代码段,让表单进行比较和对比吗?我会尝试将来自axios请求的所有URL设置为相对的,而不是prepe正在终止apiHost,因为您正在调用与源站相同的主机。表单提交调用除了表单数据和终结点之外是相同的。它确实有效。我刚刚部署了错误的映像路径修复程序。我实际上看到了您从test@test.com.我实际上已经尝试了相对路径,但失败了,因为即使Axios
baseURL
设置正确后,仍会将请求发送到
localhost:3002
// NOTE: ctx.env.apiHost is https://www.noticeeverythingcreative.com/api
const meta = await ctx.$axios(<any>{
    method: 'post',
    url: `${ ctx.env.apiHost }/contact/meta`,
    headers: { 'Content-Type': 'application/json' }
});

return { meta: meta.data };