1

I have a node app, it runs great in VS Code, and I can launch it using the script command from the terminal window.

It's just a utility I'd like running in the background on my dev machine. It watches for keystrokes and sets my busy / idle indicator to other apps. It uses iohook if you're curious, to do this.

How can I deploy it to just be running in the background (all the time, including at startup)? I'm going to deploy it as a web server so I don't have to mess with linux services.

I already have apache and nginx and all that other web server stuff installed from the numerous tutorials I've done, but I don't know how to deploy to any of them.

I tried this:

https://plainenglish.io/blog/deploying-a-localhost-server-with-node-js-and-express-js

but that only enables launching from vs code or command line, it's not a real "server" that runs all the time, doesn't require a terminal window and starts on system startup.

I need this running from apache or nginx or something like that.

https://www.ionos.com/digitalguide/websites/web-development/nodejs-for-a-website-with-apache-on-ubuntu/

I tried:

To access the Node.js script from the web, install the Apache modules proxy and proxy_http with the commands:

sudo a2enmod proxy
sudo a2enmod proxy_http

Once the installation is complete, restart Apache for the changes to take effect:

sudo service apache2 restart
  • Does this answer your question? [Run a shell script and immediately background it, however keep the ability to inspect its output](https://stackoverflow.com/questions/44222883/run-a-shell-script-and-immediately-background-it-however-keep-the-ability-to-in) – Konrad Jan 16 '23 at 16:48
  • @Konrad, no sir. That wouldn't survive a reboot. I'm looking to make my dev machine a "web server" in the devops sense, with some "web server" process running my app as one of its "web sites". Instead of publishing my nodejs app to a external 'web host' with a hosting company, I want to publish to my dev machine. Make sense? – Stupid Questions Jan 16 '23 at 16:52
  • I didn't understand that, but here is how to run a command on system start up https://askubuntu.com/questions/228304/how-do-i-run-a-script-at-start-up – Konrad Jan 16 '23 at 16:55
  • *I'm going to deploy it as a web server so I don't have to mess with linux services* - I don't get that either – Konrad Jan 16 '23 at 16:56
  • @Konrad, see the last link in my edited question. That's what I'm trying to do. Maybe I'm using the wrong buzzwords for you to get it. – Stupid Questions Jan 16 '23 at 17:05
  • If you want to use a proxy, your server must be running simultaneously. You can't run the node server using apache or nginx – Konrad Jan 16 '23 at 17:10
  • @Konrad, in that link it says right at the top, "Although open source JavaScript Node.js scripts can be run from the command line using screen, running the scripts as a service using the process manager PM2 gives the scripts a more robust set of behaviors. When run as a service this way, the scripts will automatically restart if the server is rebooted or the script crashes." It's how to run a nodejs app on apache. So, yeah? – Stupid Questions Jan 16 '23 at 17:20
  • [`pm2`](https://pm2.keymetrics.io/) is a process manager installed through npm, it's not related to apache – Konrad Jan 16 '23 at 17:25
  • 1
    @Konrad, thanks for your efforts and please see my answer below which I have tested and is working. Now do you get it, now that you see the answer? Please to help me in the future, what was it about my question that threw you off into a very different solution from what I was conceiving the answer to be? I'm trying to work on my communication skills. This happens to me a lot, getting my questions misunderstood by a huge amount. What term would I have used for you to conceive of the actual answer below, instead of the term I actually used? – Stupid Questions Jan 16 '23 at 21:26
  • I'm glad that you've managed to do it. Your question is generally clear :) – Konrad Jan 16 '23 at 21:32

1 Answers1

1

[Linux Mint] Running a web app on local machine

First website

  1. [Terminal] Install node.js: sudo apt-get install nodejs
  2. [Terminal] Install apache: sudo apt-get install apache2
  3. [Terminal] Install PM: sudo npm install -g pm2
  4. [Terminal] start apache: sudo systemctl status apache2
  5. [Browser] test apache: localhost
  6. [Terminal] Go to your web root. It can be wherever you like: cd /home/homer-simpson/websites
  7. [Nemo][root] Create app folder: /home/homer-simpson/websites/hello-app
  8. [Nemo][root] Create node.js hello world file: /var/www/html/hello-app/hello.js
  9. [Terminal] Make hello.js executable: sudo chmod 755 hello.js
  10. [xed][root] Create node.js app in this file: See hello.js listing
  11. [Terminal] Run from terminal as test: node hello.js
  12. [Browser] Test web site: http://localhost:4567/
  13. Shut down node app CTRL+C
  14. Start up app in PM: sudo pm2 start hello.js
  15. [Terminal][root] Add PM to startup scripts: sudo pm2 startup systemd
  16. [Terminal][root] Save PM apps: pm2 save
  17. [Terminal] enable apache modules: sudo a2enmod proxy && sudo a2enmod proxy_http && sudo service apache2 restart
  18. [Nemo][root] Open as root apache config: /etc/apache2/sites-available/000-default.conf
  19. [xed][root] add / replace config for your website: See 000-default.conf listing
  20. [Terminal] restart apache: sudo systemctl restart apache2
  21. [Browser] test the website: http://localhost/hello-app
  22. Hello World!

Subsequent websites:

  1. [Nemo][root] Create new app folder under your website root: /home/homer-simpson/websites/another-app
  2. [Nemo][root] Copy scripts into there and make executable
  3. [Terminal] Start up app in PM: sudo pm2 start another-app.js
  4. [Terminal][root] Save PM config: pm2 save
  5. [Terminal][root] Add new website to apache config under a new Location tag with the port number of the new app (must be unique): sudo xed /etc/apache2/sites-available/000-default.conf
  6. [Terminal] restart apache: sudo systemctl restart apache2

View it over the LAN:

  1. [Firewall] Set to "Home" profile. Incoming deny, outgoing allow, enabled
  2. [Firewall] Add a rule, simple tab, port 80, name "Apache"
  3. [Terminal] Get your hostname: hostname
  4. [Terminal][root] Change your machine name to something cool: hostname tazerface
  5. [xed][root] Change the host name in /etc/hosts
  6. [xed][root] Change the host name in /etc/hostname
  7. Reboot tazerface. <= that's your machine name now. Omg that's such a cool name.
  8. Make sure pm2 started automatically and has your apps listed as "online": pm2 list
  9. [phone][browser] Test your website: http://tazerface/hello-app
  10. If it doesn't work, make sure tazerface isn't using a wifi provided by a network repeater. It needs to be on the same wifi network as the phone (but can be on either the 5GHz or 2.4GHz variant)

Add free ssl certificate:

  1. [Terminal] Add ssl module: sudo a2enmod ssl
  2. [Firewall] Add a rule, simple tab, port 443, name "Apache ssl"
  3. [Terminal] create self signed free certificate: sudo openssl req -x509 -nodes -days 999999 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
  4. [Terminal] Leave all answers default (by hitting enter) except common name, enter tazerface
  5. [Terminal] Test certificate: openssl verify apache-selfsigned.crt
  6. [Terminal] Replace contents on .conf with ssl .conf listing below: sudo xed /etc/apache2/sites-available/000-default.conf
  7. [Terminal] Restart Apache: sudo systemctl restart apache2
  8. [phone][browser] Test your website: https://tazerface/hello-app

hello.js

var http = require('http');  
//create a server object:  
const port = 4567
http.createServer(function (req, res) {  
    res.write('Hello World!'); //write a response to the client  
    res.end(); //end the response  
}).listen(port); //the server object listens on port 4567   
// Console will print the message  
console.log(`Server running at ${port}`); 

000-default.conf (no ssl)

<VirtualHost *:80>
ServerName example.com

<Directory /var/www/>
    Options -Indexes +FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

   ProxyRequests Off
   ProxyPreserveHost On
   ProxyVia Full
   <Proxy *>
      Require all granted
   </Proxy>
   <Location /hello-app>
      ProxyPass http://127.0.0.1:4567
      ProxyPassReverse http://127.0.0.1:4567
   </Location>
</VirtualHost>

000-default.conf (ssl)

# The only thing in the firewall that needs to be open is 80/443
<VirtualHost *:80>
    Redirect / https://tazerface/

</VirtualHost>

<VirtualHost *:443>
   ServerName tazerface

<Directory /var/www/>
    Options -Indexes +FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

   SSLEngine on
   SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
   SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

    ProxyRequests Off
    ProxyPreserveHost On
    ProxyVia Full
    <Proxy *>
        Require all granted
    </Proxy>

    <Location /hello-app>
        ProxyPass http://127.0.0.1:4567
        ProxyPassReverse http://127.0.0.1:4567
    </Location>


</VirtualHost>
  • 1
    Do **NOT** place your node.js server code in the apache document root! – Marc Jan 17 '23 at 12:01
  • 2
    Because a browser can fetch your code and find security risks and potential hardcode credentials. Is it really so hard to imagen what could bad things happens when your hole application codes is in the wrong hands? Its not about personal preference, its about security and best practice. There is absolutely no reason why a client could download your node.js server code. But what do i know, 10+ years linux admin & 4+ years as dev-ops engineer. But please continue to give bad advice... – Marc Jan 17 '23 at 19:52
  • 1
    You can drop the whole static assets handling in apache. The apache works just as reverse proxy. Move your code to a diffrent directy e.g. `/opt/myapp`, remove the " – Marc Jan 18 '23 at 06:47
  • @Marc, I followed your advice and tested it on my machine, and it works, and I updated the instructions. Hopefully I didn't introduce any new security mistakes. Thanks for your time! – Stupid Questions Jan 21 '23 at 00:35