Deploying a react, socket.io app to Render

I have previous experience deploying apps to render but mostly for the Pythonic Dash-based visualizations.

I am working on a location sharing app, forked from an individual who has graciously provided his code as a reference. I forked the code to my github as can be seen here.

My aim is to have the app to be deployed on render. As background information, I was relying on Render’s “Deploy a Create React App Static Site” instructions to render this location sharing app since a good portion of it is React based.

I got various errors, even after tinkering with the Root Directory of Render’s settings. One of the most recurrent errors was:

error Couldn't find a package.json file in "/opt/render/project/src"

I don’t think this could be the issue since there exist package.json files and other .json files in the client and server folders… Furthermore, I have not altered the code in anyway. In other words, the app works, I only need to know how to upload it to Render. Apart from Python-dash apps, I don’t have any experience deploying others to Render.

Howdy!

I think it’s because of your root directory. Your project is a monorepo, so you need to tell your react build that the root directory for the react build should be client, not just blank which is the repository route.

Also, I just took took a crack at deploying it myself, and your publish directory should probably be dist not build, vite is putting your build artifacts there.

(BTW careful with posting that deploy hook url, its meant to be a secret)

Hello,

Just a question, did you succeed?

I tried with going to Render> New static site>connect a repository, selecting client folder as root directory and the src folder as the Publish Directory. I followed this route since it is the recommended way for rendering React apps. Still no luck.

Besides that, I also tried the Deploy A Node express App method, changed the root directory to client/src and start command to node app.tsx since there is no .js file in all the two root folders of client and server, just some typescript and json files.

If you succeeded, I think a step by step flow would help me, then I can backtrack by reading through each step. Furthermore, there is no dist or build folders you suggested anywhere in the two root folders.

The publish directory is the one where your bundled assets get put when the build is done- I can see from your package.json that vite is run on yarn build. As part of your build, a dist folder is created under client and all your built assets go into it, so you’ll want to specify client as your root directory and dist as your publish directory.

I got the frontend build working yesterday but didn’t push further. I’ll take a stab at the BE today. I haven’t had to set any redirects/rewrites so far (I haven’t really looked at the code) and the frontend is loading. https://location-share-p5cv.onrender.com

In the meantime, here’s the config I used for the FE build:

Hello,

Thanks. Funny I am trying it again with the same results. I guess this is the workflow for rendering a react on Render (New>New Static Site>…), going by the pic. I had done so earlier, and trying afresh ensuring it matches to your FE picture, I still get the same “failed to deploy” message. By trying to be more adventurous, I experimented with the redirect/rewrite rule, as explained in the aforementioned link, but that didn’t work either.

Here is the log.

