Nginx 502 bad gateway while hosting strapi application on ubuntu(18.04.1) instance - ubuntu-18.04

NGINX 502 Bad Gateway
I am trying to host my strapi application on aws lightsail on Ubuntu 18.04 and adding nginx for the reverse proxy the strapi application server is all default on localhost.
Previously without nginx it showed
Refused to connect to 'http://localhost:1337/admin/init' because it violates the following Content Security Policy directive: "connect-src 'self' https:".
Hence i sorted out that nginx reverse proxy is needed. And below is my Nginx location directives and env file of the strapi application.
.......................... /etc/nginx/sitesavailable/default .......................
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
proxy_pass http://localhost:1337;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_buffers 8 16k;
proxy_buffer_size 32k;
}
}
................................. /etc/nginx/sites-available/default.................................................
........................... On Strapi..........................................
-----------------------------------server.js---------------------------------
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
app: {
keys: env.array('APP_KEYS'),
  },
});
---------------------------------------database.js---------------------------------
const path = require("path");
module.exports = ({ env }) => ({
connection: {
client: "postgres",
connection: {
host: env("DATABASE_HOST", "localhost"),
port: env.int("DATABASE_PORT", 5432),
database: env("DATABASE_NAME", "****"),
user: env("DATABASE_USERNAME", "****"),
password: env("DATABASE_PASSWORD", "****"),
ssl: {
rejectUnauthorized: env.bool("DATABASE_SSL_SELF", false),
      },
    },
debug: false,
  },
});
--------------------------------------.env---------------------------------
HOST=0.0.0.0
PORT=1337

Related

Nginx Multiple Projects Error Reloading Page 404

I had 3 projects in a same domain with Nginx:
/ --> Next.js(SSR)
/app --> ReactJS
/admin --> Angular
Nginx sites-availabe/myDomain.com:
upstream nextjs {
server 127.0.0.1:8080;
}
server {
listen [::]:443 ssl;
listen *:443 ssl;
ssl_certificate /etc/ssl/xxxx.crt;
ssl_certificate_key /etc/ssl/xxxx.key;
server_name myDomain.com;
access_log /var/log/myDomain.com/access.log;
error_log /var/log/myDomain.com/error.log error;
# for public asset into _next directory
location _next/ {
alias /srv/udemii-fe/.next/;
expires 30d;
access_log on;
}
location / {
proxy_pass http://nextjs;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /app {
alias /var/www/build-react;
try_files $uri $uri/ /index.html$args;
}
location ~ ^/app/((?!(static|(.*\..*))).)+$ {
try_files /app/index.html =404;
}
location /admin {
alias /var/www/build-angular;
try_files $uri $uri/ /index.html$args;
}
}
Error:
When I'm myDomain.com/admin/home or myDomain.com/app/home (including all other internal routes) and reload the page always show 404 error(error of Next.js main app)
How fix that?. Thanks.

React app on digitalocean droplet axios requests not working on other machines

Hey all I'm having an issue pulling up my website on my desktop. On my laptop where I created the app and did all the code my React app works fine and updates however on other machines only my components/elements load while my axios requests are returning (404 connection refused error). Any tips or fixes? P.S This is my first time trying to deploy an app build to a webserver (digitalocean/NGINX).
NGINX config file
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/epenn92reactapp.space/html/among-us-reactapp3/client/buil>
index index.html index.htm index.nginx-debian.html;
server_name epenn92reactapp.space www.epenn92reactapp.space;
error_page 405 =200 $uri;
error_page 404 /index.html;
location ^~ /assets/ {
gzip_static on;
expires 12h;
add_header Cache-Control public;
}
location /v1/api {
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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-Proto $scheme;
proxy_pass http://64.227.5.159:8080;
try_files $uri /index.html;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/epenn92reactapp.space/fullchain.pem; >
ssl_certificate_key /etc/letsencrypt/live/epenn92reactapp.space/privkey.pem>
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.epenn92reactapp.space) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = epenn92reactapp.space) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name epenn92reactapp.space www.epenn92reactapp.space;
return 404; # managed by Certbot
}
Example axios Route
const [chars, setChars] = useState([]);
useEffect(() => {
const fetchData = async () => {
try {
let res = await axios.get('http://localhost:8080/api/v1/character', {
});
setChars(res.data)
}
catch (err) {
console.log('error', err)
}
};
fetchData();
}, [chars.length]);
Server.js file
const PORT = process.env.PORT || 8080
package.json
"proxy": "http://localhost:8080/"
I've been reading around for about a day now and I'm just not sure what to do any help would be great thanks!

how to host react-js app with Hapi?

