Starting an ExpressJS App

    Over the past few months I've found myself spinning up tons of new servers and walking through the process of pushing express apps live.

    Because this process always comes at unexpected times, I've never bothered documenting the steps it takes to get a blank box running express. Surprisingly it seems as though few have bothered to walk through every step involved in a single place, and most express tutorials contain outdated information which likely leads to headaches for newcomers.

    I'll be walking through an ExpressJS setup with the tech I always opt for.

    Stack

    • NodeJS
    • NPM
    • Nginx
    • Express
    • Express-Generator
    • Sass
    • Handlebars
    • PM2
    • Grunt

    Installation

    Prep your server by installing the latest updates:

    $ apt-get update
    $ apt-get upgrade -y
    

    NodeJS

    Of the things we'll be installing prior to development, NodeJS is the trickiest. Unlike other packages, we cannot simply use Ubuntu's apt-get install command for Node. NodeJS for Linux distributions is best installed via NodeSource, which is handled as such:

    $ apt update
    $ apt upgrade -y
    $ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
    $ sudo apt-get install -y nodejs
    $ sudo apt-get install gcc g++ make
    $ sudo npm install -g [email protected]
    

    Note that this also hooks us up with the latest version of NPM, so we're all good on that front.

    Nginx

    Let's install Nginx before we forget. We'll come back to Nginx later to set up the config.

    apt-get install nginx
    

    Express

    We'll install express globally. This way we can support multiple apps running express, as well as use an express generator to easily create more projects down the line.

    npm install -g express
    

    Express generator

    Install express generator globally. Express generator is the easiest way to set up a new express app with the standard structure preconfigured.

    npm install -g express-generator
    

    Create an App

    Now we get to the fun stuff.

    $ cd to the directory you'll be using to contain your apps, such as /home or /var/www. When we use express-generator in this directory, we'll be initializing a new express project will most of the common boilerplate setup preconfigured.

    This will create your Express app inside /home/myapp:

    cd /home
    
    express --view=hbs --css=less myapp
    

    Express-generator prompts you to pass arguments to automatically configure your project for you. We're able to specify which CSS preprocessor and templating system we prefer this way. I'm going to create a project using Handlebars and Sass as my weapons of choice.

    These are the options that come with express-generator in case you'd like to customize your installation:

    $ express -h
    
      Usage: express [options] [dir]
    
      Options:
    
        -h, --help          output usage information
            --version       output the version number
        -e, --ejs           add ejs engine support
            --hbs           add handlebars engine support
            --pug           add pug engine support
        -H, --hogan         add hogan.js engine support
        -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
        -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
            --git           add .gitignore
        -f, --force         force on non-empty directory
    

    Warning: common bug ahead

    If your life sucks, running express generator may have given you this error:

    /usr/bin/env: ‘node’: No such file or directory
    

    This is an issue with Debian distributions of linux which treat 'node' and 'nodejs' as separate filepaths. To alleviate this, create the following symbolic link:

    ln -s /usr/bin/nodejs /usr/bin/node
    

    Start App

    Inside your project directory run npm install to install all dependancies for your project. This will look at the package.json file that express-generator created and will install the corresponding node modules.

    cd myapp
    
    npm install
    

    Here's the result:

    .
    ├── app.js
    ├── bin
    │   └── www
    ├── package.json
    ├── public
    │   ├── images
    │   ├── javascripts
    │   └── stylesheets
    │       └── style.css
    ├── routes
    │   ├── index.js
    │   └── users.js
    └── views
        ├── error.pug
        ├── index.pug
        └── layout.pug
    
    7 directories, 9 files
    

    Set up Nginx Config

    Before creating your Nginx config, it is best to verify which port express will be running on. In most recent versions of express, this can be found in the www file. The path to this looks like myapp/bin/www.

    Check out that file and see what the value is for var port.

    vim bin/www
    

    You should see something like this:

    var port = normalizePort(process.env.PORT || '3000');
    

    Thus, the port is 3000. Remember this.

    Previously this information was stored in Express's app.js file.

    Now, create a Nginx config in sites-available:

    vim /etc/nginx/sites-available/myapp
    

    For a basic reverse proxy server configuration, use the configuration below.

    Be sure to replace the port with the port you found earlier.

    server {
        listen 80;
    
        server_name example.com www.example.com;
    
        location / {
            proxy_pass http://127.0.0.1:3000; #Replace port here
            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;
        }
    
        location ~ /.well-known {
            allow all;
        }
    
        client_max_body_size 50m;
    }
    

    Save this out. Now create a symbolic link to have this appear in sites enabled, and restart Nginx.

    ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp 
    
    service nginx restart
    

    Run your app

    Now your web server is pointing to the correct place, but your app isn't actually running. To keep your app running continuously, we'll use PM2.

    Install pm2 globally:

    npm install pm2 -g
    

    Go to your app's directory, and start your app using PM2:

    cd /home/myapp
    
    pm2 start bin/www
    

    If successful, PM2 should then list your app as running.

    You can run as many express apps on one server as you like:

    ┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
    │ App name │ id │ mode │ pid   │ status │ restart │ uptime │ cpu │ mem       │ user │ watching │
    ├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
    │ www      │ 0  │ fork │ 8953  │ online │ 79      │ 35h    │ 0%  │ 44.6 MB   │ root │ disabled │
    │ www      │ 1  │ fork │ 18195 │ online │ 0       │ 3D     │ 0%  │ 22.3 MB   │ root │ disabled │
    │ www      │ 2  │ fork │ 19990 │ online │ 0       │ 33h    │ 0%  │ 49.2 MB   │ root │ disabled │
    └──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
    

    Your app should now be accessible via your domain.

    Final items

    Your app is up and running, but you're not in the clear yet. To have things fully configured, you'll need to set up grunt or gulp to compress your source for production.

    Configuring gulp files is a tutorial in its own right. Otherwise, you're good to go to serve static files directly out of the /public folder.

    Todd Birchard's' avatar
    Todd Birchard
    New York City Website
    Engineer with an ongoing identity crisis. Breaks everything before learning best practices. Completely normal and emotionally stable.
    Todd Birchard's' avatar
    Todd Birchard

    Engineer with an ongoing identity crisis. Breaks everything before learning best practices. Completely normal and emotionally stable.