Proxy a node/react application in an apache server - node.js

Using forever to forever run the node server on the virtual machine, I am unable to get the app to run without explicitly adding the port in the url like so: URL.com:8080
If I don't use the port in the URL, I do load up the file structure of the application.
Steps to reproduce: I have a create-react-app application.On the virtual server I run 'npm run build' to make sure I have a build to serve. I then run forever start on the root of the application.
The code below should give all the necessary details. I can provide more if you need.
I have spent so much time tweaking the .conf file to try different configurations but I can't seem to get it. I am using it and successfully hosting two static html sites but not this node application.
Package.json:
...
"main":"server/index.js",
"proxy":"http://localhost:8080"
...
Apache url.conf:
<VirtualHost *:80>
ServerName URL.com
ServerAlias URL.com:8080/
DocumentRoot /var/www/nameOfApp/
<Directory />
Options -Indexes +FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/nameOfApp/public>
Options +Indexes +FollowSymLinks +MultiViews
AllowOverride All
</Directory>
</VirtualHost>
Node server file using express:
app.use(express.static(`${__dirname}/../build`));
I've also made sure I have the modules enabled to allow for proxying. So I think essentially, what I need is to request this site and not need the :8080 at the end.

Apache and NodeJS are 2 different and separate application.
You interact with them by sending request to the port that they are listening to. In your case here,
Apache is listening at port 80
Your NodeJS application is listening at port 8080
So all request to port 80 will be handled by Apache, and since you do not has an index.html, Apache will default to just list out the files and directory (Options Indexes). Up until this point, your node application do not know anything about your request.
So what you need to do is define some endpoint, say url.com/node, and tell Apache to forward all request of this endpoint to port 8080 and let your node application to do the job.
How to do this?
http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass
Best practices when running Node.js with port 80 (Ubuntu / Linode)
Node.js + Nginx - What now?
Hope this points you to the right direction.

The configuration that eventually worked was as simple as this:
<VirtualHost *:80>
ServerName yourdomain.com
ProxyPreserveHost on
ProxyPass / http://localhost:8080/
</VirtualHost>
Looks like I was over complicating it trying to create a complicated proxy but the solution was very simply adding this to the config for the node application and then running sudo systemctl restart apache2 and everything worked beautifully.

Related

Change name of local web service

I setup a local guacamole server for people in my work to access several VM's that we have running in the server. IN order to access guacamole the have to type http://ip:port/guacamole or after the host override I did in my pfsense DNS resolver http://guac.loc:port/guacamole. The problem is that even that some times is problematic for some of them so I want to do something like http://guac.loc so they can remember it easily. I did it for some with the hosta file but I can't different functionallities for some of them. So can anyone help on how to do that? Can I do it somehow from the web server? Or do I need to setup a DNS Server?
If I understand correctly, you want to have "simpler" URL, without port and "guacamole" path.
Guacamole by default runs under Tomcat on port 8080. However, you can put Apache in front of the Tomcat and proxy request to the guacamole. Apache can proxy and forward all requests to the Guacamole on the given port and path.
Something like the example below should work and also will redirect all http requests to the htpts. It is not mandatory to have SSL enabled, you can proxy http as well.
<VirtualHost *:80>
ServerName guac.loc
Redirect permanent / https://guac.loc/
</VirtualHost>
<VirtualHost *:443>
ServerName guac.loc
SSLEngine on
SSLCertificateFile /etc/ssl/certs/guac-loc.cer
SSLCertificateKeyFile /etc/ssl/private/guac-loc.key
SSLCACertificateFile /etc/ssl/certs/guac-loc-ca.crt
<Location /guacamole/>
ProxyPass http://localhost:8080/guacamole/ flushpackets=on
ProxyPassReverse http://localhost:8080/guacamole/
Order allow,deny
Allow from all
</Location>
</VirtualHost>

My PeerJS Server returns an ID, but then I get 404 on follow up requests to '/peerjs'