I have made a react-js app with react-router. I have set up my web-app with these endpoints:
/home
/user/:id
Everything works just fine until I try to host it on ec2 instance with Hapi.
First I found this tutorial, https://medium.com/#tribou/serving-react-and-flux-with-hapi-and-webpack-213afacf94ea but seems it just generate static html pages per-request, and all the component states are lost.
Then I found this one, https://medium.com/#notrab/using-create-react-app-with-hapi-js-8f4ef3dcd311, it packs everything into build/ with only one entry file, index.html. Then do I need to manually redirect /user/:id to build/index.html?
First you need inert plugin, register with your application.
This is my controller code for / endpoint:
exports.dashboard = {
auth: false,
description: 'main request handler',
handler: async (request, h) => {
return h.file('/PATH_TO_MY_BUILD_FOLDER/index.html', {confine: false});
}
};
Just that, it severs index.html from my disk.
You need to handle /static/css/ and /static/js/ folders because index.html contains links to that folders, I handled with nginx, you can use inert plugin of course, but nginx if you ask me, here is nginx config file for that
server {
listen 80;
server_name domain.com;
root /home/ubuntu/myapp/build;
# handle static files in build folder
location ~ ^/static/(.*)$ {
alias /home/ubuntu/myapp/build/static/$1;
}
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://localhost:3000;
proxy_pass_header Server;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_redirect off;
}
}
That's all.
Put that / handler to end of your route configuration, handle the /user/:id route long before the main / route.
Again, here is the route config for you:
server.route([
{
method: 'GET',
path: '/user/:id',
options: Controller.userDetail
},
{
method: 'POST',
path: '/user',
options: Controller.createUser
},
{
method: 'GET',
path: '/',
config: Controller.dashboard
},
{
method: 'GET',
path: '/{param*}',
config: Controller.dashboard
},
]);

NodeJS server on DigitalOcean using socket.io returns connection refused

