i've been struggling to configure the sites-available config file and was hoping to get some guidance. I'm trying to point sub.domain.com/app1 and sub.domain.com/app2 to the correct location. I have 2 react and express running on port 2000 and port 3000, and they are both working file when accessing the ip address and port number (xx.xx.xx.x:2000). One of the app works if the location is root(/), but as soon as I try to change the location or add another the page turns blank. Any help would be appreciated.
server {
listen 80;
server_name sub.domain.com;
location /app1 {
proxy_pass http://localhost:2000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_buffering off;
proxy_request_buffering off;
proxy_cache_revalidate on;
}
location /app2 {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_buffering off;
proxy_request_buffering off;
proxy_cache_revalidate on;
}
}
If you have a standard react application(not a next.js one) then you will need to first build it and then you have to place it in the correct path, as example /var/www/html/app1/
So your default.conf would include the following:
location /app1 {
alias /var/www/html/app1/;
try_files $uri /index.html =404;
}
location /app2 {
alias /var/www/html/app2/;
try_files $uri $uri/ index.html =404;
}
Now, if you run CRA then you should have a look on their deployment guide, especially in Serving the Same Build from Different Paths
I have to host my teams app under https://mysite/myapp
The host is ruled by nginx like that
location /myapp {
proxy_pass http://ip:port;
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;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
http://ip:port is the real host of the teams app inside a docker container.
This is the nginx config for the container
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
this is the docker file (a part of it)
FROM nginx:alpine
COPY --from=build /nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /build /usr/share/nginx/html
If I try http://ip:port/tab I see
If I try https://mysite/myapp/tab I can't see any message from the page and the browser seems to load the index.html page
Is there a way to make the react routing work with this settings?
I am running a React app on Nginx in production.
If I refresh on any route different that "/" I get "Resource not found".
for example:
Refresh on http://www.aaaa.com will be OK
Refresh on http://www.aaaa.com/bbb/ddd will result in Resource not found.
I searched a lot and tried everything I found including adding try_files $uri $uri/ /index.html;
This is part of my conf file:
upstream ggg_stream {
server ggg.aaa.com:9090 fail_timeout=0;
}
server {
listen 80;
server_name aaa.com;
root /var/www;
location / {
try_files $uri $uri/ /index.html;
}
location /ggg {
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;
# Fix the "It appears that your reverse proxy set up is broken" error.
proxy_pass http://ggg_stream/;
proxy_read_timeout 90;
# proxy_redirect http://127.0.0.1:8080 http://34.248.183.236:8080;
# Required for new HTTP-based CLI
proxy_http_version 1.1;
proxy_request_buffering off;
}
}
This server also used as a proxy so it has many stream mappings such as ggg
The site content is located at /var/www
We use React router 4.
Any ideas?
Regards,
Ido
I have a front end reactjs being served by nginx. shown here:
server {
listen 80 default_server;
server_name website.* www.website.*;
root /home/developer/website/frontend/build;
location / {
try_files $uri /index.html;
}
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:4000;
}
}
Additionally, I have a second express app receiving requests at 127.0.0.1:4000. The front end calls fetch to 'api/something' and the express app receives that and handles it but does not respond, the client side errors with 504 (Gateway Time-out). Any ideas?
You are missing the upstream server directive. Try this
upstream api {
server 127.0.0.1:4000;
}
# remove www from the url
server {
listen 80;
server_name www.website.com;
return 301 $scheme://website.com$request_uri;
}
server {
listen 0.0.0.0:80;
server_name website.com website;
error_log /var/log/nginx/website.com-error.log error;
access_log /var/log/nginx/website.log;
# pass the request to the node.js server with the correct headers
location /api/ {
proxy_pass http://api/;
proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
proxy_ignore_headers Set-Cookie;
proxy_hide_header Set-Cookie;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-NginX-Proxy true;
}
}
I have two Express powered NodeJS applications that are being served by Nginx. One application is a RESTful API, that is consumed by an Angular SPA and the other one is an Admin portal. This is something I'm trying to achieve here:
location / {
# Serves Client Side Angular Application
}
location /api {
# Serves RESTful Application
}
location /admin {
# Serves Admin Portal
}
Here is my complete configuration for nginx:
server {
server_name localhost;
listen 80;
listen [::]:80;
index index.html;
location / {
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
root /var/www/example/client/dist;
try_files $uri $uri/ /index.html =404;
}
location /admin/ {
proxy_pass http://127.0.0.1:3010/;
proxy_http_version 1.1;
rewrite /admin/(.*) /$1 break;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host/admin/;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /api {
proxy_pass http://127.0.0.1:3011;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Both of the NodeJS application utilizes forever and run on their defined ports, perfectly.
The problem I'm facing with my admin application, when I try to hit http://example.com/admin it redirects me to http://example.com/login when it should redirect me to http://example.com/admin/login. I tried to solve this issue by adding a middleware to the admin application, like:
app.use('*', function (req, res, next) {
if(process.env.target === 'dev'){
if(req.originalUrl.indexOf('/admin') > -1){
res.redirect('/admin' + req.url);
}
next();
}
});
But this doesn't work. How should I handle this situation? Is there anyway nginx can handle application redirects? If not, how should I handle it in application for different environments(Dev, Staging, Prod etc)? I'm using nginx 1.4.6, node 0.12.2 and express 4.12.2. I have no issue if I have to add any 3rd party module in my application but I'd prefer if there is an nginx solution for my problem.
Thanks.
The problem with your nginx config is the rewrite for the /admin route:
rewrite /admin/(.*) /$1 break;
With this rule in place your admin portal node app doesn't know that its paths are all hosted off of a /admin root, so if your app does a redirect relative what it thinks is root, eg res.redirect('/login'), it makes sense that it would send the browser to localhost/login.
An alternative would be to remove your nginx rewrite and just make the admin portal aware of this /admin path. That way you have the option of redirecting to a relative path, like this: res.redirect('login') which tells express to take the current request's path into account. You can use the express.Router to make this cleaner, like this for example:
var adminRoutes = express.Router()
.get('/', function(req, res) {
if(!req.user) {
// Will redirect to /admin/login
res.redirect('login');
} else {
res.send('Hello');
}
})
.get('/login', login);
// Tell express to host all routes above under a common /admin root
app.use('/admin', adminRoutes);
If on the other hand there's a better reason why you must have the nginx rewrite, you can always just include the /admin root manually for all of your app's redirects. You could provisionally append this mount path by reading it from a custom header set byproxy_set_header. For example:
app.use(function(req, res, next) {
res.mountedAt = req.headers['X-Mounted-At'];
next();
});
app.get('/', function(req, res) {
res.redirect(path.join(res.mountedAt, '/login'));
});
I solved this by combining Andrew Lavers's first solution with
location /admin/ {
proxy_pass https://127.0.0.1:3010/admin/;
}