Search code examples
reactjsexpressherokuheroku-cli

Heroku React-Express App is not deploying


I'm able to deploy my GitHub branch. However, when I open the link to the deployed web app, it shows "Invalid Host Header".

When I checked the logs, this is what I found:

2023-09-17T10:17:43.000000+00:00 app[api]: Build succeeded
2023-09-17T10:17:47.178441+00:00 heroku[web.1]: Starting process with command `npm start`
2023-09-17T10:17:48.741254+00:00 app[web.1]:
2023-09-17T10:17:48.741268+00:00 app[web.1]: > [email protected] start
2023-09-17T10:17:48.741269+00:00 app[web.1]: > concurrently "npm run server" "npm run client"
2023-09-17T10:17:48.741269+00:00 app[web.1]:
2023-09-17T10:17:49.262327+00:00 app[web.1]: [1]
2023-09-17T10:17:49.262337+00:00 app[web.1]: [1] > [email protected] client
2023-09-17T10:17:49.262337+00:00 app[web.1]: [1] > npm start --prefix client
2023-09-17T10:17:49.262337+00:00 app[web.1]: [1]
2023-09-17T10:17:49.295805+00:00 app[web.1]: [0]
2023-09-17T10:17:49.295807+00:00 app[web.1]: [0] > [email protected] server
2023-09-17T10:17:49.295811+00:00 app[web.1]: [0] > nodemon server.js
2023-09-17T10:17:49.295811+00:00 app[web.1]: [0]
2023-09-17T10:17:49.420106+00:00 app[web.1]: [0] [nodemon] 3.0.1
2023-09-17T10:17:49.420291+00:00 app[web.1]: [0] [nodemon] to restart at any time, enter `rs`
2023-09-17T10:17:49.420532+00:00 app[web.1]: [0] [nodemon] watching path(s): *.*
2023-09-17T10:17:49.420533+00:00 app[web.1]: [0] [nodemon] watching extensions: js,mjs,cjs,json
2023-09-17T10:17:49.420764+00:00 app[web.1]: [0] [nodemon] starting `node server.js`
2023-09-17T10:17:49.519430+00:00 app[web.1]: [1]
2023-09-17T10:17:49.519431+00:00 app[web.1]: [1] > [email protected] start
2023-09-17T10:17:49.519431+00:00 app[web.1]: [1] > react-scripts start
2023-09-17T10:17:49.519432+00:00 app[web.1]: [1]
2023-09-17T10:17:49.551441+00:00 app[web.1]: [0] Server is running on port 5000
2023-09-17T10:17:51.147988+00:00 app[web.1]: [1] (node:92) [DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE] DeprecationWarning: 'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
2023-09-17T10:17:51.147998+00:00 app[web.1]: [1] (Use `node --trace-deprecation ...` to show where the warning was created)
2023-09-17T10:17:51.148360+00:00 app[web.1]: [1] (node:92) [DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE] DeprecationWarning: 'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
2023-09-17T10:17:51.392218+00:00 app[web.1]: [1] Starting the development server...
2023-09-17T10:17:51.392220+00:00 app[web.1]: [1]
2023-09-17T10:17:51.704232+00:00 heroku[web.1]: State changed from starting to up
2023-09-17T10:17:54.137351+00:00 app[web.1]: [1] One of your dependencies, babel-preset-react-app, is importing the
2023-09-17T10:17:54.137360+00:00 app[web.1]: [1] "@babel/plugin-proposal-private-property-in-object" package without
2023-09-17T10:17:54.137361+00:00 app[web.1]: [1] declaring it in its dependencies. This is currently working because
2023-09-17T10:17:54.137361+00:00 app[web.1]: [1] "@babel/plugin-proposal-private-property-in-object" is already in your
2023-09-17T10:17:54.137361+00:00 app[web.1]: [1] node_modules folder for unrelated reasons, but it may break at any time.
2023-09-17T10:17:54.137362+00:00 app[web.1]: [1]
2023-09-17T10:17:54.137362+00:00 app[web.1]: [1] babel-preset-react-app is part of the create-react-app project, which
2023-09-17T10:17:54.137363+00:00 app[web.1]: [1] is not maintianed anymore. It is thus unlikely that this bug will
2023-09-17T10:17:54.137363+00:00 app[web.1]: [1] ever be fixed. Add "@babel/plugin-proposal-private-property-in-object" to
2023-09-17T10:17:54.137363+00:00 app[web.1]: [1] your devDependencies to work around this error. This will make this message
2023-09-17T10:17:54.137364+00:00 app[web.1]: [1] go away.
2023-09-17T10:17:54.137365+00:00 app[web.1]: [1]
2023-09-17T10:17:56.158476+00:00 app[web.1]: [1] Compiled successfully!
2023-09-17T10:17:56.158724+00:00 app[web.1]: [1]
2023-09-17T10:17:56.158724+00:00 app[web.1]: [1] You can now view client in the browser.
2023-09-17T10:17:56.158725+00:00 app[web.1]: [1]
2023-09-17T10:17:56.158725+00:00 app[web.1]: [1]   Local:            http://localhost:38003
2023-09-17T10:17:56.158725+00:00 app[web.1]: [1]   On Your Network:  http://172.18.105.90:38003
2023-09-17T10:17:56.158725+00:00 app[web.1]: [1]
2023-09-17T10:17:56.158726+00:00 app[web.1]: [1] Note that the development build is not optimized.
2023-09-17T10:17:56.158889+00:00 app[web.1]: [1] To create a production build, use npm run build.
2023-09-17T10:17:56.158890+00:00 app[web.1]: [1]
2023-09-17T10:17:56.163952+00:00 app[web.1]: [1] webpack compiled successfully
2023-09-17T10:18:45.294911+00:00 heroku[router]: at=info method=GET path="/" host=workshop01-cds-410d958eb7f1.herokuapp.com request_id=c43d6b5f-9c2d-4189-9d2b-c789ef726895 fwd="116.15.222.77" dyno=web.1 connect=0ms service=9ms status=304 bytes=150 protocol=https
2023-09-17T10:18:45.806704+00:00 heroku[router]: at=info method=GET path="/favicon.ico" host=workshop01-cds-410d958eb7f1.herokuapp.com request_id=4e5183cb-5510-4457-a982-ff34587c8b2e fwd="116.15.222.77" dyno=web.1 connect=0ms service=4ms status=304 bytes=150 protocol=https
2023-09-17T10:20:28.775110+00:00 heroku[web.1]: State changed from up to down
2023-09-17T10:20:29.415946+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2023-09-17T10:20:29.618612+00:00 heroku[web.1]: Process exited with status 143

