Free ExpressJS + React + Azure hosting
Yes, you can host a fullstack application on Azure for realistically $0.00. This article will show you how.
Requirements:
- Github account
- Azure account
Step 1: Setup Azure
Head over to Azure Portal create an account. You’ll want to do the following:
- Create a “Pay-as-you-Go” subscription.
- Create a Resource Group under your “Pay-as-you-Go” subscription.
- Create a Web App instance.
I recommend you use the same NodeJS version you have on your local machine to reduce the chances of running into bullshit.
Also make sure you select 1GB Free Developer Tier. Its not set to default, and you will pay money you didn’t have to if you don’t pay attention.
Step 2: Setup a Github repository / Project Structure
- Create new repo
- Clone to your machine
git clone <my-repo-url>
- Navigate to where the repo was cloned, and use
npx create-react-app client
- Navigate to where the repo was cloned, and use
- Create a
By this point your project structure should look like this:
/
server/
client/
public/
src/
node_modules/
package.json
package-lock.json
README.md
.gitignore
root = your project name
Inside your client/
directory is where your React application will go. Now, setup the Express server which will serve the React application.
- Setup your Express server using
npm init
- Install any dependencies you plan on using ex:
npm install --save express
- For now, this is all you need in your entry-point (by default, entry-point is called index.js):
const express = require("express");
const path = require("path");
const app = new express();
var port = process.env.PORT || 3000;
app.set("PORT", port);
app.use(express.static("./client/build"));
const entryPoint = path.resolve(__dirname, "client", "build", "index.html");
app.get("*", (req, res) =>
{
res.sendFile(path.resolve( entryPoint ));
});
app.listen(port, () => console.log("listen on this port: " + port));
The important bit is that your Express server needs to serve the build files of your React application.
For organization sake (and if you wish to add API testing), create a file named start.js
and add the following:
const app = require('./server/index.js');
app.listen(process.env.PORT || 8080, () => console.log(`Listening on port ${process.env.PORT || 8080}!`));
Now create a sub directory /server
, and create your index.js
file which is imported in start.js
This is the boilerplate code for your index.js
file:
const express = require("express");
const path = require("path");
const app = express();
app.use(express.json())
app.use(express.urlencoded({ extended: true}));
// Example local API route
// Express routes MUST go before React build route
// app.use("/api/ping", ping);
app.use(express.static( path.resolve(__dirname, "../", "client", "build" ) ));
const entryPoint = path.resolve(__dirname, "../", "client", "build", "index.html");
app.get("*", (req, res) =>
{
res.sendFile(path.resolve( entryPoint ));
});
module.exports = app;
From here, you can add anything related to the server. Remember, other Express routes MUST go before the React build route. Otherwise, the React route will override them all.
- Add, commit, and push your changes to the repo.
Step 3: Setup Auto-deployments
- In the Azure Portal, head over to your Web App resource, and click on Deployment > Deployment Center located on the left side-menu.
- Select Github. Azure is going to request access to your Github account, and (selected) repo. Concent to all.
- Azure will generate a .yml file, then it will add, commit, and push it to your repo in
.github/workflows
directory.
At this point, when you push your local changes to your master branch, Github Actions will update the repo, build, test, and deploy to your Azure Web App.
Take note of that .yml file:
- name: npm install, build, and test
run: |
npm install
npm run build --if-present
npm run test --if-present
Its only executing these commands on our root directory, not inside our client/
directory. This means our application will fail because Azure has not installed the React dependecies, and the React app is also not being built.
If your React application builds successfully, but Express serves a blank page, edit package.json
with the following line:
"homepage": ".",
Now, if you plan on having the server do some back-end work (an API), then you will want to setup a proxy by adding the following line to the React package.json
file:
"proxy": "http://localhost:8080",
- We want to: navigate to
./client
sub directory, install dependencies, and build my React application. So, add this to your/package.json
scripts (not to be confused with/client/package.json
!)
"build": "cd ./client && npm install && npm run build"
Using the .yml file, Github Actions will give the instruction to Azure Web App to get our dependencies, and build our application.
npm install
Installs the dependencies in the root directory (the Express server).
npm run build --if-present
Is calling the script: cd ./client && npm install && npm run build
which installs the dependencies in the client/
directory (the React app), then builds it.
Comment questions, or if something doesn’t work. Thanks for reading!