Deploying React (3000) and Express (8000) app on the apache server

Viewed 1933

I have created a React+Express application using the commands npx create-react-app client for React and npx express-generator api for the express backend. Both client and API are under the same folder application.

The react application is running on the port 3000 and I have changed the port of express app to use port 8000 in the /bin/wwww.

In the express application I have crated a route in routes/testAPI.js,

router.get("/", function(req, res, next) {
    res.send(“API is working properly”);
});

And in app.js file I have used the route to handle request,

let testAPIRouter = require("./routes/testAPI");
app.use("/testAPI", testAPIRouter);

Now in the react application inside the App.js file I have called the API and updated the content of <p>{this.state.apiresponse}</p>.

App.js file,

class App extends React.Component{
   constructor(props){
       super(props);
       this.state = {
          apiResponse : "",
       }
    }
    apiCall = () => {
       fetch("http://localhost:8000/testAPI")
        .then(res => res.text())
        .then(res => this.setState({ apiResponse: res }));
    }
    componentWillMount = () => {
       this.callAPI();
    }
    
    render(){
        return(
          <div>
              <p>{this.state.apiResponse}</p>
          </div>
    )
   }
 }

My issue is to deploy this application on an apache server. As I'm running the express and react at different ports(3000 and 8000). I can build the react app using npm run build which will create static build files for react. But, how can I build the express app to use with react? Is it so moving the express files to the server and always run the application there at port 8000?

I have successfully abled to run both at time using concurrent. I can run the application using npm run dev. But how to build the application and serve from apache?

Thanks in advance.

3 Answers

In the package.json of your react app use proxy

"proxy": "http://localhost:8000"

and use only the routes not base url to fetch

fetch("/testAPI")

Now copy React App Folder to your Express folder and add this scripts to your package.json of Express

"scripts": {
"client-install": "npm install --prefix reactapp",
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix reactapp",
"dev": "concurrently \"npm run server\" \"npm run client\""
},

Now run

npm run client-install

for only one time And run

npm run dev

to run both server and client

I appreciate all the answers I have received. So as an addition to the answers I have received I would like to mention how I moved the build into production.

1. npm install -g pm2
2. sudo chmod 755 /server/build/server.js (build file)
3. sudo pm2 start /server/build/server.js (Adds to pm2 task)
4. sudo pm2 startup systemd

And I have created a new virtual host in /etc/apche2/sites-available/nodeapp.conf and enable these apache modules sudo a2enmod proxy && sudo a2enmod proxy_http

<VirtualHost *:80>
ServerName localhost(can be domain)

   ProxyRequests Off
   ProxyPreserveHost On
   ProxyVia Full
   <Proxy *>
      Require all granted
   </Proxy>

   <Location /node>
      ProxyPass http://127.0.0.1:3001
      ProxyPassReverse http://127.0.0.1:3001
   </Location>

    <Directory "/project/server/build">
    AllowOverride All
    </Directory>
</VirtualHost>

Now enable the site by sudo a2ensite nodeapp.conf. Reload the server and hit localhost/node and boom!

Incase if you are getting any blank screen error make sure add the below in react's package.json. "homepage":"http://localhost/node".

https://www.ionos.com/community/server-cloud-infrastructure/nodejs/set-up-a-nodejs-app-for-a-website-with-apache-on-ubuntu-1604/

You need to modify your react application. Use Env variables to use diffenrent URLS. Define your base url as ENV.

After a build it's just simple HTML, CSS, JS application you can deploy it on sub path as well.

ex. https://example.com/website

There is no need to deploy react on port or with Express.

But if you want to achieve something like this what you can do is prepare a build, put it in express views folders and serve your react application from Express.

Related