Home > Enterprise >  Is it a good practice to keep nodejs server and react frontend in same directory?
Is it a good practice to keep nodejs server and react frontend in same directory?

Time:04-09

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 ?

CodePudding user response:

Modern stack monoliths

https://lzomedia.com/blog/different-ways-to-connect-react-frontend-and-node-backend/

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: enter image description here

But, if your site will be a complex spa with several menus, modules, roles, invocation to several rest apis, etc I advice you a distributed or decoupled architecture. I mean one app or process by repository/server. Here some advantages :

  • frontend (spa) with react
    • own domain like acme.com
    • you could use specialized services for static webs
    • you are not bound to only one api. You could consume several apis.
    • react developers could have its own git strategy
    • custom build for webs
  • backend (api) with nodejs
    • own domain like acme.api.com
    • you could scale only the backend because the heavy process is in this layer
    • nodejs developers could have its own git strategy

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

CodePudding user response:

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:

# Build the frontend.
FROM node:lts AS frontend
WORKDIR /app
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ ./
RUN npm build
# Built files are left in /app/build; this stage has no CMD.

# Build the main server.
FROM node:lts
WORKDIR /app
COPY server/package*.json ./
RUN npm ci
COPY server/ ./
# Copy the build tree from the frontend image into this one.
COPY --from=frontend /app/build ./static
RUN npm build

# Normal metadata to set up and run the server container.
EXPOSE 3000
CMD ["npm", "run", "start"]

(*) 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.

  • Related