GitHub Actions + Node JS+ Azure Web App + What a (insert expletive) Nightmare!

Jay (Vijayasimha BR)
Published in
4 min readMar 23


art by Joseph Diaz

I knew deploying node JS would be difficult. However, I did not realize, it will be this difficult. but, I got it working, so, I am awesome.

So, roughly 24 hours ago, I got two deployments working for GitHub Actions.

Obviously, I had to do finish the trifecta. Deploy a back end app.

Now, all of these are simple apps, of course. So, clearly, I will face all kind of challenges when I decided to do more. Still, if we can get a basic app, deployed, the future challenges, will be incremental rather than creational.

So, filled with hope and confidence, from yesterday’s successes, I started my journey.

How wrong I was.

as always, the final code, with the GitHub actions file, is available here.

First up, I decided to pick one of my existing, locally running, project.

I realized, I cannot just ‘lift’ and ‘deploy’ this as it is.

  1. I had to remove the env file, for it is not possible (with my current knowledge), to use multiple ports like I am doing in the locally running project.
  2. That meant, I removed the two extra servers that were running, and keeping only the ‘api’ specific server.
  3. I had make significant changes to the index.js and the related server file, to get things rolling. it’s easier if you look at the file in the linked repository.
  4. after making these changes, I had to make sure that the project is still running locally, and of course, make the necessary “||” operator usage to enable functionality after deployment.

Perhaps, the most important difference is the way ports are handled. Here is how I did in the original, local host only, project.

  constructor(hostname =process.env.LOCAL_HOST, port= process.env.DEFAULT_PORT2) {
this.serverName = 'Express Server API';
this.hostname = hostname;
this.port = port;

//Auto Start Server


this.server.listen(this.port, () => {
console.log(`${this.serverName} Started at http://${this.hostname}:${this.port}/`);

and here is the deployment version. look at the port differences.

  constructor() {
this.serverName = 'Express Server API';

//Auto Start Server


this.server.listen(process.env.PORT || 3000 , () => {
console.log(`${this.serverName} and Started at port ${process.env.PORT || 3000}`);

that created a bunch of challenges, to get this, given my limited exposure to node JS.

I also had to make some changes, from the yaml file, from react js deployment. specifically, this one.

  AZURE_WEBAPP_NAME: githubactionsnodejscodingtutorjay2   # set this to your application's name
AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root
NODE_VERSION: '18.x' # set this to the node version to use

In react, the path was different. But otherwise, since both react and this back end app, use node js, rest of the life was identical.

Now, there were some additional things I had to do, on the Azure App.

First, I had to go to the kudu console, called as ‘Advanced Tools’ in the Azure portal, and add a Web.config file!

what the!

and, the web config looks like this.

now, you see, the key part is actually this exact line.

<action type="Rewrite" url="dist/index.js"/>

It took me a while to figure this out, and in general all these steps. Eventually, I was able to get the following message from the deployed app.

ah. such a relief.

and, of course, a simple api endpoint.

oh, yeah! go, speed racer, go speed racer, go speed racer….go!!!

Phew! It should not have to be this hard, man.

I work as a full-time freelance coding tutor. Hire me at UpWork or Fiverr or Stack Overflow or GitHub. see my personal website. see my photography art hobby at Behance and Unsplash and ArtStation. Also, podcast about life. podcast about movies. and Twitch. and YouTube Channel. If you are a student, join my discord server.