Question

404 GET Requests turns into 502 Gateway Errors? NGINX or other issues?

Hey guys,

I have been having issues with my MERN project lately.One is that I keep getting 404 errors and the other is now I see a 502 Error when I visit my DO IP address.

Today I was making changes to my signup and login code. I noticed that I would get 404 errors when trying to test it out and I would also get the same errors in POSTMAN.

I decided to visit my Explore page and would get a GET request 404 error. Which was strange because this wasn’t happening yesterday.

Then in POSTMAN I did a GET request to /api/blog/posts and to api/users/users and I didn’t get a list of posts or users. Instead I saw the index.html from React.

I went to my DO IP address and would see the same 404 error in my Explore page.I then got rid of all of my changes for the day and that didn’t help.

After a couple a minutes I went back to my ip address and now see a 502 Gateway Error. I went back to POSTMAN to do GET request to /api/blog/posts and to api/users/users and now I see 502 Gateway Error

I’m not sure what the issue. If it’s NGINX, my code, or something else. I can’ do anything with my project now.

Any help would be appreciated.

NGINX

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

        # SSL configuration
        #
        # listen 443 ssl default_server;
        # listen [::]:443 ssl default_server;
        #
        # Note: You should disable gzip for SSL traffic.
        # See: https://bugs.debian.org/773332
        #
        # Read up on ssl_ciphers to ensure a secure configuration.
        # See: https://bugs.debian.org/765782
        #
        # Self signed certs generated by the ssl-cert package
        # Don't use them in a production server!
        #
        # include snippets/snakeoil.conf;

        root /var/www/*PROJECT NAME*/client/build/index.html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name *DO IP ADDRESS*;

        location ^~ /assets/ {
                gzip_static on;
                expires 12h;
                add_header Cache-Control public;
  }

        location / {
                proxy_http_version 1.1;
                proxy_cache_bypass $http_upgrade;

                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_pass http://localhost:3000;
                client_max_body_size 50M;
        }
location = /favicon.ico {
  log_not_found off;
}
}

server.js

require('dotenv').config()
const path = require("path")
const express = require('express')
const mongoose = require('mongoose')
const cookieParser = require('cookie-parser')
const app = express()

const blogAPI = require('./api/blogApi')
const auth = require('./api/auth')
const users = require('./api/users')


_/* Connect to Database */_
mongoose.connect(process.env.DBURI, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(() => console.log('MongoDB connected...'))
    .catch(err => console.log(err))


app.use(cookieParser())


_/* POST form handling */_
app.use(express.json());
app.use(express.urlencoded({ extended: true }));



_/* Routing */_

app.use('/api/blog', blogAPI)
app.use('/api/auth', auth)
app.use('/api/users', users)

app.use('/public', express.static(path.join(__dirname, 'public')))

// Display React in production
app.use(express.static(path.join(__dirname, '/../client', 'build')))
app.get('*', function (req, res) {
    res.sendFile(path.join(__dirname, '/../client', 'build', 'index.html'))
});

app.listen(process.env.PORT, () => console.log("Server started!"))


module.exports = app;

PostController

class PostService {
    _//  list_
    _static_ list() {
        return Post.find({})
            .then((posts) => {
                return posts
            })
    }
}

API

_/* CORS */_

const corsOptions = {
    origin: `${process.env.FRONTEND}`,
    methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
    credentials: true,
    preflightContinue: false,
    optionsSuccessStatus: 204
}

router.use(cors(corsOptions))


_/* Start of Routing */_

_/* Code associated with blog posts */_

_// list_
router.get('/posts', (req, res, next) => {
    PostService.list()
        .then((posts) => {
            res.status(200)
            res.json(posts)
        })
})

interceptor.js

const axiosPrivate = axios.create({
    baseURL: `${process.env.REACT_APP_URL}/api`
});

Explore Page

useEffect(() => {
        const fetchPosts = _async_ () => {
            try {
                let response = await axiosPrivate.get('/blog/posts')
                setPostsLoaded(response.data)
                setLatestPosts(response.data.slice(-5))
                setShowLatestPosts(true)
            } catch (error) {
                console.log(error);
            }
        }
        fetchPosts()
    }, [])

Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Bobby Iliev
Site Moderator
Site Moderator badge
April 5, 2023

Hi there,

There are a few things that I could suggest here:

Note that it is recommended to take a backup of your work before making any changes so that if anything goes wrong you could always revert back to a working version.

The 404 errors

This might be happening because the React app is not able to route the API requests correctly, and it’s serving the React app’s index.html instead of the actual API response. What you could do here is to update the location / block in your NGINX configuration to the following:

location / {
    try_files $uri $uri/ /index.html;
}

location /api {
    proxy_http_version 1.1;
    proxy_cache_bypass $http_upgrade;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://localhost:3000;
    client_max_body_size 50M;
}

That way the React app will be served from the / location and the Node.js API will be served from the /api location.

The 502 Gateway Error

This could be because your Node.js server is not running or it’s crashing due to an error. Make sure your server is running and check the logs for any error messages. You can start with the following:

  • Check the Nginx error log: tail -100 /var/log/nginx/error.log
  • In your NGINX configuration, the root directive should point to the directory, not the file. eg:
root /var/www/*PROJECT NAME*/client/build;
  • Make sure that your process.env.REACT_APP_URL variable in the interceptor.js file has the correct value. It should point to your DigitalOcean Droplet’s IP address or your domain name with the appropriate protocol (http or https).

Let me know how it goes after those changes!

As a side note, keep in mind that once you make a change to the Node.js project and the Nginx configuration you need to restart them. A good practice is to run nginx -t before restarting Nginx to make sure that there are no configuration errors.

Best,

Bobby

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel