I need to serve my React built files (build directory) using nodejs server. With React being wrapped in Docker my nodejs server can not access build directory within /frontend. So what I am thinking of is to move my server.js
into /frontend
and having a single Dockerfile for both of them.
It would have something like this CMD ['npm run build', 'node server.js']
Would that be illegal and bad practice ?
2
Answers
To architect a web, you have these options:
Ancient monoliths
This was the first way to implement a web. All is in the server: frontend & backend. Frontend(html) is created dynamically in the server and sent to the browser on each request.
In this kind of applications:
Here some languages and its frameworks
Not your case but I saw flows like this:
npm run build
. Usually a human execute this.Modern Monoliths
As you can see in the picture, the frontend and backend are deployed n the same server, in the same port.
If your are developing a single site with its backend, it could work to have frontend and backend in the same repository or directory. It will be like the modern monoliths: mean, mern, mevn with some challenges related to the fact to have different application types in one repository.
CSR/SPAs with several apis/microservices
Suitable if:
If this is your case, I advice you a distributed or decoupled architecture. I mean one app or process by repository/server. Here some advantages :
serve the spa
If your web is simple, you could use
But if your web has complexities like backend: env variables portability, one build, etc you could use:
References
You can’t (*) run multiple servers in a single container.
For your setup, though, you don’t need multiple servers. You can compile the React application to static files and serve those from your other application. There are some more advanced approaches where a server injects the data or a rendered copy of the page as it serves these up; these won’t necessarily work with a React dev server in a separate container (probably some of the setup described in @JRichardsz’s answer goes into this more).
If both halves are in the same repository, you can potentially use a Docker multi-stage build to compile the front-end application to static files, then copy the result into the main server image. This could look like:
(*) It’s technically possible, but you need to install some sort of process manager, which adds significant complication. It’s less of a concern with the approach I describe here but you also lose some things like the ability to see just a single process’s logs or the ability to update only one part of the system without restarting the rest of it. The
CMD
you suggest won’t do it. I’d almost always use multiple containers over trying to shoehorn in something like supervisord.