How to setup Mojolicious with nginx? - perl

Required to develop a web application using Mojolicious. Therefore required to setup with a web server.

From the Mojolicious Nginx documentation:
One of the most popular setups these days is Hypnotoad behind an Nginx reverse proxy, which even supports WebSockets in newer versions.
upstream myapp {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://myapp;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Ad:
Required to develop a web application using Mojolicious. Therefore
required to setup with a web server.
isn't true. Just follow the: http://www.mojolicious.org
put into some file, let say: mojo.pl
use Mojolicious::Lite;
get '/' => {text => 'I ♥ Mojolicious!'};
app->start;
To run this example with the built-in development web server start it with morbo.
$ morbo mojo.pl
it will answer:
Server available at http://127.0.0.1:3000
Just CLICK THIS LINK in your browser. You will get
I ♥ Mojolicious!
And could start the development immediatelly. Setting the nginx is enough much-much later - for the deployment.

Related

Running a proxy_pass on a subpath in NGINX

I am trying to run a Flask app on Gunicorn through an Nginx server. I would like the app to run on a sub-directory instead of through a different port, if possible, but all I get are 404 errors. Here is my conf file, which is an included file in the conf.d folder:
server {
listen 80;
server_name 127.0.0.1;
location / {
root /var/www/html;
}
location /chess/ {
proxy_pass http://unix:/usr/share/nginx/sockets/chess.sock;
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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Could someone please tell me how to do this? I have looked all over and tried a lot of different things, to no avail. It runs fine on a different port, but that is not what I want. A subdomain is also a suitable option, but I can only get that to work in production, not development, for some reason. Someone posed the question here but the link they gave to the solution is dead.
when do you get 404's? when you access /chess/?
please attach the flask app's code.
anyway,
the following certainly works, I tested it.
followed this guide
myproject.py:
from flask import Flask
app = Flask(__name__)
#app.route("/chess/",defaults={'name': None})
#app.route("/chess/<name>")
def hello(name):
if name is None:
name="!"
else:
name = ", " + name
# PLEASE don't use the following line of code in a real app, it creates a self-xss vulnerability. ALWAYS sanitize user input.
return f"<h1 style='color:blue'>Hello There{name}</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
nginx - /etc/nginx/sites-enabled/myproject (symlink)
server {
listen 8080;
server_name your_domain www.your_domain;
location / {
root /home/username/myproject/static/;
}
location /chess/ {
include proxy_params;
proxy_pass http://unix:/home/username/myproject/myproject.sock;
}
}
<host>:8080/chess/stackoverflow:
<host>:8080/a.html: (actually served from /home/myproject/static)
generally and for future reference - try looking at nginx logs (/var/log/nginx) or service logs (journalctl -u myproject or systemctl status myproject)
Two methods are available. The first method involves adding the subpath to both the NGINX configuration and the Flask app, as suggested in the answer by Yarin_007. Set up NGINX like so:
server {
listen localhost:80;
location / {
root /var/www/html;
}
location /chess/ {
proxy_pass http://unix:/usr/share/nginx/sockets/chess.sock;
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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
And alter the Flask app to include the subpath:
from flask import Flask, request
...
#app.route("/chess/", methods=["GET", "POST"])
...
The alternative, as suggested in this answer is to run the Gunicorn service on a non-privileged port (or maybe a subdomain) and use two proxy_pass directives to direct from the port 80 subpath like so:
server {
listen localhost:80;
location / {
root /var/www/html;
}
location /chess/ {
proxy_pass http://localhost:8080/;
}
}
server {
listen localhost:8080;
location / {
proxy_pass http://unix:/usr/share/nginx/sockets/chess.sock;
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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
The Flask app can remain as it was originally:
from flask import Flask, request
...
#app.route("/", methods=["GET", "POST"])
...

Flutter app cannot make socket connection with certificate handshake error CERTIFICATE_VERIFY_FAILED

One might say this question is a duplicate, but it is not, as other questions this type are about self-signed certificate, and about development environment.
I have a valid certificate from letsencrypt.org, but I cannot manage to establish socket connection. I have a nodejs server where I use the module "ws", and use the package "web_socket_channel" in flutter.
I had the same handshake problem for all my http requests (using requests package) but I could bypass it adding option verify to false:
final r = await Requests.get(app_url, verify: false);
I don't like this solution as it is not secure for production environment.
I would like a solution that would suit production environment.
Thanks to you all
For every one reading this, the problem was not from my flutter code, it was from my nginx configuration, I had to add the following lines to
/etc/nginx/conf.d/sysmon.conf file:
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://<SERVER_IP>:<PORT>;
}

Virtual host with sails.js

I want to have subdomains for my app.
For example:
myapp.com
admin.myapp.com
static.myapp.com
And directory structure like this:
myapp
frontend [sails app] -> myapp.com
backend [sails app] -> admin.myapp.com
static [express app] -> static.myapp.com
app.js
In express I could use vhost.
How can I achieve this in sails.js?
I have not tried it, but I think it can be done using Nginx's reverse proxy.
Let's say you have 2 SailsJS projects (Sails1 and Sails2) configured to run on two different ports (port 1337 and port 1338) respectively. You can configure the SailsJS app to run on any port by making changes in /config/locals.js
Now follow below steps:
Run both applications using "sails lift" or "forever" commands
Install Nginx
Config Nginx
$ cd /etc/nginx/sites-available/
$ sudo touch sails1.conf
$ sudo touch sails2.conf
$sudo ln -s /etc/nginx/sites-available/sails1.conf
/etc/nginx/sites-enabled/sails1.com.conf
$ sudo ln -s /etc/nginx/sites-available/sails2.conf
/etc/nginx/sites-enabled/sails2.conf
Put below content in /etc/nginx/sites-available/sails1.conf
server {
listen 80;
server_name sails1.com;
location / {
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;
}
}
Put below content in /etc/nginx/sites-available/sails2.conf
server {
listen 80;
server_name sails2.com;
location / {
proxy_pass http://localhost:1338;
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;
}
}
Restart Nginx and try accessing sails.com and sails2.com hopefully you should be able to see both your website.
I haven't used vhosts directly with sails, but you can access the underlying express engine pretty easily..
//./config/express.js
module.exports.express = {
customMiddleware: function (app) {
app.use(vhost('*.example.com', require('app1'));
app.use(vhost('example.com', function(..){...}));
app.use('/queue', require('kue').app);
}
}

Nginx site configuration disabling 301 rewrite for another site

I currently have two enabled site configurations in nginx, let us call them old-site.example and new-site.example. There is no other site configuration active.
old-site.example should 301-redirect to new-site.example. This currently works well as long as the old-site.example configuration is alone. After adding the new-site.example configuration file, it does not redirect anymore.
oldsite.conf:
server {
listen 80;
server_name *.old-site.example;
rewrite_log on;
location / {
return 301 http://www.new-site.example$request_uri;
}
}
newsite.conf:
server {
listen 80;
server_name www.new-site.example;
charset utf-8;
location / {
#forward to application server
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_pass http://127.0.0.1:8080;
}
}
other configuration details:
JBoss AS7 as application server running behind Nginx 1.5.1
This was a DNS related error, sorry everyone.
Background: The ISP of the client managed to "smart redirect" the domain instead of using DNS. They basically scraped the new site on their servers and returned it via the old domain. I'm speechless.
If you ever have a problem like this, check DNS resolution before second-guessing your config.

Socket.io/WebSockets continuously reconnecting — issue with Nginx proxy configuration?

I am using Socket.IO in my Node.js application. Today I deployed it for the first time, and I noticed that my sockets keep reconnecting. I have "connect" and "disconnect" logging to the console in the respective socket events, and this is the result:
What's more, it seems that the polling technique is being used, when my browser is surely modern enough to use WebSockets — so I believe this is a configuration issue. WebSockets work fine when I am running the Node.js in development with no proxy in the middle.
This is my Nginx configuration, which serves as a proxy to my Node.js server:
upstream reader.oliverjash.me {
server 127.0.0.1:3000;
}
server {
listen 80;
server_name reader.oliverjash.me;
access_log /var/log/nginx/reader.oliverjash.me.access.log;
error_log /var/log/nginx/reader.oliverjash.me.error.log;
location / {
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_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://reader.oliverjash.me;
proxy_redirect off;
}
}
I believe that the lines:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
are significant in enabling WebSockets (as per this reference/tutorial). Before I added these, WebSockets did not work at all with the proxy. Now I seem to get polling, which is better than nothing.
My Nginx version is 1.4.0 stable.
Turns out the problem was because I had clustered my Node apps. Added Redis as a memory store for Socket.IO and that solved all of my problems! http://adamnengland.wordpress.com/2013/01/30/node-js-cluster-with-socket-io-and-express-3/