self-hosting nextjs alongside a backend on the same domain using nginx
Answered
Birman posted this in #help-forum
BirmanOP
hello forum,
i have a small linux VPS server which hosts both a nextjs build and an all-in-one backend (pocketbase).
a domain name is routed to the VPS's IP.
what i used to do, which worked, was to have the next app on the root of the domain, and a sub-domain for the admin dashboard provided by the backend.
i am now trying to use only one domain for both services.
the backend has two paths:
i have removed the rest of the file because it's mostly certbot boilerplate that is functional.
my issues is this. with the above configuration, the root domain
i have a small linux VPS server which hosts both a nextjs build and an all-in-one backend (pocketbase).
a domain name is routed to the VPS's IP.
what i used to do, which worked, was to have the next app on the root of the domain, and a sub-domain for the admin dashboard provided by the backend.
i am now trying to use only one domain for both services.
the backend has two paths:
/api and /_. with this knowledge, i tried to simply add a location to my nginx configuration for this domain, as follows:location ~ ^/(api|_)/ {
add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive";
proxy_set_header Connection '';
proxy_http_version 1.1;
proxy_read_timeout 360s;
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_pass http://localhost:<port>;
}
location / {
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_pass http://localhost:3000;
}i have removed the rest of the file because it's mostly certbot boilerplate that is functional.
my issues is this. with the above configuration, the root domain
/ successfully redirects to the nextjs app. backend data calls to /api seem to work as well. i cannot access the dashboard via the browser however. when i try, a 404 is returned from the nextjs app (not nginx) as if it were a route. i know about the trailingSlashes option, but i suspect i can solve this via pure nginx configuration without forcing all other paths to have a trailing slash, hopefully anyway.Answered by Giant panda
location ~ ^/(api|_(?!next)) {
return 200 "api backend";
}
location / {
return 200 "nextjs backend";
}16 Replies
BirmanOP
i have tried basically all variations of the backend nginx locations (
although, i have succeeded in making the backend dashboard available, but it breaks static content and nextjs api calls, a reversal of the main problem.
i realise this may be more of an nginx question, or even a pocketbase question as well, but i'm giving it a shot here anyway.
thanks in advance
=, ~ ...), changing the order of the location blocks, adding/removing trailing slashes to urls and paths, and adding a rewrite rule to append a slash again, but to no avail so far.although, i have succeeded in making the backend dashboard available, but it breaks static content and nextjs api calls, a reversal of the main problem.
i realise this may be more of an nginx question, or even a pocketbase question as well, but i'm giving it a shot here anyway.
thanks in advance
Giant panda
So at what path should the dashboard be?
BirmanOP
domain.com/_
Giant panda
Have you tried
domain.com/_/? Your rule specifies it needs a trailing slashAlso https://nginx-playground.wizardzines.com/ can be useful to test rules
you could add a simplified version like
location ~ ^/(api|_)/ {
return 200 "api backend";
}
location / {
return 200 "nextjs backend";
}Changing to
location ~ ^/(api|_) (without trailing slash) makes it work I thinkLet me know if that does the trick for you
BirmanOP
thank you for the resource, i was looking around for something like this. better than entering the same commands over and over again ha.
i have tried
i'll do some more testing and come back here as well though. in any case, many thanks!
i have tried
domain.com/_/, but i suspect because of the default behaviour of nextjs the trailing slash is removed after i enter the url.i'll do some more testing and come back here as well though. in any case, many thanks!
BirmanOP
after removing the trailing slash, i just realised, does the underscore also unintentionally catch
_next? because according to an nginx test it does, explaining why when i do the opposite the dashboard works, html works, but not static content from _next.Giant panda
Possibly, you could either add this explicitly into the location block to next or use a regex lookahead clause. This will only match the underscore if it's not followed by "next"
Giant panda
location ~ ^/(api|_(?!next)) {
return 200 "api backend";
}
location / {
return 200 "nextjs backend";
}Answer
Giant panda
using the playground testing
http --pretty format get http://localhost:80/_next/thing then routes to the nextjs backendI prefer the above, but you could also do something along the lines of
location ~ ^/(.*|_next) {
return 200 "nextjs backend";
}
location ~ ^/(api|_) {
return 200 "api backend";
}Or, just use a different path for your admin dashboard that doesn't overlap and avoid the whole problem 😉
@Giant panda Or, just use a different path for your admin dashboard that doesn't overlap and avoid the whole problem 😉
BirmanOP
hello, a bit delayed in my response sorry.
i ended up going back to separate domains for the backend and the frontend, as i realised only after starting to go down the rabbit hole of nginx that i use api routes with nextjs, so my original plan never would have worked any way.
your answer is correct though, and if not for the conflicts between api routes, this nginx setup works fine.
thank you for your help in any case.
i ended up going back to separate domains for the backend and the frontend, as i realised only after starting to go down the rabbit hole of nginx that i use api routes with nextjs, so my original plan never would have worked any way.
your answer is correct though, and if not for the conflicts between api routes, this nginx setup works fine.
thank you for your help in any case.