skip to Main Content

I am running XAMPP on Windows to host an Apache server on port 80. Now I’m trying to have a NodeJS script running in the background but the problem is that it can only listen on port 80. If it does, everything works as it should but I can’t have Apache running at the same time, because Apache takes priority and just serves my website. The NodeJS script doesn’t even get to listen.

My question is: how do I switch the listening port of the NodeJS script (the specific port really doesn’t matter) so that Apache can still run on port 80 and I can reach the NodeJS script from all around the world.

Part of the NodeJS code:

const http = require('http');

const port = 8080;
const host = '0.0.0.0';




server = http.createServer( function(req, res) {
    if (req.method == 'POST') {
        var body = '';
        req.on('data', function (data) {
            body += data;
            doStuff(body);
        });
        res.writeHead(200, {'Content-Type': 'text'});
        res.end('received request successfully');
    }
    else {
        res.writeHead(405, {'Content-Type': 'text'});
        res.end('not allowed method ' + req.method + ', try again with GET or POST');
    }

})

server.listen(port, null, function(error){
  if(!!error){
    console.log("x1b[41m%sx1b[0m", "error while initializing listener on port " + port + ": " + error);
   }
   else{
    console.log("x1b[32m%sx1b[0m", "started listener at 'http://" + host + ':' + port + "'");}
 });

Additional information is in my other question which got flagged as duplicate.

6

