Reputation: 123
The error occurs only when api is HTTPS. The testing site is hosted on Digital Ocean.But the below setup is working on my local(MAC Os) with self signed certificate.
Things which i have tried:
Below is my docker compose setup
docker-compose.yml
version: '3'
services:
laravel:
build: ./laravel/docker/php
depends_on:
- database
expose:
- 9000
volumes:
- ./laravel:/var/www/laravel
- $HOME/.composer/:$HOME/.composer/
- ./laravel/docker/php/php-custom.ini:/usr/local/etc/php/conf.d/php-custom.ini
angular:
build: ./angular
expose:
- 9000
volumes:
- ./angular:/var/www/angular:rw
depends_on:
- laravel
links:
- laravel:laravel
web:
build: ./nginx
volumes:
- ./:/var/www/
- ./dh-param/dhparam-2048.pem:/etc/ssl/certs/dhparam-2048.pem:ro
- /docker-volumes/etc/letsencrypt/live/fabivo.com/fullchain.pem:/etc/letsencrypt/live/fabivo.com/fullchain.pem
- /docker-volumes/etc/letsencrypt/live/fabivo.com/privkey.pem:/etc/letsencrypt/live/fabivo.com/privkey.pem
ports:
- 80:80
- 443:443
links:
- laravel:laravel
- angular:angular
depends_on:
- laravel
- angular
environment:
- VIRTUAL_HOST=fabivo.com, portal.fabivo.com , api.fabivo.com, shop.fabivo.com
networks:
default:
aliases:
- api.fabivo.com
- portal.fabivo.com
- shop.fabivo.com
- fabivo.com
- api.paisaclub.com
database:
build: ./laravel/docker/mariadb
environment:
- "MYSQL_ROOT_PASSWORD=secret"
- "MYSQL_DATABASE=homestead"
- "MYSQL_USER=homestead"
- "MYSQL_PASSWORD=homestead"
ports:
- 3306:3306
volumes:
mysqldata:
networks:
default:
external:
name: nginx-proxy
nginx config
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name fabivo.com;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/fabivo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fabivo.com/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
location / {
# NOTE THERE IS NO TRAILING SLASH AT THE END. NO TRAILING SLASH. NO SLASH. NO!
proxy_pass http://angular:9000; # <--- THIS DOES NOT HAVE A TRAILING '/'
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.fabivo.com portal.fabivo.com shop.fabivo.com;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/fabivo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fabivo.com/privkey.pem;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass laravel:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
#CSP
# add_header Content-Security-Policy "frame-src 'self'; default-src 'self'; script-src 'self' 'unsafe-inline' https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com; img-src 'self'; style-src 'self' https://maxcdn.bootstrapcdn.com; font-src 'self' data: https://maxcdn.bootstrapcdn.com; form-action 'self'; upgrade-insecure-requests;" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}
}
server.ts
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
const domino = require('domino');
import { enableProdMode } from '@angular/core';
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';
import { readFileSync } from 'fs';
//import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();
// Express server
const app = express();
const compression = require('compression');
const PORT = process.env.PORT || 9000;
const DIST_FOLDER = join(process.cwd(), 'dist');
//
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
// Our index.html we'll use as our template
const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html'), 'utf8').toString();
const win = domino.createWindow(template);
global['window'] = win;
Object.defineProperty(win.document.body.style, 'transform', {
value: () => {
return {
enumerable: true,
configurable: true
};
},
});
global['document'] = win.document;
global['$'] = require('jquery');
global['jQuery '] = global['$'];
global['Materialize'] = win.Materialize;
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.bundle');
const { provideModuleMap } = require('@nguniversal/module-map-ngfactory-loader');
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP)
]
}));
app.use(compression());
app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));
// Server static files from /browser
app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), { maxAge: '1y' }));
// All regular routes use the Universal engine
app.get('*', (req, res) => {
res.render('index', {
req: req,
res: res
});
});
// Start up the Node server
app.listen(PORT, () => {
console.log(`Node server listening on http://localhost:${PORT}`);
});
UPDATE:
here is minimal reproduction repo https://github.com/ssatz/Angular-SSR-HTTPS-Error Deployed to heroku HEROKU
Note : This is working perfectly in my local with Self Signed certificate.
Upvotes: 1
Views: 1224
Reputation: 123
This is due to SSL configuration. Incase if any one having the issue, change secp384r1 to prime256v1
ssl_ecdh_curve prime256v1;
Upvotes: 1