Hosting a node.js application in a subdirectory on a lemp droplet - Express static files pointing to domain root instead of app root

January 2, 2018 1.3k views
Node.js Nginx Ubuntu 16.04

I am currently trying to setup some node.js applications on a LEMP server. The scenario is as follows:

www.mydomain.com serves up the standard websites using PHP/MySQL
e.g. www.mydomain.com/site1, www.mydomain.com/site2, ... etc.

node.mydomain.com will serve up all my little node apps.
e.g. node.mydomain.com/app2, node.mydomain.com/app3, ... etc.

But it looks like the Express static folder (/public) is not getting setup properly.

node.mydomain.com/app2/styles.css or node.mydomain.com/app2/bundle.js are not browsable. Also, it looks like webpack is either not bundling correctly, my express routes aren't setup properly, my nginx server blocks are not configured right, OR running node apps in subdirectories are a pain.

When I browse to the index page, the static files are pointing to node.mydomain.com/styles.css instead of node.mydomain.com/app2/styles.css.

It all works fine on my localhost. All Express routes including static are fine. But when I deploy to the subdir, npm install, build wepback, then start the server, I get the above problems.

Here are some relevant code snippets (Node Express React app):

My Express route to the static files

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

Sample link in index.html

<link rel="stylesheet" href="styles.css" /> 

Express Listen

const port = process.env.PORT || 3000;
    app.listen(port, function () {
        console.log(`Your server, listening on port ${port}`);
        console.log(`Browse to http://localhost:${port} to view your app`);
    });

Server Block Directives

location /app2 {
                proxy_pass http://localhost:3000;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_buffering off;
        }

Webpack Config File

module.exports = {
  entry: './app.js', // assumes your entry point is the app.js in the root of your project folder
  output: {
    path: __dirname,
    publicPath: '/app2/',
    filename: './public/bundle.js' // assumes your bundle.js will also be in the root of your /public folder
  },
  devtool: 'source-map',
  resolve: {
    //extensions: ['', '.js', '.jsx'] //removed '', to fix wpack config error
    extensions: ['.js', '.jsx']
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'babel-loader',
        options: {
          presets: ['react', 'es2015'] // if you aren't using 'babel-preset-es2015', then omit the 'es2015'
        }
      },
      // use the style-loader/css-loader/sass-loader combos for anything matching the .scss extension
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      }
    ]
  }
};

I am new to deploying node.js apps and have been googling for some insights but have yet to find something that will work. Setting a baseurl doesn't seem to be an option unless using create-react-app (which I am not). I am also not sure if this is an issue of webpack not bundling correctly or only bundling with root as the only option etc. So I am still not sure what to do.

If anyone has any thoughts or experience with this, any insights would be much appreciated.

If all else fails I may change my nginx/url setup slightly to just serve the apps up at:

app2.mydomain.com
app3.mydomain.com
...
etc.

Instead of:

node.mydomain.com/app2
node.mydomain.com/app3

Thanks!

1 Answer

Update: I also tried setting it up under app2.mydomain.com and it still doesn't work. It looks like my express routes are not working... /public, /api, none of them are working...

Not sure what the issue is...

Have another answer? Share your knowledge.