I'm working on a WebRTC video conferencing/remote performance site (built on an AWS "Lightsail" VM), and I've run into a very odd issue with PeerJS.
I'm hosting my own PeerJS server on port 3001, via an Apache2 reverse proxy. The reverse proxy seems to work correctly, because when peerjs.min.js hits '/peerjs/id' it returns an ID as expected.
However, subsequent calls to '/peerjs' that are made from inside the peerjs.min.js file instantly return a 404 error.
(I should note that my site works correctly if I simply use the default PeerJS server.)
So, for example, this request works as expected:
https://peer.improv-stage.com/peerjs/id
While this follow up request (which again, is kicked off from inside peerjs.min.js), results in a 404 error.
wss://peer.improv-stage.com/peerjs?key=peerjs&id=bd261271-09f7-44a3-a07e-3d3364c1989f&token=40sh9uviwb
(The id and token, parameters here are from a single invocation of the page, and will change on each visit, of course.)
I'm pretty sure it's a problem with my server setup, so, here's the info for that...
I'm invoking the Peer Server with the following command inside the htdocs directory:
peerjs --port 3001 --proxied true
And it replies with:
Started PeerServer on ::, port: 3001, path: / (v. 0.6.1)
And here's the relevant vhosts config from apache:
<VirtualHost *:443>
ServerName peer.improv-stage.com
DocumentRoot "/opt/bitnami/apache/htdocs"
ProxyPass / http://127.0.0.1:3001/
ProxyPassReverse / http://127.0.0.1:3001/
SSLEngine on
SSLCertificateFile "/opt/bitnami/letsencrypt/certificates/improv-stage.com.crt"
SSLCertificateKeyFile "/opt/bitnami/letsencrypt/certificates/improv-stage.com.key"
<Directory "/opt/bitnami/apache/htdocs">
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Another thing to note is that this lives on the same server as the site "Improv Stage" site itself. The improv stage site is a NodeJS app and it invokes the peer server (on the client side), with the following:
var myPeer = new Peer(undefined, {
host: 'peer.improv-stage.com',
port: 443,
secure: true,
path: "/",
debug: 3
})
I'm thinking that the solution will be to spin up another VM just for the Peer Server, but this entire thing bugs me. It should work, shouldn't it?
In any case, the site is currently live as I write this, and I'll leave it up and running until at least a few of you have had a look at it and offer some feedback. You can reach it at:
https://www.improv-stage.com/stackoverflow
Thanks for any ideas you can offer!
Diz
By adding this line of code to apache2 this problem solved for me:
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteRule /(.*) ws://localhost:9500/$1 [P,L]
please note 9500 is the specific port that peerServer runs on it.
I have express and socket.io on port 3000 and peerServer on port 9500.
this answer helped a lot.
I think it is very dependent on web server configuration.

How can I make a ProxyPass work for all pages without defining a new rule for each page

I'm very new to setting up apache configs. The docs don't make much sense to me, I have a node app running on a port that functions as a website, but I want to be able to connect to it with my domain. I've been looking around and figured I need to use a ProxyPass to redirect traffic from port 443 (https) to the port the app is running on (I already use apache for other stuff so I didn't want to switch). And it works generally, but is there a way to make only a single ProxyPass rule that will handle all pages (e.g. I go to https://example.com/ it will use https://localhost:4450/ and if I go to https://example.com/example it will use https://localhost:4450/example and for all other pages).
I would think I need a RewriteRule, but I don't really understand how I can get the page (whatever is after the first / or none) using it.
You simply run apache as a reverse proxy here is an example configuration:
<VirtualHost *:443>
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/file.pem
ProxyPreserveHost On
ServerName localhost
ProxyPass / http://0.0.0.0:4450/
ProxyPassReverse / http://0.0.0.0:4450/
</VirtualHost>
and you have to enable the proxy modules like that
a2enmod proxy
a2enmod proxy_http

how to run multiple cross platform web application on the same server using different ports?

I am running a java web application on tomcat 7.0, which is setup on media temple Ubuntu 16.04 server. The application is running on port 8080, and I have a domain which is binded to the port.
e.g. public-ip-of-server:8080 xyz.com
Now, I want to run a node js application (rocket-chat) on the same Linux server using port 3000. I have configured the whole application, and the application is running on localhost:3000/ but when I am trying to access the application using public IP of the server (e.g. public-ip:3000/), I am not able to access it.
I have allowed the traffic on port 3000 using command,
ufw allow 3000
I also edited apache2.conf,
ProxyPass /rocketchat http://public-ip-of-server:3000/
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module
modules/mod_proxy_http.so
but after changing this parameter I am not able to restart the apache2 service.
so I revert back the changes.
what should I do to run both the application (java and node js) on the same Linux server ? can anyone please help me out.
Just bind nodejs app to interface 0.0.0.0 instead of 127.0.0.1.
In your Apache configuration, you should use the localhost instead of public ip. So instead of:
ProxyPass /rocketchat http://public-ip-of-server:3000/
use:
ProxyPass /rocketchat http://localhost:3000/
I am using Ubuntu server so httpd.conf is not present there, so I have created another file, in sites-available folder of apache2.(e.g xyz.conf).
I have two domain which pointing to the same media temple name server,
I used one domain for pointing tomcat application on port 8080 and another domain for node js application on port 3000, by making virtual host in xyz.conf
<VirtualHost *:80>
ServerName xyz.com
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
</VirtualHost>
<VirtualHost *:80>
ServerName abc.com
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
After this I enabled proxy mode using command :
sudo a2enmod proxy
And also make this xyz.conf file as site configuration file, using command,
sudo a2ensite xyz.conf
It will ask you to reload the apache2 service,
just reload it and restart,
e.g sudo systemctl restart apache2.service
The problem resolved by forwarding the request, which is received on port 80 of apache2, to tomcat:8080 and nodejs:3000, by creating virtual host.

Run NodeJS app on httpd subdomain

Thanks in advance for your help,
I want to launch a nodeJS application through httpd (RedHat) in a server that has a lot of VirtualHosts, so I went to the httpd conf file located at /etc/httpd/conf/httpd.conf and added in the end of the file the following configuration:
<VirtualHost *:80>
ServerName subdomain.example.com
ProxyPreserveHost on
ProxyPass / http://localhost:8080/
</VirtualHost>
My NodeJS app is running on localhost:8080 but when I go to subdomain.example.com I am just getting a Server Not found error. Tried a lot of combinaisons in the httpd config file that I have found in the internet but in vain. I restart the httpd service everytime I did a change to the config file by running service httpd restart
This was only a DNS propagation issue. Fixed by adding an A record to the DNS entries.

Resources