Answers


  1. Just change your node.js server port something like:

    var server = app.listen(8080, function() {
        console.log('Ready on port %d', server.address().port);
    });
    

    where 8080 is node.js server’ new port.

    Login or Signup to reply.
  2. Looking at your other question, which was marked as duplicate of this one, you’ve got some additional information there that will probably help to elucidate what you’re needing. Specifically, you mention the following:

    I want to host multiple http servers with NodeJS, that all get and send http requests. At the same time I want to have Apache running, which occupies port 80. If I disable Apache and let NodeJS run on port 80, it will work but I can’t have them running at the same time.

    This script will run and receive requests locally at port 8081, but I can’t seem to send an AJAX request to it through the Internet, even after forwarding the port with my router:

    I think @ankit-agarwal is probably right in that you need a reverse proxy setup to forward traffic to your different backends. Assuming you’ve got an externally facing IP address, you should be able to access each of your backends using the ports they are listening on. For example, if the exposed public IP address of your machine is 100.120.110.43:

    +---------+------+-------------------------------------+
    | Backend | Port |             Web Address             |
    +=========+======+=====================================+
    | Apache  |   80 | 100.120.110.43 or 100.120.110.43:80 |
    | Node1   | 8080 | 100.120.110.43:8080                 |
    | Node2   | 8081 | 100.120.110.43:8081                 |
    +---------+------+-------------------------------------+
    

    If you want to access each of the backends without specifying the port, you have to have some way to tell your internal network which backend to serve based on the request. One way of doing this is to use path based routing, where you setup your reverse proxy to route the traffic to the different backends based on the path in the url. You didn’t post your Apache configuration, but you can use your current Apache server to handle this using the ProxyPass and ProxyPassReverse directives similar to below:

    ProxyPass "/node1"  "http://100.120.110.43:8080/"
    ProxyPassReverse "/node1"  "http://100.120.110.43:8080/"
    
    ProxyPass "/node2"  "http://100.120.110.43:8081/"
    ProxyPassReverse "/node2"  "http://100.120.110.43:8081/"
    

    The cool thing about using a reverse proxy is that you don’t have to expose your node backends to the public. Let’s assume you haven’t, and they are only accessible from the internal network at 0.0.0.0:port.

    Listen 80
    <VirtualHost *:80>
        DocumentRoot /www/apache
        ServerName www.apachefrontend.com
        ProxyRequests off
        ProxyPass /node1  http://0.0.0.0:8080/
        ProxyPassReverse /node1  http://0.0.0.0:8080/
        ProxyPass /node2  http://0.0.0.0:8081/
        ProxyPassReverse /node2  http://0.0.0.0:8081/
    </VirtualHost>
    

    You could also point to different hosts/ips that only you have access to.

    Finally, you can also use VirtualHost and ServerName if you have different DNS records to point to the different backends.

    Listen 80
    <VirtualHost *:80>
        DocumentRoot /www/apache
        ServerName www.apachefrontend.com
    </VirtualHost>
    <VirtualHost *:80>
        ServerName www.nodebackend1.com
        ProxyRequests off
        <Proxy *>
            Order deny,allow
            Allow from all
        </Proxy>
        <Location />
            ProxyPass /  http://0.0.0.0:8080/
            ProxyPassReverse /  http://0.0.0.0:8080/
        </Location>
    </VirtualHost>
    <VirtualHost *:80>
        ServerName www.nodebackend2.com
        ProxyRequests off
        <Proxy *>
            Order deny,allow
            Allow from all
        </Proxy>
        <Location />
            ProxyPass /  http://0.0.0.0:8081/
            ProxyPassReverse /  http://0.0.0.0:8081/
        </Location>
    </VirtualHost>
    

    For any of the above to work, you need to have mod_proxy and mod_proxy_http enabled in apache.

    These probably aren’t the most robust examples and I haven’t tested them, but they should demonstrate the idea. You can learn more here.

    Login or Signup to reply.
  3. I haven’t really understood what you meant by you’re not getting any response, because I ran the same code and it works fine for me.

    I only noticed something here (I kept a note for you in the comment)

    server = http.createServer( function(req, res) {
        if (req.method == 'POST') {
            var body = '';
            req.on('data', function (data) {
                body += data;
                doStuff(body); //you haven't defined doStuff so you will end up with a error message on this line, but you sever will still run fine
            });
            res.writeHead(200, {'Content-Type': 'text'});
            res.end('received request successfully'); 
        }
        else {
            res.writeHead(405, {'Content-Type': 'text'});
            res.end('not allowed method ' + req.method + ', try again with GET or POST');
        }
    
    })
    

    Postman image

    When running your post request, don’t forget to add "" in your body area, select raw then choose JSON(application/json). That should run fine for you, except you might get a reference error as shown below, but you should still get your response of received request successfully.

    error

                doStuff(body);
                ^
    
    ReferenceError: doStuff is not defined
    

    Ensure that you’re doing the same thing and let us know if your issue it resolved.

    Login or Signup to reply.
  4. Seem something already running on your 8080 port. Simply change to another port. For example 7000
    And make sure that all request you call to nodejs app like this

    localhost:7000 // Normal we run at port 80 url simply localhost without port
    
    Login or Signup to reply.
  5. This is same scenario as using NodeJs in a Shared Hosting. I have written a blogpost about it here

    Let me give an excerpt.

    1. Just run the NodeJS server at let’s say 8080 port.

    2. Now, let’s say your Apache serves at http://example.com, create a folder in your public_html or www. let’s say the name is server. So, your new folder path is http://example.com/server

    3. create a .htaccess file in the server folder
    4. add the following lines,

      RewriteEngine On
      RewriteRule ^$ http://127.0.0.1:8080/ [P,L] #which is your node server ip:port
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^(.*)$ http://127.0.0.1:8080/$1 [P,L] #same ip:port
      

    This will redirect all the requests from http://example.com/server to your Node server.

    Login or Signup to reply.
  6. If I want use Apache and Nodejs in same port:
    npm http-proxy-middleware

    1. Set Apache Port = 81

    [apache dir]/conf/httpd.conf

    ~59: Listen 81

    2. Set nodejs APP port = 3050

    server.listen(3050);
    // on linux ports<1000 require root privilegue

    3. Use third proxy APP (http-proxy-middleware)

      // https://www.npmjs.com/package/http-proxy-middleware
      var express = require('express');
      var proxy = require('http-proxy-middleware');
    
      // proxy middleware options
      var options = {
          target: 'http://localhost:81', // target host ROOT
          changeOrigin: true, // needed for virtual hosted sites
          ws: true, // proxy websockets
          pathRewrite: {
              // '^/api/old-path' : '/api/new-path',     // rewrite path
              // '^/api/remove/path' : '/path'           // remove base path        
          },
          router: {
              // Examples:
              // when request.headers.host == 'dev.localhost:3000',
              // override target 'http://www.example.org' to 'http://localhost:8000'
              // 'dev.localhost:3000' : 'http://localhost:8000',
              // 'localhost:9000': 'localhost:9002/sub',                 
              // '/sub': 'http://localhost:9002',
    
              'localhost': 'http://localhost:81',         //Root to Apache
              'sub.localhost': 'http://localhost:3050',  // internal
              'sub.mydomain.com': 'http://localhost:3050', //external
          },
      };
    
      // create the proxy (without context)
      // var proxy_wp = proxy(options_wp);
      var proxy_node = proxy(options);
    
      // mount `exampleProxy` in web server
      var app = express();
      app.use(proxy_node);
      app.listen(80);
    

    Then:

    1. localhost:80 – is apache site
    2. sub.localhost:80 – node
    3. localhost:80/sub – node, if you set

    for task runner i use npm PM2

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search