I was trying to introduce socket.io to my application developed in Laravel and in AngularJS.
The application works fine in my computer, nevertheless when I try to make it work on the server I get the error 'GET http://localhost:8080/socket.io/?EIO=3&transport=polling&t=LQxpNjO net::ERR_CONNECTION_REFUSED'.
The server is running Ubuntu 16.04 and I am using nginx as a web server.
This is the file which creates the nodejs server:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
var port = 8080;
http.listen(port, function() {
console.log('Listening on *:' + port);
});
io.on('connection', function (socket) {
console.info('Client connected');
redis.subscribe('counter.increase');
redis.on('message', function (channel, message) {
console.log('Received message ' + message + ' in channel ' + channel);
socket.emit(channel, message);
});
socket.on('disconnect', function() {
console.info('Client disconnected');
});
});
This is the AngularJS factory that should connect to the nodejs server. Here I am using angular-socket-io:
angular.module('myServices').factory('socket', function (socketFactory) {
var ioSocket = io.connect('http://localhost:8080');
socket = socketFactory({
ioSocket: ioSocket
});
return socket;
});
This is the configuration file of nginx (/etc/nginx/sites-available/default):
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name XXX.XXX.XXX.XXX;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
How could I solve this problem?
Update 1
I updated the nginx configuration file like this:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name XXX.XXX.XXX.XXX;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~* \.io {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location ~ /\.ht {
deny all;
}
}
upstream app_yourdomain {
server 127.0.0.1:3000;
keepalive 8;
}
and the AngularJS factory like this:
angular.module('myServices').factory('socket', function (socketFactory) {
var ioSocket = io.connect('http://localhost:8080/socket.io');
socket = socketFactory({
ioSocket: ioSocket
});
return socket;
});
Now i get the following error:
- GET http://example.com/bower_components/socket.io-client/socket.io.js
Update 2
These are my nginx configuration file:
upstream app_example.com {
server 127.0.0.1:3000;
keepalive 8;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name XXX.XXX.XXX.XXX;
location / {
# First attempt to serve request as file, then as
# directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ ^/(socket\.io) {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location ~ /\.ht {
deny all;
}
}
and the AngularJS factory:
angular.module('myServices').factory('socket', function (socketFactory) {
var ioSocket = io.connect('http://localhost');
socket = socketFactory({
ioSocket: ioSocket
});
return socket;
});
Working solution
Thanks to John I finally managed to make the application work.
This is nginx configuration file:
upstream app_example.com {
server 127.0.0.1:3000;
keepalive 8;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name XXX.XXX.XXX.XXX;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ ^/(socket\.io) {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location ~ /\.ht {
deny all;
}
}
This is the AngularJS factory:
angular.module('myServices').factory('socket', function (socketFactory) {
var ioSocket = io.connect('http://example.com');
socket = socketFactory({
ioSocket: ioSocket
});
return socket;
});
This is the nodejs server:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
var port = 3000;
http.listen(port, function() {
console.log('Listening on *:' + port);
});
io.on('connection', function (socket) {
console.info('Client connected');
redis.subscribe('counter.increase');
redis.on('message', function (channel, message) {
console.log('Received message ' + message + ' in channel ' + channel);
socket.emit(channel, message);
});
socket.on('disconnect', function() {
console.info('Client disconnected');
});
});
Socket.io use /socket.io after your domaine name. Then you have to specify the socket.io location :
location ~* \.io {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
And don't forget the upstream for your node js app
upstream app_yourdomain {
server 127.0.0.1:3000;
keepalive 8;
}
For anyone else who is might be trying to figure this out like me, I just got this working after 4 hours of trying on a digital ocean server.
Follow the working solution that OP edited into the answer solved half of it, however I had to use a cdn for the links inside my html files.
Here's the cdn's to choose from https://cdnjs.com/libraries/socket.io.
Pick one and replace the url in <script src="http://localhost:3000/socket.io/socket.io.js"></script> with the cdn on the pages where you need it.
For my client side javascript (or angular in this case), just use the public domain name that you want to connect to the app with.
Also, make sure you add the the stuff you don't have in your nginx setup that OP wrote in the working answer. No need for the php section unless you're using php. I'm not so I omitted it. Make sure that you replace 'app_example.com' with the same address or domain that you used in your client side javascript.
This probably isn't the right place to post this but I can't comment yet and I don't want other people going through 4 hours of trial and error.
John's answer is correct.
In case someone is looking for extra info.
Suggesting that your localhost is on 9000 at EC2, with React framework for front-end.
Project structure
your-project-folder/api/app.js
your-project-folder/client/src/socket.js
Client(===your-project-folder/client/src/socket.js):
import { io } from "socket.io-client"; // make sure you have npm i socket.io-client under "your-project-folder/client"
export const socket = io.connect('https://yourdomain'); // production
// Develop: export io.connect('http://localhost:9000');
You do NOT need <script src="%PUBLIC_URL%/socket.io/socket.io.js"></script> under client/public/index.html because you access socket client from import { io } from "socket.io-client"; ...which is from your node_modules under your client/ folder.
And under server/ section inside /etc/nginx/nginx.conf
# Connect to socket io server
location ~* \.io {
proxy_pass http://localhost:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header Connection 'upgrade';
}

AngularJS, Nodejs and Nginx application returns 404 when trying to hit endpoint

So, I have tried to put a Nginx reverse proxy between my AngularJS client and the NodeJS server. All my static files are served as expected but some routes which are accessed using $http.get from an Angular service return 404. (such as app.get('/sessionInit') or app.get('/login')).
I will append to this some relevant parts of my code hoping that hey might help you in any way.
This is my API endpoint:
app.get('sessionInit', function(req, res){
if(sess){
res.send(JSON.stringify({
code : 610,
scope : "session",
message : "Session on the way !",
session : sess
}));
}else {
res.send(JSON.stringify({
code : 613,
scope : "session",
message : "Session does not exists or has expired please log in again.",
session : null
}));
}
});
This is my angular request:
this.getSession = function getSession(){
var promise = $http({
url: '/sessionInit',
method: "GET"
}).then(function (result) {
if(result.data.code == 610){
//update browser cookies
$cookies.putObject("userSession", result.data.session);
setUserInfo();
if(typeof($cookies.get("userSession")) != null) return $cookies.get("userSession");
else return null;
}else{
console.log(result.data.code, result.data.message, result.data.session);
return null;
}
});
return promise;
};
This is my nginx config file:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html/law-bid-nodejs;
index index.php index.html index.htm;
# Make site accessible from http://localhost/
server_name *mypublicip*;
location / {
try_files $uri $uri/ =404;
proxy_set_header 'Access-Control-Allow-Origin' '$http_origin';
proxy_set_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
proxy_set_header 'Access-Control-Allow-Headers' 'X-Requested-With,Accept,Content-Type, Origin';
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:3000;
}
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# # With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /\.ht {
deny all;
}
}
When trying to request the 'sessionInit' with angular from my NodeJS server where I have my route it is returning a publicip/sessionInit 404 not found error.
Any help is appreciated. Thank you !
Put a / before sessionInit
app.get('/sessionInit', function(req, res){
if(sess){
res.send(JSON.stringify({
code : 610,
scope : "session",
message : "Session on the way !",
session : sess
}));
}else {
res.send(JSON.stringify({
code : 613,
scope : "session",
message : "Session does not exists or has expired please log in again.",
session : null
}));
}
});
In your Nginx config try_files $uri $uri/ =404; will also cause an issue. /sessionInit is not an existing file and therefore will redirect to 404, add a specific section for your api before your location / {.. section and call /api/sessionInit from your angular app:
location /api/ {
proxy_pass http://nodejs/;
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-Proto https;
proxy_connect_timeout 30;
proxy_send_timeout 300;
proxy_read_timeout 900;
send_timeout 30;
}
In server_name, don't put an ip but an hostname like: mywebsite.local then edit your hosts file (/etc/hosts on linux/max) and append 127.0.0.1 mywebsite.local
--
Not Question Related
Don't bother yourself with res.send(JSON.stringify(..)) and use res.json(..) which would more look like the following:
app.get('/sessionInit', function(req, res){
if(sess){
res.json({
code : 610,
scope : "session",
message : "Session on the way !",
session : sess
});
}else {
res.json({
code : 613,
scope : "session",
message : "Session does not exists or has expired please log in again.",
session : null
});
}
});
Be also carful with CORS and think about using expressjs/cors if necessary.

Resources