Self-host on Heroku

Tl;dr - follow this Gist to get RedwoodJS running on Heroku.

I’ve got a basic guide for running RedwoodJS on Heroku. Not sure how much of this is going to change over time as Redwood evolves, but the basic approach is something like this:

  1. Add a build script to the root package.json rw build
  2. Have a release phase that runs yarn rw db up
  3. Have a modified pm2 script that fires up the api-server using a UNIX Socket (because that’s what Heroku lets you work with when you want to run multiple backends from a single frontend Nginx server) and signals to Heroku’s NGINX buildpack that the app has started successfully
  4. Use the Heroku NGINX buildpack and point it at that unix socket, and the build web HTML

Feedback welcome here or on the Gist to keep it up to date!

4 Likes

Nice work! :clap:

Not sure if you have see the deploy script for aws_serverless:

Deploying via AWS Serverless assumes that you have setup the credentials for the Serverless Framework on your computer. In order to setup your Redwood project to use AWS Serverless run: yarn rw generate deploy aws_serverless

Once that’s complete you can invoke a deployment via: yarn rw deploy api aws_serverless. This command will take care of building, packaging, and shipping your AWS Serverless functions.

But might a deploy provider of heroku be possible based on your work?

It’s be great to have multiple deploys that are easy to setup and … well … deploy :slight_smile:

Thanks for this!

Great idea - I was working on just getting my own project up and running, but a deployment provider would operationalize the manual steps outlined in my gist!

A few things off the top of reading the code for deployment providers:

  1. We’d need a way to move @redwoodjs/core from being a dev to prod dependency in the root package.json as part of the deploy provider. This enables running db up as part of the release phase in Heroku, which happens after dev dependencies have been pruned. I’d love feedback on the best way to tackle this.
  2. We’d need a way to add pm2 to the root package.json - looks like only the api workspace can get packages added in a deploy step. I’m tempted to remove the pm2 dependency, and use child_process or a bash script to start the redwood app and, once running, touch the file necessary to signal to the NGinx buildpack that our app is running. I’d love thoughts on this as well.
  3. We’d need a way to add the build script to package.json. No way around that, unless yarn build automatically maps to rw build in a vanilla Redwood project and I missed that.

Welcome anywhere I’m missing something, as I’m very new to Redwood as a whole.

1 Like

Awesome really helpful gist :smile:

I think a golang or rust process manager would be equally in keeping with Redwood’s philosophy - use the right tool for the job. Prisma uses rust. Perhaps the deploy setup could let you pick from several options.

1 Like

The only reason I have a process manager in there is so that once the app boots up we can signal to Heroku’s NGINX buildpack that we’re ready for traffic. It expects your app to touch /tmp/app-initialized. Using PM2 was lazy on my part, an even better approach would be to rely on something like child_process.fork() and dropping the PM2 dependency entirely.

I’m using a setup that’s very similar to this, but I’m running into issues with the v1-rc release of RW. Has anyone else here tried to upgrade?

This is the error I’m seeing

2021/12/04 13:40:30 [error] 244#0: *13 connect() to unix:/tmp/nginx.socket failed (11: Resource temporarily unavailable) while connecting to upstream, client: 172.17.0.1, server: _, request: "POST /api/graphql HTTP/1.1", upstream: "http://unix:/tmp/nginx.socket:/graphql", host: "app.example.tld", referrer: "https://app.example.tld/"