I have a MERN application split into:
1. client folder : Front-End code (REACT app)
2. server folder : API Code (Express, NodeJs)
For some reason, front-end calls the /api part of the app, but does not return a response. Is the issue in Apache2 setup? or something in the react app. And how is the link usually done between ExpressJs (Backend) and the ReactJs (Frontend).
Routing is setup through an Apache2 Reverse Proxy
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/
Options -Indexes
ProxyRequests on
ProxyPass /api https://example.com:3000/
ProxyPassReverse /api https://example:3000/
ProxyPass / https://example.com:7000/
ProxyPassReverse / https://example:7000/
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
</IfModule>
Just to clarify in picture of what I'm trying to achieve:
I think the issue is that you've forgotten to prepare your React App for production. You spent all the time developing it and using react-scripts-start or something similar. When you are done developing you have to run react-scripts-build so that your code can be transpiled into something the browser can read. Web browsers don't read things like import and require.
Here's info on preparing for production (it's very simple)
https://create-react-app.dev/docs/production-build
And here's info on how to integrate it with your back end:
https://create-react-app.dev/docs/deployment#other-solutions
Essentially:
In your client folder run
npm build
In your server.js add
app.use(express.static(__dirname + '/build')
Now a client requests your index.html from your back end server and it serves your react app. Added benefit: no more CORS errors. Any work-around you did for CORS you should probably take it out.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 months ago.
Improve this question
I made React.js project , but it needs server side rendering, So now I have to migrate from CRA to next.js . the problem: I have to upload my website on apache web server, from what I gathered from google, I need installed node.js and pm2 (latest versions), also configured apache for reverse proxy. I also created ecoystem for pm2(I guess it was necessary). it looks like this at the moment:
module.exports = {
apps : [{
name: "nextjs-app",
script: "npm",
args: "run build",
env: {
NODE_ENV: "production"
}
}]
};
but when I ran pm2 start npm -- start , terminal is giving me respone like this:
pm2 start npm -- start
[PM2] Spawning PM2 daemon with pm2_home=/home/georgianar/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /usr/local/bin/npm in fork_mode (1 instance)
[PM2] Done.
but when I try to see list of process, there is none, and when user tries to enter the website, site log shows that there is no service on port 3000
AH01114: HTTP: failed to make connection to backend: localhost
and
(111)Connection refused: AH00957: http: attempt to connect to 127.0.0.1:3000 (localhost:3000) failed
any idea why?
Well if you want to run both on the same server you can do it in many ways
To run both Node.js and Apache on the same server, follow these steps: https://nodejs.org/en/download/package-manager/
To run your Node.js application as a service, you can use multiple methods such as creating a service, using a process manager (PM2 is common), or running a script on server startup with a cron job. For more information, see this link: How do I run a node.js app as a background service?. You'll need a server start script, typically named server.js, to do this. An example can be found at Next.js: https://nextjs.org/docs/advanced-features/custom-server. To run the application manually in the background, navigate to the app directory and run node ./server.js &
Set up a tunnel using proxypass on Apache. This is commonly used to run the Node.js application on a specific URL. You'll need to install the Apache module mod_proxy and edit the configuration for your Apache server. An example configuration could look like this:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin webmaster#example.com
ProxyPreserveHost On
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
You can also wrap the proxypass to run under a specific path using the location tag, like this:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin webmaster#example.com
ProxyPreserveHost On
<Location "/mynodeapplication/">
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
</Location>
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
</VirtualHost>
This will run your application at https://yoururl/mynodeapplication. For more information, see this link: https://httpd.apache.org/docs/trunk/mod/mod_proxy.html.
I hope this covers most of it.
To run Next on Apache, you'll need to set up the Apache settings so that when the domain or subdomain you want Next to run on is accessed, Apache points the request to the local port on the machine that's running Next. Another issue is that Next's built-in server doesn't support SSL (which I'm assuming you want), and using a custom server instead (like Express) loses you many features and optimizations that would otherwise just work with the Next server. So you'll not only need to have Apache redirect to Next, but also have Apache handle the SSL certificate.
To do this, specify a VirtualHost for the server on port 80 to redirect to HTTPS. For example, at least in Ubuntu, in etc/apache2/sites-available/000-default.conf, you can add:
<VirtualHost *:80>
ServerName subdomain.example.com
Redirect / https://subdomain.example.com/
</VirtualHost>
And then set up the SSL certificate for SSL requests (on port 443), and tell Apache to route client requests to the local machine port, and to route the local machine port's responses back to the client. If you're using LetsEncrypt, you can add this into 000-default-le-ssl.conf:
<VirtualHost *:443>
ServerName subdomain.example.com
ProxyPreserveHost On
ProxyRequests Off
ProxyPass / http://0.0.0.0:16534/
ProxyPassReverse / http://0.0.0.0:16534/
SSLEngine On
SSLProxyEngine On
SSLCertificateFile <insert path to fullchain.pem>
SSLCertificateKeyFile <insert path to privkey.pem>
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
Above, I'm running Next on port 16534 - this is the port you'd see Next logging when it starts:
ready - started server on 0.0.0.0:49447, url: http://localhost:16534
so substitute it with whichever port you're using.
You'll also need to make sure the DNS server for your website points users to your webserver's external IP address by adding an A record, if you don't have one already. If the Next app is to run on a subdomain, you'll need a separate A record for the subdomain.
So i have a React application , and a NodeJS (Express) Application running on port 4000.
i created the build for the react app and deployed it along with the backend on Apache.
The react app works fine , but the Frontend calls for the Node API dont seem to work , here's my Apache config:
<VirtualHost *:80 >
ServerName example.com
DocumentRoot /var/www/html
<Directory /var/www/html >
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
The front end doesnt seem to reach the backend am i missing something in the config ?
By the way in the front end i use Axios as a http client to make requests to the backend with its URL http://localhost:4000/ , and the app works fine in my local machine.
Thanks in advance!
In react you can transfer static files in the build folder to cpanel, direct admin or other shared server.
What is the solution for nextjs?
without using the nodejs and install it on the server
If your application does not generate dynamic pages at runtime you can use nextjs export static which will generate static HTML for you and then you could deploy on cpanel
I found the way myself.
On a dedicated server, as long as you are connected to the server using Putty, you can load the site by creating a virtual host. by example
<VirtualHost *:80>
ServerName digiattar.com
ServerAlias www.digiattar.com
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
<Proxy *>
Require all granted
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
If you enter the domain address in the browser, the server points to the localhost address and port 8080, on which Nextjs is running.
After completing the steps, you can go to the root of your project and run Nextjs as like it is on your computer using the command npm run dev or next start or etc
but after close putty everything expire, using pm2 for this problem
Lets assume I have project on .NET and is required to develop frontend for some additional module on ReactJS. According to requirements, I can login only on backend side (it has it's own UI) and frontend on React should be a standalone application. I can authorize on frontend side with backend API by passing cookies (that I get after login on backend) in Header.
I have placed source code to /var/www/project so there is such structure:
/var/www/project/backend - .NET serves to 127.0.0.1:5000
/var/www/project/frontend - I have generated a static build from ReactJS to /var/www/project/frontend/index.html
My Apache configuration:
<VirtualHost *:80>
ServerName project.com
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
<VirtualHost *:80>
ServerName subdomain.project.com
DocumentRoot /var/www/project/frontend/
<Directory "/">
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Backend works and I can access it at project.com. Frontend works also on subdomain.project.com. But I need backend to path cookie (e.g. http://prntscr.com/lgfikx) to frontend (where currently is http://prntscr.com/lgfjlx)
I have tried ProxyPassReverseCookiePath, ProxyPassReverseCookieDomain, Set-Cookie, but failed. Probably I have just used it wrong, but I have not found anywhere a working example. Answers on similar questions have not worked for me.
My final goal is to authorize frontend so I could talk to backend API. Can somebody tell me the best or just any working solution of how to do it?
If you can see the correct cookie in the WebDev tools, it's most likely that you set the cookie to HttpOnly and didn't make it available to JavaScript in the first place.
If your backend is aware of the domain name used (the cookies it sets should say .project.com in the Domain column of your web developer tools and not 127.0.0.1 or localhost), your frontend app should be able to access the cookies as well.
You only need the ProxyPassReverseCookieDomain if your backend server is using a different domain name than the one the reverse proxy uses. (i.e.: backend lives at domain.com, but you're accessing it through a reverse proxy at project.com)
I have 2 applications hosted on a single apache tomcat on port 8080
>
http://mydomain.com:8080/application1
http://mydomain.com:8080/application2
I would like to run an apache proxy in front of BOTH of them with the following behaviour
>
http://mydomain.com/* (apache2) -> http://mydomain.com:8080/application1/* (tomcat)
http://subdomain.mydomain.com/* (apache2) -> http://mydomain.com:8080/application2/* (tomcat)
The best I have got right now is 2 machines with different IPs and routing the domain and subdomains correspondingly.
Ideally I want the apache proxy and the 2 apps to be on the SAME machine...
Can anyone with kick arse DEVOps skills assist?
In addition to #Jon Lin answer, consider using ProxyPassReverse also, just in case your app do any redirects. It makes Apache correct URL's on responses (More about ProxyPassReverse). It will look like that:
<VirtualHost subdomain.mydomain.com:80>
ProxyPass / http://localhost:8080/application1/
ProxyPassReverse / http://localhost:8080/application1/
</VirtualHost>
<VirtualHost mydomain.com:80>
ProxyPass / http://localhost:8080/application1/
ProxyPassReverse / http://localhost:8080/application1/
</VirtualHost>
I hope it helps.
In the virtualhost config for mydomain.com (apache), you need
ProxyPassMatch ^/(.*)$ http://mydomain.com:8080/application1/$1
In the virtualhost config for subdomain.mydomain.com (apache), you nede
ProxyPassMatch ^/(.*)$ http://mydomain.com:8080/application2/$1
Both config files should be on the same machine, and even the same file. See VirtualHost Examples for some examples on how this is setup.