DEV Community

Bradley Ashton
Bradley Ashton

Posted on

Blog: Hosting fullstack apps on CentOS VPS

// This is an ongoing blog and will be updated regularly

My goal is to host projects on my own CentOS VPS hosted on DigitalOcean. During my learning i was always recommended to use services from Heroku, Netlify and Render to host my backend and GitHub Pages for my frontend - i never liked splitting my apps.
I think i heard Next.js can resolve this with serverless options?

I also wanted to easily edit my projects without the hassle of npm run build and uploading. I'd thought of FTP/SSH extensions for VSCode but there must be a better way?

This is my journey...


Server Installations

I installed Node Version Manager (NVM) to my server for Node and NPM. I updated the bash commands and checked the versions to ensure they were installed correctly.

# curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
# source ~/.bashrc
# node --version
~ v14.15.4
# npm --version
~ 6.14.4
Enter fullscreen mode Exit fullscreen mode

I needed my apps to stay live when terminal was closed so i globally installed the **daemon process manager 'PM2' **and again checked the version to ensure they were installed correctly. This manager will run the dev environment on the live server without needing to create a build package.

# npm i -g pm2
# pm2 --version
~ 5.3.0
Enter fullscreen mode Exit fullscreen mode

Firstly i created a subdomain (forecast.literecords.com) so my app would have it's own address. Using the Git Version Control plugin within my cPanel (v110) i created a repo and pointed the directory to the subdomain so edits go live as easily as possible.

# git remote add <local-name> <cpanel-repo-url>

# git remote add cpanel ssh://root@literecords.com/home/litereco/public_html/forecast.literecords.com
# git push -u cpanel main
Enter fullscreen mode Exit fullscreen mode

My project is already remotely connected to a GitHub repo so i added my cPanel repo as a second remote (not 'origin').

The original ssh user received 'Permission Denied" errors so i changed the user to 'root' which worked. Later i found a solution to the permissions by changing ownership of the directory to the user 'litereco'.

# chown -R litereco. /home/litereco/.ssh
Enter fullscreen mode Exit fullscreen mode

This project is build using React-Vite so i set the server port and allowed host in 'vite.config.js', this can be done in command line when starting the service too.

export default defineConfig({
  plugins: [react()],
  server: {
    port: 4444,
    host: true,
  },
});
Enter fullscreen mode Exit fullscreen mode

Problem

I originally thought there was a problem with permissions on my server but i now think it's something else. While the initial upstream set works, further push attempts show an error.

! [remote rejected] main -> main (Working directory has unstaged changes)
error: failed to push some refs to 'ssh://literecords.com/home/litereco/public_html/forecast.literecords.com'
.

I tested replacing files through SFTP and the changes are instantly live so i see no reason why # git push wouldn't do the same once my remote GIT issue is resolved.


Starting Services

To run the process with PM2 i SSH connected to my server and navigated to the subdomain directory where the app is located. I then started the service with npm run dev and gave it a name.

# cd home/litereco/public_html/forecast.literecords.com
# pm2 start "npm run dev" --name "Forecast App"
Enter fullscreen mode Exit fullscreen mode

Nginx

Right now this runs from any part of the parent domain so long as it includes the port :4444 so installed Nginx and configured it to listen on port :4567 because :4444 was already in use and direct the default to my app location.
/etc/nginx/nginx.config

server {
        listen       4567;
        listen       [::]:4567;
        server_name  forecast.literecords.com;
        root         /home/litereco/public_html/forecast.literecords.com;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
Enter fullscreen mode Exit fullscreen mode

I created my proxy file in /etc/nginx/sites-available/forecast.literecords.com

server {
    server_name  forecast.literecords.com;
    index index.html index.htm;
    access_log /var/log/nginx/nodeapp.log;
    error_log  /var/log/nginx/nodeapp-error.log error;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://165.232.78.74:4444;
        proxy_redirect off;
    }
}
Enter fullscreen mode Exit fullscreen mode

Tested the NGinx config.

# nginx -t
~ nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
~ nginx: configuration file /etc/nginx/nginx.conf test is successful
Enter fullscreen mode Exit fullscreen mode

Restarted Nginx service.
# sudo systemctl restart nginx.service

Navigated to forecast.literecords.com, blank page!

Top comments (0)