title: How to correctly configure Nginx for Node.js REST API?
body: <p>I have a node application running on a service with Apache and Nginx as a reverse proxy.</p>
  
  <p>On the same server also a Node REST API is running.</p>
  
  <p>The JavaScript code looks as follows:</p>
  
  <p>api.js</p>
  
  <pre><code>// Express
  const express = require('express');
  const bodyParser = require('body-parser');
  const cors = require('cors');
  
  // Express App
  const app = express();
  
  // Env
  const PORT     = process.env.PORT || 3000;
  const NODE_ENV = process.env.NODE_ENV || 'development';
  
  // Config
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: true }));
  app.use(cors());
  
  // Routes
  const users = require('./routes/users');
  
  // Angular Http content type for POST etc defaults to text/plain at
  app.use(bodyParser.text(), function ngHttpFix(req, res, next) {
    try {
      req.body = JSON.parse(req.body);
      next();
    } catch(e) {
      next();
    }
  });
  
  app.use('/api', users);
  
  app.listen(PORT, function() {
     console.log('Listen on http://localhost:' + PORT + ' in ' + NODE_ENV);
  });
  </code></pre>
  
  <p>/routes/users.js</p>
  
  <pre><code>var models  = require('../models');
  var express = require('express');
  var router = express.Router();
  
  // get all users
  router.get('/users', function(req, res) {
    models.Beekeeper.findAll({}).then(function(users) {
      res.json(users);
    });
  });
  
  module.exports = router;
  </code></pre>
  
  <p>The Nginx configuration looks as follows:</p>
  
  <pre><code>index   index.html index.htm;
  
  upstream api {
      server 127.0.0.1:3000;
  }
  
  server {
      listen 80;
      server_name example.com;
      return 301 https://$server_name$request_uri;
  }
  
  server {
      listen 443;
      root /var/www;
  
      ssl on;
      ssl_prefer_server_ciphers On;
      ssl_protocols TLSv1.2;
      ssl_session_cache shared:SSL:10m;
      ssl_session_timeout 10m;
      ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;
  
      add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
      add_header X-Frame-Options DENY;
      add_header X-Content-Type-Options nosniff;
  
      ssl_dhparam /etc/nginx/ssl/dhparam.pem;
      ssl_certificate /etc/letsencrypt/live/example.com/cert.pem;
      ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  
      server_name example.com;
  
      location / {
              proxy_pass http://127.0.0.1:8000;
              proxy_http_version 1.1;
              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;
  
      }
  
      location /api {
              proxy_pass http://api;
              proxy_http_version 1.1;
              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;
              rewrite ^/api/?(.*) /$1 break;
              proxy_redirect off;
      }
  }
  </code></pre>
  
  <p>The problem is that if I make an API call on my development server, for example, localhost:3000/api/users, it works as expected.</p>
  
  <p>However, if I make an API call on my production server, for example, <a href="https://example.com/api/users" rel="noreferrer">https://example.com/api/users</a>, I get <em>Cannot GET /users</em> and <em>404 NOT FOUND</em>, respectively.</p>
  
  <p>I suppose that there is something wrong with my Nginx configuration, however, although I already read numerous other posts about similar problems here on Stackoverflow, I could not solve the problem.</p>