Search code examples
node.jsreactjsnginxaxiosvps

Backend and frontend won't communicate after deployment on VPS nginx server


I'm deploying my first Node.js / React / MySQL app. I decided to deploy it on a VPS server from Hostinger (first time I'm using a VPS). I followed some tutorials to set up the server with Nginx. I cloned my repo, build the front and now both front and back are online, but they won't communicate together (every request from client to server returns a 404 error.)

In development everything was working fine. I use Axios to make fetch requests. They were communicating through a proxy ("proxy": "http://localhost:4000" in package.json of frontend. I removed this line in production)

My Nginx config for backend:

server {
        server_name api.mywebsite.com www.api.mywebsite.com;

        location / {
        proxy_pass http://127.0.0.1:4000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        }
}

and for frontend:

server {
        listen 80;
        listen [::]:80;

        root /var/www/mywebsite/frontend/build;
        index index.html index.htm;

        server_name shop.mywebsite.com www.shop.foryoumaquillage.fr;

        location / {
                try_files $uri $uri/ =404;
        }
}

Those config are in different files, in /etc/nginx/sites-available folders with links to /etc/nginx/sites-enabled/ folder. I tried to put the config in a unique file but it didn't work.

For info here is my frontend package.json:

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@paypal/react-paypal-js": "^8.1.1",
    "@redux-devtools/extension": "^3.2.5",
    "@reduxjs/toolkit": "^1.9.5",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "ag-grid-community": "^30.0.3",
    "ag-grid-react": "^30.0.4",
    "axios": "^1.4.0",
    "bootstrap": "^5.2.3",
    "bootstrap-icons": "^1.10.5",
    "react": "^18.2.0",
    "react-bootstrap": "^2.7.4",
    "react-dom": "^18.2.0",
    "react-helmet-async": "^1.3.0",
    "react-image-gallery": "^1.2.11",
    "react-multi-carousel": "^2.8.4",
    "react-redux": "^8.1.1",
    "react-router-bootstrap": "^0.26.2",
    "react-router-dom": "^6.11.1",
    "react-select": "^5.7.3",
    "react-simple-star-rating": "^5.1.7",
    "recharts": "^2.6.2",
    "rsuite": "^5.33.1",
    "web-vitals": "^2.1.4"
  },
  "devDependencies": {
    "react-scripts": "5.0.1"
  },
  "scripts": {
    "start": "set PORT=3005 && react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

and package.json for backend:

{
  "name": "backend",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "server-prod": "node server.js",
    "server-dev": "npx nodemon server.js",
    "client": "npm start --prefix ../frontend",
    "dev": "concurrently --kill-others-on-fail \"npm run server-dev\" \"npm run client\""
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bcryptjs": "^2.4.3",
    "cookie-parser": "^1.4.6",
    "cors": "^2.8.5",
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "express-fileupload": "^1.4.0",
    "express-rate-limit": "^6.8.1",
    "helmet": "^7.0.0",
    "jsonwebtoken": "^9.0.0",
    "mysql2": "^3.3.3",
    "node-fetch": "^2.6.12",
    "uuid": "^9.0.0"
  },
  "devDependencies": {
    "concurrently": "^8.2.0",
    "nodemon": "^2.0.22"
  }
}

What I tried:

I tried to change Axios configuration using the following:

import axios from 'axios';

export const AxiosRequest = axios.create({
  baseURL: process.env.API_URL,
});

and I use AxiosRequest for all my fetch requests (API_URL=http://127.0.0.1:4000)

I installed cors (which I didn't use in development) to try to fix my problem but it didn't work. For now it allows requests from everywhere. app.use(cors())

I tried to change Nginx config following old Stackoverflow solutions (for example make my backend listen to 3005) but nothing work (usually the changes I tried just make my api unaccessible...).

As said it's the first time I'm deploying a "complex" app like this one, and first time I'm using a vps / nginx. So I might have made a rookie mistake either in my code or setting up my Nginx server

edit

Precisions on how I deploy my app: I bought a domaine name via hostinger and created 2 DNS records: both are type A, point to the same ip address and with TTL 14400. One is named api.mywebsite.com, and the other one is shop.mywebsite.com (the name is the only difference).

On my server, in directory /var/www/ I created a new directory for the app, and inside it I have the backend directory and the frontend one.


Solution

  • I'm not sure what was wrong but I decided to delete my repo and server config files, and redo everything.

    I chose this time to build the frontend, move the file to the backend directory, and only run my backend, by modifying app.use(express.static(...)) function in the server.js file.

    For now, my config file is very simple, and might need some improvement:

    server {
            listen 80 default_server;
            listen [::]:80 default_server;
    
            index index.html;
    
            server_name mywebsite.com www.mywebsite.com;
    
            location / {
                    proxy_pass http://127.0.0.1:4000;
                    proxy_http_version 1.1;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection 'upgrade';
                    proxy_set_header Host $host;
                    proxy_cache_bypass $http_upgrade;
            }
    }
    

    And I changed my DNS settings.

    Now everything seems to work properly.