Я перепробовал примерно 5 миллионов вариантов темы здесь, а также провел много времени, просматривая документы Nuxt, и я не могу получить Nuxt SSR с бэкэндом Nest, работающим при развертывании в контейнере docker в AWS. Ниже моя текущая установка. Пожалуйста, дайте мне знать, если я что-то пропустил.
Вот ошибки, которые я получаю:
https://www.noticeeverythingcreative.com/contact Этот маршрут делает запрос POST
для мета страницы в https://www.noticeeverythingcreative.com/api/contact/meta
в методе asyncData
компонента. Это приводит к большой старой ошибке от Ax ios. Ниже приведена часть, которая, на мой взгляд, актуальна, но, если вам нужно больше, дайте мне знать.
{
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'
}
Вот соответствующая часть моего nuxt.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
},
Когда я развернусь, я используйте Dockerfile
, который копирует все необходимые файлы из каталога моего проекта в контейнер, запускает yarn install
, предоставляет порт 3002, запускает yarn build.prod
и заканчивается CMD ["yarn", "start"]
(соответствующие сценарии package.json
см. ниже).
"scripts": {
"clean.nuxt": "rimraf .nuxt",
"build.client": "nuxt build",
"build.server": "tsc -p tsconfig.server.json", // Transpile TypeScript from `src/server` into `.nuxt/api`
"build.prod": "run-s clean.nuxt build.client build.server",
"start": "cross-env NODE_ENV=production node .nuxt/api/index.js",
}
Образ docker создается локально и отправляется в репозиторий ECR. Затем я S SH на свой сервер и запускаю docker-compose up -d
с этим файлом compose:
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 / nuxt.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;
}
Проблемы, которые я Я имею дело только в производственной среде на производственном хосте. Локально я могу запустить yarn build.prod && cross-env NODE_ENV=development node .nuxt/api/index.js
, и приложение работает и отображает без ошибок.
Обновление
Если я разрешу приложению Nuxt работать на localhost внутри контейнера docker, я столкнусь с противоположной проблемой. Например, если я изменю свой блок nuxt.config. js server и ax ios на
server: {
port: 3002, // default: 3000,
},
axios: {
baseURL: 'http://localhost:3002'
}
и изменим запрос на:
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 };
A fre sh нагрузка https://www.noticeeverythingcreative.com/contact делает хорошо. Это можно подтвердить, просмотрев исходный код страницы и убедившись, что заголовок обновлен и что нет ошибок консоли. Однако, если вы загрузите домашнюю страницу (https://www.noticeeverythingcreative.com) и нажмете ссылку контакта в навигационной панели, вы увидите POST http://localhost:3002/api/contact/meta net::ERR_CONNECTION_REFUSED
.
ПРИМЕЧАНИЕ. Эта версия развернута на момент последнего редактирования этого вопроса.