In this article, we’re going to go over how to deploy your Prisma API for production use for your sites and apps. For the purposes of this article, we’ll be making use of Prisma Cloud and Heroku to deploy our service.
Prerequisites
You’ll need a basic Node.js-based Prisma GraphQL application, which you can clone from this boilerplate repo here. Just remember to move into the prisma folder and start a new Docker container.
$ npm install $ docker-compose up -d $ prisma deploy
You’ll also need to know how to setup and connect to your Postgres database in Heroku, which you can brush up on here.
This affiliate banner helps support the site 🙏
Installation
The only new thing you’ll need is env-cmd
, since we’re going to be reconfiguring some variables to be different in development vs production mode.
Creating a Prisma Service
For hosting our Prisma container, as we had on port 4466
, we’re going to be using Prisma Cloud. Once you’ve logged in using your Github account, on the Servers
page you’ll be able to start with ADD SERVER
.
Once you’ve named your server it’ll walk you through a few steps. Create a new database, connect it to your Heroku account, and set it as a PostgreSQL-type database. Creating the Server will be a similar process.
Now if you look at your Heroku account you should see your new database already added. Like before, we’ll grab our Postgres credentials and add them to our projects docker-compose.yml
file.
Prisma Configuration
Currently, our configuration is looking at localhost:4466
(or your docker ip), which isn’t where our new server is. We don’t want to hard code either as our endpoint since we’ll want to transition between them.
We’re going to do this by creating two .env
files, each with a different endpoint and we’ll tell Prisma which to use when we want to do anything.
prisma.yml
endpoint: ${env:ENDPOINT} datamodel: datamodel.graphql
dev.env
ENDPOINT=http://192.168.99.101:4466/ #Or http://localhost:4466 on Mac
Now when you run prisma deploy
if you use the -e
flag you can specify where which env file you wish to use is. So prisma deploy -e ./dev.env
should work just like before.
We can get our server endpoint by using our empty prod.env
file, which should open a helpful little interface to create our service and connect it to your server, which for me is alligator-example
.
Once you name your service and set the stage to prod
you should be able to see your new service over at Prisma Cloud.
Even cooler, now if you look back at prisma.yml
you’ll see a new services endpoint added to the file, which we can take and move over to the production env file.
prod.env
ENDPOINT=https://alligator-example-342bdfs2.herokuapp.com/alligator-prisma-example/prod
Now we can use our environment variable trick to easily move between testing the dev and production databases.
Node.js Configuration
Prisma is only one half of our application, we still need a way for Node to access either the production or development servers and databases. Our first step is to change any references to our local container into an environment variable, just like we did in the Prisma config.
prisma.js
const prisma = new Prisma({ typeDefs: 'prisma/generated.graphql', endpoint: process.env.ENDPOINT })
Now, we need to reconfigure our scripts for Heroku and have them look for our env
files before doing anything.
Let’s move everything from the start
script into a new dev
script and use env-cmd
to point it to the dev.env
file. We’ll use start
as our production script since that’s what Heroku uses by default. The only difference from dev
is that it uses the prod.env
file, uses Node instead of nodemon, and looks for the bundled version of our app.
One problem, Heroku doesn’t know how to handle our unprocessed code without Babel, so we need to add a postbuild process to build out our app into something more usable and direct our start script to that. heroku-postbuild
just bundled everything in src
into a separate dist
folder.
package.json
{ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "get-schema": "graphql get-schema -p prisma", "start": "env-cmd ./prisma/prod.env node dist/index.js", "heroku-postbuild": "babel src --out-dir dist --copy-files", "dev": "env-cmd ./prisma/dev.env nodemon src/index.js --ext js,graphql --exec babel-node" }, }
For me, env version 9.0+ gave me consistent problems, although 8.0.2 works fine. You might want to try downgrading if you encounter any persistent issues.
Finally, we need to make a slight tweak to which port our graphql-yoga server is starting on. We want it to use either the port given by Heroku or a default for local development.
index.js
const port = process.env.PORT || 3000 server.start(port, () => console.log('server running'))
Now when you connect this repo to Heroku it should automatically deploy your API as a GraphQL playground that anyone can access.
Closing Thoughts
Prisma has easily become my favorite way of working with databases, but since it’s so new there still isn’t much support in other cloud hosting services like AWS or Google Cloud. Still, it’s better to get comfortable with it now since Prisma will only become more common and powerful as other services start supporting it.