[英]Angular SSR is not working in docker NGINX
I added angualr universal to my app.我在我的应用程序中添加了 angualr Universal。
When I run commands:当我运行命令时:
npm run build:ssr
npm run serve:ssr
SSR rendering works fine. SSR 渲染工作正常。
But when I run my app in docker SSR isn't work I see only my static index.html in page source.但是当我在 docker SSR 中运行我的应用程序时,我在页面源代码中只看到我的 static index.html。
This is my server.ts:这是我的 server.ts:
import 'zone.js/dist/zone-node';
import {APP_BASE_HREF} from '@angular/common';
import {ngExpressEngine} from '@nguniversal/express-engine';
import * as express from 'express';
import {existsSync} from 'fs';
import {join} from 'path';
import {AppServerModule} from './src/main.server';
const compression = require('compression');
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/my-app-frontend/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
server.use(compression());
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/main/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4200;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export * from './src/main.server';
This is my Dockerfile
:这是我的
Dockerfile
:
FROM node:16.17.0-alpine3.16 AS node
WORKDIR /frontend
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build:ssr
This is my docker-compose.yml
:这是我的
docker-compose.yml
:
version: '3'
...
frontend:
container_name: my-app-docker-frontend
build: ./frontend
restart: unless-stopped
command: npm run serve:ssr
networks:
- my-app-docker-network
nginx:
image: nginx:stable
container_name: my-app-docker-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
depends_on:
- frontend
- backend
networks:
- my-app-docker-network
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
volumes:
my-app-docker-db: { }
networks:
my-app-docker-network:
driver: bridge
This is my app.conf
:这是我的
app.conf
:
server {
gzip on;
gzip_static on;
gzip_types text/plain application/xml;
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 1000;
listen 80;
server_name mysite.com;
server_tokens off;
location / {
proxy_pass http://frontend:4200;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /api {
proxy_pass http://backend:8080;
rewrite ^/api/(.*) /$1 break;
}
}
I spend two days to solve this problem, any help will usefull.我花了两天时间解决这个问题,任何帮助都会有用。
It looks like your post is mostly code;看起来您的帖子主要是代码; please add some more details.
请添加更多细节。
I fixed my problem.我解决了我的问题。
My app worked fine, exept that SSR wasn't work.我的应用程序运行良好,只是 SSR 不起作用。 I aded request intersepter and realized that I was getting error:
我添加了 request intersepter 并意识到我遇到了错误:
Http failure response for (unknown url): 0 Unknown Error
But everything work fine.但一切正常。 I started googling and found this post:
我开始用谷歌搜索,发现这篇文章:
https://github.com/angular/angular/issues/20738#issuecomment-415740935 https://github.com/angular/angular/issues/20738#issuecomment-415740935
Author had problem with localhost and docker.作者对 localhost 和 docker 有问题。 I am not using localhost in my project so i just replace
serverUrl
in my environment.prod.ts
file.我没有在我的项目中使用 localhost 所以我只是在我的
environment.prod.ts
文件中替换serverUrl
。
Before was just api
i replase with full url https://myapp.com/api and SSR started working.之前只是
api
我用完整的 url https://myapp.com/api和 SSR 开始工作。 Also the error: Http failure response for (unknown url): 0 Unknown Error
went away.还有错误:
Http failure response for (unknown url): 0 Unknown Error
消失了。
This was easy fix, but spend 4 days to find it.这很容易解决,但要花 4 天时间才能找到它。 The main couse of error was thay I used relative url instead of absolute.
错误的主要原因是我使用相对 url 而不是绝对。
as angular manual said:正如 angular 手册所说:
The tutorial's HeroService and HeroSearchService delegate to the Angular HttpClient module to fetch application data. These services send requests to relative URLs such as api/heroes. In a server-side rendered app, HTTP URLs must be absolute (for example, https://my-server.com/api/heroes). This means that the URLs must be somehow converted to absolute when running on the server and be left relative when running in the browser.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.