Creating and Deploying a Node Server

 

Today we’ll use VSC to create a simple node server that uses express, test it with a browser, create a GitHub repository for our code, and deploy it to Azure.  This node app will eventually become our API server.

Set Up the Project Directory

Open in Visual Studio Code (VSC) to the api-server directory we created in the last tutorial .  Then create a subdirectory named src inside your api-server directory to hold the source code for our node application.  There are many ways to create subdirectories in VSC.  One way is to click on the directory (in the Explorer pane) in which you want to create a subdirectory.  This should reveal an icon to create a new Folder (i.e. directory).  If you click on the new Folder icon a text box is revealed in which you can enter the name of the new directory.

Initialize npm

Open up the terminal in VSC and verify that your working directory is the api-server directory using the pwd command.

$ pwd

We need to set up an npm package.json file for our node application.  To do so, run the following command in the VSC terminal.  When you do, you will be prompted with a series of questions.  You can press enter for each to choose the default values.  Before entering yes when asked Is this OK? notice that the value for the main property is index.js.  This is the name of the file that will be executed first when your app runs.  We will change this later.

$ npm init

You can view documentation for all of the npm commands (including init) at https://docs.npmjs.com/cli/v8/commands/.

In the future, to avoid having to press enter for each of the default values, you can simply run the following command to bypass all of the prompts.

$ npm init -y

When you ran npm init, it created a file named package.json.  Open the file and view it’s contents.  This file contains information needed by the node runtime to run the app.

Install npm Packages

The npm packages are publicly available libraries of code that we can install in our project and import and and use in our apps. You can find information about all npm packages at https://www.npmjs.com.

The npm install (or npm i) command downloads and installs into our project a package and any packages that it depends on.

The first two packages that we are going to install are nodemon and express.  Run the following commands from the VSC terminal to install the nodemon and express packages into your project.

$ npm i nodemon --save-dev
$ npm i express
$ npm i cors

After you’ve run the commands you should notice that a new subdirectory named node_modules was created in your project. If you expand this subdirectory you will see that the nodemon and express packages were installed in it.  What are all of the other packages?  They are the packages that are dependencies of nodemon and express.  They were installed automatically when nodemon and express were installed.  Open up a few and explore their code.

Per the npm website, “nodemon is a tool that helps develop node.js based applications by automatically restarting the node application when file changes in the directory are detected.”

The –save-dev flag specifies that the package should only be installed when the project is under development or testing, but not when installed on a live environment, like Azure.

Express is a framework that provides a set of features that make developing web applications quick and easy.  You can view the documentation including guides and their API reference at http://expressjs.com.

The cors module allows the API server to allow requests from any location.  This will be useful later on when we make requests from our separate client app.

If you reopen up package.json you should see two new property; one named devDependencies and another named dependencies.  These properties contain the packages that our app is now dependent on.  When we push our code to Azure and Azure installs our application on their servers, the express package will be installed, but the nodemon package will not since it is a development dependency.

Create an Initial API Server Application

Let’s write some code.  In the src subdirectory, create a file named app.js and add the following code (minus the comments if you want) to it.  Don’t forget to save the file after editing.

const express = require('express')
const cors = require('cors')
const app = express()

// Configure express to allow requests from anywhere "*"
app.use(cors()) 
app.use(function (req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
    next(); 
}); 

// Configure express to read JSON objects in the body of requests.
app.use(express.json())

// Set up a default route ('') and return 'Hello World!' in the 
// response when requests are received
app.get('', (req, res) => {
    res.send('Hello World!')
})

// Set port to the PORT environment variable (if it is defined), 
// otherwise set it to 3000 
const port = process.env.PORT || 3000

// Configure the server to listen for connections on the port. 
// Print to the console when ready for connections
app.listen(port, () => {
    console.log('Server is up on port ' + port)
})

Modify the package.json File

Since our main program is in src/app.js rather than index.js, we need to modify the entry point to our web app in package.json.  Modify the main property so that it reads as follows.

 "main": "src/app.js",

Notice the scripts property in package.json.  We want to create two new scripts.  One named start that will run app.js using node, and one named dev that will run app.js using nodemon.

Modify the scripts property so that it reads as follows:

...
"scripts": {
  "start": "node src/app.js",
  "dev": "nodemon src/app.js"
},
...

Test the Node.js App

