Search code examples
node.jsweb-deployment

What's the simplest way to deploy a node app on linux mint?


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

Solution

  • [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>