This is my file structure:

Folder1 (a folder in the GitHub Repo)
- client
        ^-- build
        ^-- node_modules
        ^-- public
        ^-- src
        ^-- .gitignore
        ^-- package.lock.json
        ^-- package.json
- node_modules
- .gitignore
- package.lock.json
- package.json
- server.js

My server.js:

const _ = require('lodash');
const express = require('express');
const app = express();
const port = 5000;

if (process.env.NODE_ENV === 'production') {
  // Exprees will serve up production assets
  app.use(express.static('client/build'));

  // Express serve up index.html file if it doesn't recognize route
  const path = require('path');
  app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
  });
}

list_of_texts = [
    "Logic will get you from A to B. Imagination will take you everywhere.",
    "There are 10 kinds of people. Those who know binary and those who don't.",
    "There are two ways of constructing a software design. One way is to make it\
    so simple that there are obviously no deficiencies and the other is to make\
    it so complicated that there are no obvious deficiencies.",
    "It's not that I'm so smart, it's just that I stay with problems longer.",
    "It is pitch dark. You are likely to be eaten by a grue."
]

app.get('/api', (req, res) => {
  res.send(_.sample(list_of_texts));
}); // note that "/" will clash with the root route of the react app
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

My package.json (outside of client folder):

{
  "name": "workshop01",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "client-install": "npm install --prefix client",
    "server": "nodemon server.js",
    "client": "npm start --prefix client",
    "start": "concurrently \"npm run server\" \"npm run client\"",
    "heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "concurrently": "^8.2.1",
    "express": "^4.18.2",
    "lodash": "^4.17.21",
    "nodemon": "^3.0.1"
  }
}

My app.js in client:

import React, { useEffect, useState } from 'react';
import image from './fortune-cookie.avif';

function App() {
  const [message, setMessage] = useState('');
  useEffect(() => {
    fetch('/api')
      .then((res) => res.text())
      .then((data) => setMessage(data))
      .catch((err) => console.log(err));
  }, []);
  return (
    <div style={{textAlign: "center"}}>
      <h1><img src={image} width="150" alt='fortune-cookie'></img>{message}</h1>
    </div>
  );
}
export default App;

I've been trying to debug for a while now, but am still not sure what the problem is here. Any help would be appreciated!


Solution

  • I've resolved the issue.

    This is my current server.js:

    const _ = require("lodash");
    const express = require("express");
    const app = express();
    const port = process.env.PORT || 5000;
    const path = require("path");
    
    // Exprees will serve up production assets
    app.use(express.static(path.join(__dirname, "client/build")));
    
    app.get("/api", (req, res) => {
      res.send(_.sample(list_of_texts));
    }); // note that "/" will clash with the root route of the react app
    
    // Express serve up index.html file if it doesn't recognize route
    app.get("*", (req, res) => {
      res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
    });
    
    list_of_texts = [
      "Logic will get you from A to B. Imagination will take you everywhere.",
      "There are 10 kinds of people. Those who know binary and those who don't.",
      "There are two ways of constructing a software design. One way is to make it\
        so simple that there are obviously no deficiencies and the other is to make\
        it so complicated that there are no obvious deficiencies.",
      "It's not that I'm so smart, it's just that I stay with problems longer.",
      "It is pitch dark. You are likely to be eaten by a grue.",
    ];
    
    app.listen(port, () => {
      console.log(`Server is running on port ${port}`);
    });
    
    

    Specifically, I changed my port to process.env.PORT || 5000 instead of hardcoding it at 5000. I also made sure that Express serves up the index.html file from client/build.

    This solved the issue for me, hope this helps you too!