Building A Photo Blog on Strapi Gatsby And Typescript: Part 4 Deployment

Now that I got a tolerable front end set up in part 3, I was ready to put this blog out there. Or at least figure out how to. There are a lot of options for deploying a Strapi app, in fact, having very little knowledge of this world, I found it a bit overwhelming.

I tried Render, attempting to avoid the big players AWS and Azure, where my dollars will likely only go to wipe Jeff Bezos and Bill Gate’s butts, respectfully (respectfully). I also chose Render because there’s a simple guide for Strapi with SQlite and uploads on disk. I popped in the env/production files they had and the YAML file with a few adjustments. I ran into an issue however, when trying to deploy via YAML, and got the dreaded “An error has occurred” error message. An un-debuggable, detail-less, dead-end of an error message. I posted in their slack for help, I suspect this has to do with my blog being split into frontend and backend folders and Render not knowing where to go.

Render’s backend YAML deploy failure
A recreation of my error on first deploy, you can check the logs from within the service for more details though

In less than 48 hours, I got a helpful message from the folks at Render. Thanks to David, I just needed to tweak some paths in my YAML because my front end and backend are in the same repo. My final YAML is below:

services:
- type: web
name: strapi
env: node
plan: starter
buildCommand: cd backend && yarn install && yarn build
startCommand: cd backend && rsync -a public/ /data/backend/public/ && yarn start
healthCheckPath: /_health
disk:
name: strapi-data
mountPath: /data/backend
sizeGB: 1
envVars:
- key: NODE_VERSION
value: 12.18.4
- key: NODE_ENV
value: production
- key: DATABASE_FILENAME
value: /data/backend/strapi.db
- key: JWT_SECRET
generateValue: true
- key: ADMIN_JWT_SECRET
generateValue: true

With the backend deployed on Render, how do I get my Gatsby front end up and running? The Render Gatsby docs are a little light on detail but now that I’ve dipped my toe in the Render pool, I think I can fandangle my way into getting this working. I know that I’ll need to tell Gatsby where my backend is now that its not just on localhost.

Gatsby front end logs page on render
Weirdly there is no tab for the logs here, you have to click the deploy failure in Events to get the logs

I’m using process.env.API_URL in gatsby-config.js and gatsby-node.js to tell Gatsby where the GraphQL calls should be made to build the pages, so I know I’ll need to set that. Setting environmental variables on Render is pretty easy, but I wasn’t sure whether to use the internal address or the “live address” for the API_URL. After getting a couple of time out errors on the internal address, I used the live address.

Backend live and internal addresses

I redeployed after setting the environment values and got a 403 error.

Dec 12 07:22:19 PM  Request failed with status code 403
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM Error: Request failed with status code 403
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM - createError.js:16 createError
Dec 12 07:22:19 PM [frontend]/[gatsby-source-strapi]/[axios]/lib/core/createError.js:16:15
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM - settle.js:18 settle
Dec 12 07:22:19 PM [frontend]/[gatsby-source-strapi]/[axios]/lib/core/settle.js:18:12
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM - http.js:202 IncomingMessage.handleStreamEnd
Dec 12 07:22:19 PM [frontend]/[gatsby-source-strapi]/[axios]/lib/adapters/http.js:202:11
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM - node:events:388 IncomingMessage.emit
Dec 12 07:22:19 PM node:events:388:22
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM - readable:1295 endReadableNT
Dec 12 07:22:19 PM node:internal/streams/readable:1295:12
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM - task_queues:80 processTicksAndRejections
Dec 12 07:22:19 PM node:internal/process/task_queues:80:21
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM
Dec 12 07:22:19 PM not finished source and transform nodes - 0.176s
Dec 12 07:22:19 PM ==> Build failed 😞

403 means access forbidden, Of course, because I hadn’t set my roles and permissions in my live Strapi app to be public for viewing and counting. Now I get past the 403 error, but now I’m getting a time out error.

c 12 07:57:31 PM  info Starting to fetch data from Strapi - strapi-wsb7:10000/photos?_limit=1000
Dec 12 07:57:31 PM info Starting to fetch data from Strapi - strapi-wsb7:10000/tags?_limit=1000
Dec 12 07:59:42 PM success Fetched Strapi Data - 130.802s
Dec 12 07:59:42 PM error "gatsby-source-strapi" threw an error while running the sourceNodes lifecycle:
Dec 12 07:59:42 PM
Dec 12 07:59:42 PM connect ETIMEDOUT 0.0.39.16:80
Dec 12 07:59:42 PM
Dec 12 07:59:42 PM
Dec 12 07:59:42 PM Error: connect ETIMEDOUT 0.0.39.16:80
Dec 12 07:59:42 PM
Dec 12 07:59:42 PM - node:net:1138 TCPConnectWrap.afterConnect [as oncomplete]
Dec 12 07:59:42 PM node:net:1138:16
Dec 12 07:59:42 PM
Dec 12 07:59:42 PM
Dec 12 07:59:42 PM not finished source and transform nodes - 130.878s
Dec 12 07:59:42 PM ==> Build failed 😞

Time out on getting Strapi data? That might be because there are no tags to fetch. I added a tag content type… but still got the same error. Here I switched to the live Strapi URL for my API_URL. This got me closer to deployment, but another error popped up.

Dec 12 08:10:47 PM  error There was an error in your GraphQL query: 
Dec 12 08:10:47 PM Cannot query field "tags" on type "StrapiPhoto".

Why can’t I query tags on StrapiPhoto? I didn’t have any tag content types connected to any photoes in the live Strapi site, so I added a tag in the live backend to a test photo. This again moved the needle closer to full deployment.

success run page queries - 0.107s - 5/5 46.55/s
Dec 12 08:24:56 PM success write out requires - 0.019s
Dec 12 08:25:12 PM failed Building production JavaScript and CSS bundles - 15.255s
Dec 12 08:25:12 PM error Generating JavaScript bundles failed
Dec 12 08:25:12 PM
Dec 12 08:25:12 PM Can't resolve '../components/photoDesc' in '/opt/render/project/src/frontend/src/templates'
Dec 12 08:25:12 PM
Dec 12 08:25:12 PM If you're trying to use a package make sure that '../components/photoDesc' is installed. If you're trying to use a local file make sure that the path is correct.
Dec 12 08:25:12 PM not finished Generating image thumbnails - 15.890s

Why can’t I import the component with the relative path? Why in the production environment does the “..” not get respected? I can import the <PhotoDesc> component locally.

Because that’s not the issue. The real issue is the same one I had back in part 1 of this build a blog journey. Capitalization. ../components/photoDesc is not ../components/PhotoDesc and Render (Linux really) won’t let me get away with sloppy camelCase. At least I’m not the only schmuck with this problem. There’s an open PR on Typescript for exactly this issue.

With that, my site is finally live on https://gatsby-frontend.onrender.com/!

Woohoo!!

There’s a couple more things I need to do. Right now, my Gatsby site only updates if I redeploy, not whenever I update my Strapi backend. If I add a new photo or update a description I want my live site to update with the new data. I need to add web hooks for Strapi and for Render. This was really easy, all in the Strapi and Render dashboards.

I’d also like to have a tolerable URL, no offense to the “onrender.com” fans. I jumped over to my favorite DNS provider, got locked out of my account, had a chat with customer service, then updated the A Record and CNAME record and after a little bike ride tayloredtotaylor.xyz is live.

Developer. Musician. Naturalist. Traveler. In any order. @tayloredtotaylor

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store