Oct 17 05:20:49 PM  ==> It looks like we don't have access to your repo, but we'll try to clone it anyway.
Oct 17 05:20:49 PM  ==> Cloning from https://github.com/sammigachuhi/location_share...
Oct 17 05:20:50 PM  ==> Checking out commit cdfe2a9c0b5ac90f33cae438a202859d905d4325 in branch main
Oct 17 05:20:54 PM  ==> Using Node version 14.17.0 (default)
Oct 17 05:20:54 PM  ==> Docs on specifying a Node version: https://render.com/docs/node-version
Oct 17 05:20:54 PM  ==> Using Node version 14.17.0 (default)
Oct 17 05:20:54 PM  ==> Docs on specifying a Node version: https://render.com/docs/node-version
Oct 17 05:20:55 PM  ==> Using Ruby version 2.6.8 (default)
Oct 17 05:20:55 PM  ==> Docs on specifying a Ruby version: https://render.com/docs/ruby-version
Oct 17 05:21:26 PM  ==> Installing dependencies with npm...
Oct 17 05:21:45 PM  
Oct 17 05:21:45 PM  > esbuild@0.18.20 postinstall /opt/render/project/src/client/node_modules/esbuild
Oct 17 05:21:45 PM  > node install.js
Oct 17 05:21:45 PM  
Oct 17 05:21:46 PM  added 271 packages from 240 contributors and audited 294 packages in 19.572s
Oct 17 05:21:46 PM  
Oct 17 05:21:46 PM  51 packages are looking for funding
Oct 17 05:21:46 PM    run `npm fund` for details
Oct 17 05:21:46 PM  
Oct 17 05:21:46 PM  found 0 vulnerabilities
Oct 17 05:21:46 PM  
Oct 17 05:21:51 PM  audited 294 packages in 4.791s
Oct 17 05:21:52 PM  
Oct 17 05:21:52 PM  51 packages are looking for funding
Oct 17 05:21:52 PM    run `npm fund` for details
Oct 17 05:21:52 PM  
Oct 17 05:21:52 PM  found 0 vulnerabilities
Oct 17 05:21:52 PM  
Oct 17 05:22:08 PM  ==> Using Python version 3.7.10 (default)
Oct 17 05:22:08 PM  ==> Docs on specifying a Python version: https://render.com/docs/python-version
Oct 17 05:22:12 PM  ==> Running build command 'yarn build'...
Oct 17 05:22:12 PM  yarn run v1.22.19
Oct 17 05:22:12 PM  $ tsc && vite build
Oct 17 05:22:17 PM  vite v4.4.11 building for production...
Oct 17 05:22:17 PM  transforming...
Oct 17 05:22:20 PM  ✓ 44 modules transformed.
Oct 17 05:22:20 PM  ✓ built in 2.80s
Oct 17 05:22:20 PM  [vite]: Rollup failed to resolve import "leaflet/dist/leaflet.css" from "/opt/render/project/src/client/src/components/Elements/Map/index.tsx".
Oct 17 05:22:20 PM  This is most likely unintended because it can break your application at runtime.
Oct 17 05:22:20 PM  If you do want to externalize this module explicitly add it to
Oct 17 05:22:20 PM  `build.rollupOptions.external`
Oct 17 05:22:20 PM  error during build:
Oct 17 05:22:20 PM  Error: [vite]: Rollup failed to resolve import "leaflet/dist/leaflet.css" from "/opt/render/project/src/client/src/components/Elements/Map/index.tsx".
Oct 17 05:22:20 PM  This is most likely unintended because it can break your application at runtime.
Oct 17 05:22:20 PM  If you do want to externalize this module explicitly add it to
Oct 17 05:22:20 PM  `build.rollupOptions.external`
Oct 17 05:22:20 PM      at viteWarn (file:///opt/render/project/src/client/node_modules/vite/dist/node/chunks/dep-2b82a1ce.js:48205:27)
Oct 17 05:22:20 PM      at onwarn (file:///opt/render/project/src/client/node_modules/@vitejs/plugin-react/dist/index.mjs:247:9)
Oct 17 05:22:20 PM      at onRollupWarning (file:///opt/render/project/src/client/node_modules/vite/dist/node/chunks/dep-2b82a1ce.js:48234:9)
Oct 17 05:22:20 PM      at onwarn (file:///opt/render/project/src/client/node_modules/vite/dist/node/chunks/dep-2b82a1ce.js:47965:13)
Oct 17 05:22:20 PM      at file:///opt/render/project/src/client/node_modules/rollup/dist/es/shared/node-entry.js:24276:13
Oct 17 05:22:20 PM      at Object.logger [as onLog] (file:///opt/render/project/src/client/node_modules/rollup/dist/es/shared/node-entry.js:25950:9)
Oct 17 05:22:20 PM      at ModuleLoader.handleInvalidResolvedId (file:///opt/render/project/src/client/node_modules/rollup/dist/es/shared/node-entry.js:24862:26)
Oct 17 05:22:20 PM      at file:///opt/render/project/src/client/node_modules/rollup/dist/es/shared/node-entry.js:24822:26
Oct 17 05:22:20 PM      at processTicksAndRejections (internal/process/task_queues.js:95:5)
Oct 17 05:22:20 PM  error Command failed with exit code 1.
Oct 17 05:22:20 PM  info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Oct 17 05:22:20 PM  ==> Build failed 😞

Your steps and setup looks good to me.
Ah, looks like you are using a pretty old version of node though.
Try setting your NODE_VERSION to whatever you’re using locally (I’m using 16.13.1)

I’m not a vite expert, but maybe try that first. I had trouble with the vite build locally too and had to do some hacking to make it work, but when I build on render, my hacks aren’t needed.

Hi there,

What you set the root and publish directory to will depend on your app’s configuration and how you build it. Matt’s initial response is correct.

Samuel, you will need to build your client first, which is why there is no dist or build directories in your repo. You need to run yarn build / npm run build to create them. You can do this locally if you are unsure which value to use. You can see what is created locally and put that as your public directory. Just make sure you don’t commit your built frontend to Git (add build or dist to your .gitignore).

Also node app.tsx isn’t going to work as NodeJS can’t directly run Typescript files. You need to build your frontend first. Unless you want to run both your frontend and backend from the same service, you should probably use a static site. If you use a web service instead of a static site, you will need to make it so your server code serves your dist / build directory through Express. Something like this would work.

If your server code is also ts/tsx you will need to run it through ts-node or transpile it to Javascript first with tsc.

Regards,

Keith
Render Support, UTC+10 :australia:

I’ve got all the builds running now.

With respect to your failing frontend build, make sure to set a NODE_VERSION in your environment variables, double check your params look like mine did and then try doing a “clear build cache and deploy”:
Screenshot 2023-10-18 at 11.57.19 AM

I’ve found that with some of attempts I’ve made that the build cache causes intermittent hiccups. My hope is that as long as your service definition matches mine, after a clear build cache, you’ll get through. (fingers crossed)

I got the backend build to pass, but never tested the application. You need to make sure in your buildCommand that you are doing yarn; yarn build. Static sites pull your dependencies automatically via npm, but web services don’t do this, so you have to set your build command to be: yarn; yarn build. My server build params:

@Keith
Off the back of this, since I just learned it the hard way, I opened up a feature request for some transparency in the build logs around using npm by default: https://feedback.render.com/features/p/transparency-during-static-sites-dependency-install

Hello,

First of all thanks for getting me through the deployment stage. I merged your Github commit to mine and deployed it anew on Render using Create New Web Service rather than Create Static Site as before.

I set the params as in your picture. It succeeded alright, but all I get is the below image, but the app’s heading is printed out.

You can find the empty app, except for its heading, here – https://react-location-share-web-service.onrender.com/

The interface is not there. I understand it has been quite a load on your part to see this through.

Here are the logs:

Oct 18 09:35:10 PM  ==> Deploying...
Oct 18 09:35:32 PM  ==> Using Node version 14.17.0 (default)
Oct 18 09:35:32 PM  ==> Docs on specifying a Node version: https://render.com/docs/node-version
Oct 18 09:35:32 PM  ==> Running 'yarn start'
Oct 18 09:35:34 PM  yarn run v1.22.5
Oct 18 09:35:35 PM  $ node dist/index.js
Oct 18 09:35:37 PM  Server is running
Oct 18 09:35:40 PM  Your service is live 🎉
Oct 18 09:35:44 PM  ==> Detected service running on port 10000
Oct 18 09:35:44 PM  ==> Docs on specifying a port: https://render.com/docs/web-services#port-detection

Yours sounds like an advanced way to do it yet I only copied the folders from some guy who managed to create it by cloning them to my repo.

If I were to do what you suggested, I wouldn’t where to start since I have never worked with this kind of apps/folders before. The closes is working with at most three files, like the standalone Leaflet apps where you only need a .html, .css and .js file.

You merged commits in from my fork?
The build I got working was against your repo- I was just playing around on my side, so I don’t know that those changes will help you- likely they will cause confusion- I would revert them if I were you.

I merged your Github commit to mine and deployed it anew on Render using Create New Web Service rather than Create Static Site as before.

There’s confusion here. Your repo is in two parts, a client and a server. Your client is a react app and needs to be deployed as a static site with client as the root directory as we talked about before.

Your backend server needs to be deployed separately as a web service with server as the root directory, using those parameters in the screen shot I posted before. Both of those services should specify a NODE_VERSION (I can see from your logs that the default is still being used).

EDIT: I haven’t used the app so I can’t help you with the rewrite/redirect part and if it’s needed/what it’s doing, all I can do is spot-check what’s wrong with your build.

Hi Samual,

For react-location-share-web-service.onrender.com this is your server/backend, and you shouldn’t expect to see any more in your browser than you did. Your server code isn’t going to have your react app, and all you have for the / route handler is:

app.get('/', (req: Request, res: Response) => { res.send('Welcome to LocShare!')})

Which is exactly what you see. This is typical for a backend to have a very simple handler for /, just to check the service is up and running. So everything looks okay.

As Matt says, you must deploy your client/frontend as a static site.

Regards,

Keith
Render Support, UTC+10 :australia:

Hello Keith,

This thing must be taking me in circles. But first, good to know the BE is okay. I actually reverted to the original status before the commit of forking MgDales Github. Nevertheless, the results are the same text you saw on – react-location-share-web-service.onrender.com

You merged commits in from my fork?
The build I got working was against your repo- I was just playing around on my side, so I don’t know that those changes will help you- likely they will cause confusion- I would revert them if I were you.

Actually, once again, the server is here on a new link – https://share-location.onrender.com/ I tried reversing using git like a day later, was too much hustle compared to starting afresh.

I have uploaded the front-end client folder, and although I have done this one before, I would appreciate on how to go about it. I am doing considering MgDale’s comments, that client is the root directory (you will see it in the pic below). I just need to know what will go to the Publish Directory parameters since as I had mentioned earlier, there is no dist or other folder given as clues in the Publish Directory instructions, and I don’t want to open VS code to do the running to produce a dist as you mentioned to me (not arrogantly speaking but I wouldn’t even have a clue what I should do, this one is a complex project). But if I managed to get the web server running, I can get the FE too with some detailed help.

Here is the pic showing the FE parameters which I assume are in the client folder. Let me know what to tweak and others to make the front-end online like the back-end. Assuming this will be the final nail in the coffin.

Hi Samual,

Vite’s default output directory is dist: https://vitejs.dev/config/build-options.html#build-outdir. This is what you should use for your publish directory.

Regards,

Keith
Render Support, UTC+10 :australia:

To add: vite is a tool called a “bundler”. It’s taking your code and transforming it, but it doesn’t overwrite your code with the now transformed code, it puts that new code into the client/dist folder (if dist isn’t there, it will create it for you automatically). That’s why when you look at the git repo/file system you don’t see a dist folder yet- when you run yarn build, dist will be created.

When you specify the Publish Directory to be client/dist, the build (yarn build) process happens first, then the deployment process will look for the dist folder and publish that.

I tried to sum all the stuff we talked about in this thread into simpler, example repo deployment instructions, etc. Using Socket.io on render.com

It’s a little different since it’s not using vite, just the regular create react native app, but i think the deployment instructions are useful nonetheless, and for anyone else who lands in this thread trying to figure out socket.io.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.