# Simple setup for deploying a Vue or React frontend  to CPanel-based hosting

So I have several little tools, or apps that I create for convenience and most of them tend to be Single Page applications written with either Vue or React. Sometimes I will make a backend for them and others don't require it. Either way, I sometimes decide to host the front end on a CPanel-based hosting and the back end on a VPS or cloud service somewhere else. As a result, I often have to find a way of "deploying" these applications to CPanel which means uploading the built files via FTP. I have several toy projects and so it became boring to have to upload files via some FTP client, so in this article, I will document one way I have found to ease the drudgery.

It relies on NodeJS, which is typically okay for my project since am most likely using something like Vue or React with Node/npm build system anyways. We only need one extra devDependency: **ftpdeploy**

```bash
$ npm install --save-dev ftp-deploy
```

Once we have that installed, we can now add the config file for it in `ftpdeploy.js` which can be setup like below, obviously you would change according to your site details.

```javascript
import FtpDeploy from "ftp-deploy";
import { cwd } from 'node:process';
import { join } from 'node:path';
const ftpDeploy = new FtpDeploy();

const config = {
    user: "mycpaneluser",
    // Password optional, prompted if none given
    password: null,
    host: "ftp.example.com",
    port: 21,
    localRoot: join(cwd(), "./dist"),
    remoteRoot: "/someapp.example.com/",
    // include: ["*", "**/*"],      // this would upload everything except dot files
    include: ["*", "dist/*", ".*"],
    // e.g. exclude sourcemaps, and ALL files in node_modules (including dot files)
    exclude: [
        // "dist/**/*.map",
        "node_modules/**",
        "node_modules/**/.*",
        ".git/**"
    ],
    // delete ALL existing files at destination before uploading, if true
    deleteRemote: false,
    // Passive mode is forced (EPSV command is not sent)
    forcePasv: true,
    // use sftp or ftp
    sftp: false,
};

ftpDeploy
    .deploy(config)
    .then((res) => console.log("finished:", res))
    .catch((err) => console.log(err));
```

This script can then be run using NodeJS via `node ftpdeploy.js`Or you can add that to your package.json under scripts, something like:

```json
  "scripts": {
    ...
    "deploy": "npm run build && node ftpdeploy.js"
  },
```

Which makes deploying or pushing updates as simple as

```bash
$ npm run deploy
```

That's it, I guess ideally, one should have a nice CI/CD process and better tooling for deploying *real-world* projects but this setup serves me well for some small toy projects, especially on utilizing my CPanel hosting plan.

### Notes

* I recommend trying GitHub actions for a CI/CD process that can deploy sites when you push a tag/release.
    
* My friend, Walter, reminded me that we had agreed to atleast publish one post - this post probably wasn't going to get published if it wasn't for his reminder. Checkout his blog [https://ntumbuka.me/](https://ntumbuka.me/)