Start up your node server in the terminal using the command specified in the start script (shown below).  You should see Server is up on port 3000 printed to the terminal.

$ node ./src/app.js

Now open a browser and navigate the browser to http://localhost:3000.  You should see Hello World! in the browser.

Localhost is a reserved hostname which refers to the same computer making the request.  Since your browser is running on your laptop, localhost refers to your laptop.

Since your node application is running on your laptop and listening to port 3000, when the browser connects to port 3000 with the request, your app responded by sending the browser a response containing the text Hello World!

You can stop the node server by pressing CTRL + c in the terminal.

Now restart the node server by running the npm script named dev using the following command in the terminal.  This is the command we’ll use to start the node server when developing it.

$ npm run dev

Verify that the app is running using your browser.

Now change app.js so that the app sends the client some other text other than Hello World and save the file.

Notice that nodemon automatically restarted node.  Refresh browser to verify that the app is now sending the new text.

When you’re finished experimenting, shut down the node server using CTRL + c.

Create a Git Repository

Let’s create a git repository for our app. In the terminal, change the working directory to the project’s api-server directory (if not already there).  Recall we can view the working directory using the pwd command, and change the working directory using the cd command.

Now initialize a git repository by issuing the following command in the terminal.

$ git init

We don’t want git to track the files in the node_modules directory.  To do so, create a new file named .gitignore in the project’s api-server directory.

Inside .gitignore add the following line so that the node modules are not copied to the repo.

node_modules/

We can verify that this directory is not tracked by running the following command and noticing that node_modules/ is not listed.

$ git status

We can now add all of the tracked files and directories to the git staging area using the following command.

$ git add .

Next we want to commit the changes to the staged files using the command below.

$ git commit -m "initial commit"

Push Code to GitHub

Now on GitHub, create a new repository for the node server’s code.

After you’ve created a repository, you should see a box on the webpage that reads Quick setup — if you’ve done this kind of thing before. In that box press, press the SSH button. This changes the commands need to push code to GitHub using SSH key authentication.

Scroll down on the webpage to see three commands listed under …or push an existing repository from the command line.  Issue these commands from the terminal.

If you refresh your GitHub page, you should see your app’s code.

Create an Azure Web App

Open up the Azure portal (portal.azure.com) in a browser.  Under Azure services click on the arrow labeled More services. Scroll down to Web & Mobile and select App Services.  Next press the Create dropdown and choose Web App.

This screen should seem familiar as it is similar to the screen we saw when creating the static web app.  Fill out the form so that it is similar to the following.

  • Name: (something unique but that implies its your api server)
  • Publish: Code
  • Runtime stack: Node 20 LTS
  • Operating System: Linux
  • Region: East US 2
  • Linux Plan (East US): (keep default value)
  • Pricing plan: Free F1 (Shared infrastructure)

Then click the blue button labelled Review + create.  After it is done validating, press the blue button labelled Create.  When your deployment is complete, click the blue button labelled Go to resource.

On the resource page, once its fully loaded, choose Configuration in the menu on the left-hand side of the page.  Near the top, choose the General settings tab.  Toggle Basic Auth Publishing Credentials to On.  If it is already On, toggle it Off, and then back On.  Then press Save at the top of the page.

Choose Deployment Center in the menu on the left-hand side of the page.  On the Deployment Center page, choose GitHub in the Source dropdown menu.  Then select the appropriate Organization, Repository, and Branch.  Under Authentication settings select Basic authentication.  When done, click Save.

At this point, the GitHub workflow should run.  You can check the status of the action workflow on GitHub to see if it completed successfully.  You can also view the Azure Deployment Center logs to see the status of the workflow.

When the workflow is done running, click Overview on the left-hand side of the Azure portal page.  Copy the “Default domain” into the browser’s URL field and press enter.  You should see the response text from your node server.

If so, please email the default domain to your instructor.

Update Your Local Repo

Since Azure wrote the .yaml file to your repo, don’t forget to run git pull in VSC before your next push.

Test the Auto-deployment

In VSC, make a change to the string returned in your server’s response and push the code to GitHub.  View the action workflow and when finished, open your browser to the server’s default domain (provided by Azure).  You should see the new text displayed in the browser.

 

© 2024, Eric McGregor. All rights reserved. Unauthorized use, distribution and/or duplication of this material without express and written permission from the author is strictly prohibited.