Cpanel Git: Part 1 - Deploying the React App
Tags: git, github, react, laravel
Published: 2022-12-24 04:00:33

This is my first post here.

I'm going to explain how to deploy a React App on a Cpanel Shared Hosting using Git. Ensure you have git and nodejs setup.

### Scaffolding a new react app

1. You can use your preferred package manager e.g yarn, pnpm or using npx.

`pnpm create vite@latest example-react-app`

Read about vitejs at: https://vitejs.dev/guide/

2. Choose a framework 
![Selecting a framework](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nvx3hkj6ogo6zy7bgjw6.png)

3. Choose a variant
![Selecting a variant](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vselhxqsw2ufc69i50rj.png)

4. Follow the remaining prompts
![React app scaffolded successfully](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5l97t801hmnh98i8bung.png)

### Initiate a git repository
Inside our newly scaffolded react app we are going to run the following commands
`git init`
`git add .`
`git commit -m "Initial Project"`

### Creating a github repository
Head over to github.com and create a new repository. You can decide to create a private repository. For the purpose of this tutorial I will call it `cpanel-react-example`

![Creating a new github repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mrwidjbx0ujogvd1clsg.png)

### Pushing to github
Since we have already initiated our github repository we are going to push our existing one. Now inside the react app we scaffolded earlier we will follow the github commands.

![Pushing to github](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92b8tby2lr5c3mcilxn6.png)

With that done, our github repository should look like this.

![Github Repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a870xuc85so72o5zf4pm.png)

### Adding the build action
We are going to create a new file `.github/workflows/build.yml`

If you don't understand this, inside your newly scaffolded app you will need to create a folder `.github` then create a folder `workflows` inside it. Finally you will create a file `build.yml` inside the `workflows` folder.


![Base dir](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/64l4nkfbsu6gz69egkwo.png)

![Workflows](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqvq972brn8re3ge1mfi.png)

![Github Action](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x1dpgnaf87rlx5smgy0d.png)

Edit the build.yml.

```yaml
name: React App build workflow
on:
  push:
    branches:
      - main
jobs:
  build:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        node-version: [15]
    steps:
    - uses: actions/checkout@v3
    - uses: pnpm/action-setup@v2.2.4
      with:
        version: 7
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'pnpm'
    - name: Install dependencies
      run: pnpm install
    - name: Build
      run: pnpm run build
    - name: Deploy
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./dist
```

What the script does is to build our react app and deploy it to the `gh-pages` branch whenever we push to the `main` branch. You can read more about github actions at https://docs.github.com/en/actions

We will commit our changes and push to github
`git add .`
`git commit -m "Added github action"`
`git push`

Once pushed we will have a new branch called `gh-pages` containing our deploy

![Actions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/242ykcejbbed52toeuah.png)


![Branches](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v34q0qj5fvz94t18nzy0.png)


![Gh-Pages branch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgivhnalno8qiw1hsoyz.png)

### Deploying to hosting
To deploy to your shared hosting you will need two items:

1. A `.cpanel.yml` file - Read more at https://docs.cpanel.net/knowledge-base/web-services/guide-to-git-deployment/
2. Deploy keys

#### Creating .cpanel.yml
The `.cpanel.yml` file is like the github action script but for cpanel. It contains the instructions on how to deploy the react app.

Navigate to the public folder of your react-app and create three new files
`.cpanel.yml`
`.deploy.example.sh`
`.gitignore`


![Cpanel Deploy files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyy9vpndixy14xylrqy3.png)

We will edit our files using the content of this github gist: https://gist.github.com/sadiqsalau/c1b0f0e4b15e40274b64854c6c557e24


##### .cpanel.yml
This file is required for any cpanel deployment. It contains all command to deploy the react app. `.cpanel.yml` file can be destructive so make sure you take a look at it especially the parts that make use of the command `rm -rf`. Edit it to suit your deployment.

##### .deploy.example.sh
This file is an example of `.deploy.sh`. Treat it like a `.env.example` file

##### .deploy.sh
Based on the `.cpanel.yml` in that gist, this will automatically be created on your shared hosting when you run your first deployment. Treat it like a `.env` that exports variables that define the path where your react app will be deployed to on your hosting. Once created you should edit it before your next deployment.

##### .gitignore
Our `.gitignore` file will exclude `.deploy.sh` from being tracked by git.

With all three files setup, it's time to commit them. So we will run:
`git add .`
`git commit -m "Added cpanel deploy script"`
`git push`

#### Generating deploy keys
Open a new terminal and run
`ssh-keygen -t ecdsa-sha2-nistp256 -C "your_email@example.com"`
Note: Some shared hosting can't clone a repository using a key with password so when prompted to enter a password just press enter.

Also take note of where the generated keys are stored

![Generating SSH key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jlpidga1qbjqaf38r31r.png)

![SSH key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gbnsmxasooe49wx5tutu.png)


We are going to rename our keys, for this tutorial they will be renamed to `cpanel_react_example`

![Renamed keys](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/072bppwfyc33o153tmnx.png)

