Build your own React CI in 5 minutes!
Tags: tutorial, devops, react, nginx
Published: 2021-05-07 23:11:22

Hey everyone! This post is part of *Introduction to StewardX* series.

In this tutorial, I'll show you how can you build your own CI, super easy.

All you need is:
- [StewardX](https://github.com/gokayokyay/stewardx)
- A Linux server (preferably with sudo access)
- Docker
- NodeJS - for building React of course 😊

My server's OS is Debian flavored (Ubuntu) but you should be able to find the installation commands of the packages for your own distribution just by a quick search, if not please leave a comment so I can help you. Okay here we go!

## Install Nginx
Pretty straightforward. Just run the command below if Nginx is not installed on your server:
```shell
$ sudo apt update
$ sudo apt install nginx
```
Now you should be able to access your server via http, just navigate to

`http://yourserverip`

And you'll be presented Nginx's default welcome page. If not, you please check if your ports are not blocked and nginx is installed correctly. You can follow the [amazing tutorial by DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-20-04) to configure ports for nginx.

**Note:** I'm not affiliated with DO in any manners, I just like their tutorials.

Once you got Nginx working proceed to the next step:

## Configuring Nginx to serve your React app

Now, for more detailed explanation you can follow [this tutorial on DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-react-application-with-nginx-on-ubuntu-20-04). But I'll be demonstrating how you can configure it here too.

To keep it simple and fast, I won't be demonstrating the server blocks but in production you should use them! For now, I'm just going to use the default one.

Open `/etc/nginx/sites-enabled/default` with your favorite editor.
```shell
$ sudo nano /etc/nginx/sites-enabled/default
```

If you scroll down, you'll see this specific line:
```shell
root /var/www/html;
```

Okay this line means that Nginx will serve the files it found in that specific directory. So we'll move our built files there. If you want, you can change the directory I won't be changing it for this tutorial. Moving on!

## Building our React app

I'll be using the [documentation repository of StewardX](https://github.com/gokayokyay/stewardx-docs) for demonstration purposes. It's a React app too 😊
```shell
$ cd
$ git clone https://github.com/gokayokyay/stewardx-docs
$ cd stewardx-docs
$ npm install # or yarn
```

Okay now I can build my app
```shell
$ npm run build # or yarn build
```

You'll see a `build` folder has been created. Great!

## Installing and Running StewardX

Head over to [releases page of StewardX](https://github.com/gokayokyay/stewardx/releases/latest) and download the latest binary, it'll have a name like: `stewardx_${version}_${os}_${arch}`. At the time of writing, the latest binary is named: `stewardx_v0.1.2_linux_x64`. I suggest that you download it to a directory. I'll be creating a new one:

```shell
$ cd
$ mkdir stewardx
$ cd stewardx
$ wget https://github.com/gokayokyay/stewardx/releases/download/v0.1.2/stewardx_v0.1.2_linux_x64 -O stewardx
$ chmod +x stewardx
```

Since it's not even in beta, you might have to build it from source, to do it please follow this link: [Building it from source](https://stewardx.dev/getting-started#building-it-from-source).

Now, you'll need to have a PostgreSQL instance running to start StewardX. You can get a free one or start your own by running:
```shell
docker run --rm -P -p 127.0.0.1:5432:5432 -v "$HOME/postgres-data:/var/lib/postgresql/data" -e POSTGRES_PASSWORD="1234" --name pg postgres:alpine
```

**NOTE:** DON'T USE THIS COMMAND FOR PRODUCTION, PLEASE! IT'S PASSWORD IS 1234 😭

You'll need your database URL. If you run the command above, then it is:
```shell
postgresql://postgres:1234@localhost:5432/postgres
```

Now run this command while you're still at the same directory with `stewardx`.
```shell
STEWARDX_DATABASE_URL=postgresql://postgres:1234@localhost:5432/postgres ./stewardx
```

If you see no output, then it means it's working! 😊

## Creating the build script

I'll create a new a directory for the script
```shell
$ cd
$ mkdir ci-scripts
$ cd ci-scripts
$ touch react-ci.sh
$ chmod +x react-ci.sh
```

Now open the script with your favorite editor and paste the following:
```shell
#!/bin/bash
PROJECT_DIR_NAME=stewardx-docs
PROJECT_GIT_URL=https://github.com/gokayokyay/stewardx-docs
PROJECT_PARENT=$HOME/
DEPLOY_DIR=/var/www/html/
```

We've just defined the variables here, moving on:
```sh
...
cd $PROJECT_PARENT
if [ -d "$PROJECT_PARENT/$PROJECT_DIR_NAME" ] 
then
    echo "Directory ${PROJECT_DIR_NAME} exists. Skipping git clone..." 
    cd $PROJECT_DIR_NAME
    git stash
    git pull
else
    echo "Directory ${PROJECT_DIR_NAME} doesn't exists, cloning it..."
    git clone $PROJECT_GIT_URL
    cd $PROJECT_DIR_NAME
fi
```

We pull the latest changes if available. Time to build it
```sh
...
echo "Cleaning node_modules for a fresh start!"
rm -rf node_modules
echo "Installing the modules..."
npm install
```

Documentation repository don't have any tests, so I'm skipping test command:
```sh
...
echo "Now building it, this can take a while"
npm run build
echo "Cleaning old files in serve directory"
rm -rf $DEPLOY_DIR/*
echo "Okay, now moving the artifacts into the serve directory."
mv build/* $DEPLOY_DIR
echo "Done."
```

And save it.

Issue this command:
```sh
$ pwd
```
and save it's output for the next step.

Now to test our script, just run
```sh
./react-ci.sh
```

Go check your website `http://yourserverip` if it works, now it's time to

## Create a webhook

Get the output of `pwd` command from previous step. To add a webhook to StewardX we can either use it's [panel](https://stewardx.dev/panel) (needs to be built) or just send a request to it by any web client, I'll be using curl:
```sh
curl --header "Content-Type: application/json" -X POST --data '{"task_name": "React app CI", "frequency": "Hook", "task_type": "CmdTask", "task_props": {"command":"/bin/bash #pwd_output#"}}' http://localhost:3000/tasks
```

Change **#pwd_output#** with the output you saved from previous step mine was: `/root/ci-scripts/react-ci.sh` (yup used root, I like danger)

This command will output an id, save it for the last step:

## Using the webhook from GitHub

Now, it is time to add the webhook to the GitHub. Navigate to your project's repository, and click settings.

Navigate to `Webhooks` section from the left panel. Click `Add webhook` button found on the top of the page. When the page opens up, you'll want to fill the `Payload URL` with `yourserversurl:STEWARDX_PORT/execute/id_of_your_task`, so it'll look something like `http://mydomain.com:3000/execute/c99ff533-d3c2-4ee3-9b8f-a972a9db00db`.

And congratulations! You've created your own CI!

For more information and documentation of StewardX, please visit [https://stewardx.dev](https://stewardx.dev).

I really appreciate if you leave a feedback 😊 Stay safe!