#### Adding github deploy keys
Now go to your github repository, navigate to `Settings > Security > Deploy Keys` and add a new deploy key. 

![Navigate to settings tab](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5zjsum2hsvhfeuwoitg1.png)

![Security section](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eu2ugyyrjt3v1s2t98i9.png)

![List of keys](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/phyxuij5znobe6hubsr4.png)

Give your key a title e.g Deploy key, for the key field copy the content of your public key (`id_ecdsa.pub` which we renamed to `cpanel_react_example.pub`). You can open the public key with a text editor or run the command `cat key_name.pub` with key_name being the name of your key.

As an example it should look like this

![Public key example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6qc13qsdg4yu7hjjkbzi.png)

![Adding new key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rw6d7k72y5qihwlo2ioj.png)

Finally add the deploy key.

![New deploy key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4or1lzncmsuwogzx0rxr.png)

#### Deploying to Cpanel

##### Login to Cpanel 
![Cpanel Login Page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/obt063hi5b9q2mhafs5f.png)

##### Navigate to file manager

![File Manager link](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nfhuw5z288zs4y0csg3s.png)

##### Creating .ssh folder

Click settings, enable hidden files and create a new folder named `.ssh` if it doesn't exist

![File Manager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txu824cm3631pvmc05b8.png)


![Settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k0q7j801xzd777ynnzzh.png)


![New .ssh folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jjxuihweq1mfu5p2jysp.png)


##### Upload deploy keys

Open `.ssh` folder and upload your deploy keys

![.ssh folder](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g714bgdllxdaopkmbl69.png)


![Uploaded deploy keys](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ba1cnfpf397tnnrifei.png)


##### Change private key permission
Right click and change the permission of your private key to 0600

![Right click private key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mcp5nh0u6cp7a0a56wez.png)

![Initial Permissions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6e1jai9vqlglmcuu4643.png)

![Unchecked permissions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gym4lq4esh7mtwp9p47n.png)


![Permission updated](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ivr7tmuyu84dwcqdsmpw.png)


##### Create .ssh config
Still within our `.ssh` folder create a new file named `config`

![New button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tlroxpagv1c13yulgmyj.png)


![Create config file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcg6sm9tp4brj57tn2wx.png)

##### Edit .ssh config

![Edit config](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xykils1hgg75ngm1efa9.png)

Edit replacing `example-1` with your github repository name and `example_1` with your ssh key name.
```
Host example-1.github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/example_1
  IdentitiesOnly yes
```

![Edit config content](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8bqrpf8bw22g1sglwp42.png)

Once done return to cpanel dashboard

![Return to cpanel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d8y3sjgdy2qtxxcv2fho.png)

##### Creating a new cpanel repository

Navigate to Git Version Control
![Cpanel Git Version Control](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tx62xbrk9vay6lrdelrf.png)


![Create a new repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6bwu5hip8erxrikkdsz.png)

The Clone URL will have this format
`git@example-repo.github.com:example-user/example-repo.git`

The other fields should be filled automatically

![Create repo part 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wx596wsyyr3svctdnxvb.png)


![Create repo part 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ul2sa96rpa3twk2x4j4n.png)


![Repo cloned](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z26lev4brfosrccqjw6b.png)

Take note of the path to your repository.

##### Switching-checked out branch
Click on the manage button
![Manage repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qacf8t05ienelnrcikf3.png)

Change the checked-out branch to `gh-pages`
![Switch checked out branch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hrtxizbhv44o7byrnapb.png)

![Switching checked-out branch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9sskr6z40l394s377nl4.png)

![Switched successfully](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xqsozgpg2v1oxpztbv9.png)

##### Running first deployment
Switch to the `Pull or Deploy` tab

![Switch to pull or deploy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6l3nklqcwkmthkaeonq.png)

Before we deploy, let's open our repository in the file manager to see its contents


![Open repo in file manager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wa1qvela6vpfmh5bakag.png)


![Repository content](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n0l0539l1ille1enxj8n.png)

If you take a look at the files listed, you should notice that there is no `.deploy.sh` which we mentioned earlier. It will be created once we run our first deployment.
Let's return to the repository and deploy


![Deploy repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7j2g3ylc3hipet5edm5.png)


![Deployed repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g4ney8duyagbu99bwbzb.png)

Once it has been deployed a new file `.deploy.sh` will be created. It should be edited if you aren't deploying to the root of your site (usually the public_html folder).


![New .deploy.sh](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2b6s694eyl8bjmmshvdk.png)

##### Running the second deployment

Now return and run deploy once more.

![Deploy once more](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/91hflf1cigr7hl4yn1xu.png)


Once deployed, navigate to the path where you specified in `.deploy.sh`, you should see the react app.


![Site Deployed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z5b8f8dlbt5bas0i4sjo.png)

Visit the url of your site to see your live app..

![Site live](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0pq7tsu2adh13rdqgljt.png)


Now whenever you make changes to your app and push to github just go to your repository, pull then deploy.

![Pull and deploy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/co9pipmzrlqzp1g098du.png)

A working example can be found at: https://github.com/sadiqsalau/cpanel-react-example

The next part is using laravel as the API..