ADHD Dev Journal: Serverless Next.js

Doing a little catching up on the weekend, trying to get this demo site working for a hackathon. My preferred stack is nextjs + prisma. I’ve always deployed it on Vercel before, but at my current company we use AWS directly and extensively. I am finally trying out the serverless tool for deploying apps, and it has not been the easy straightforwrad experience I hoped for.

First, I needed to sort out the authentication thing, and of course a big corporate IT organization manages their AWS access in a very particular way, which was a little confounding to me coming from the startup - quick and dirty way of doing things.

Second was the fact that I was using a newer configuration thing called “serverless components“ and specifically the one for NextJS which is supposed to take all the config for a nextjs app and abstract it into a single line with good defaults.

Unfortunately I ended up running into an edge case because the client binaries for Prisma are not copied into the deployment package that is uploaded to AWS Lambda. There is an example workaround in this repo config which almost worked. But for some reason I had to copy the client files directly into the root of my deployment directory, otherwise Prisma couldnt find it and I would get errors int the logs like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ERROR   PrismaClientInitializationError3 [PrismaClientInitializationError]: Query engine binary for current platform "rhel-openssl-1.0.x" could not be found.
This probably happens, because you built Prisma Client on a different platform.
(Prisma Client looked in "/var/task/chunks/query-engine-rhel-openssl-1.0.x")

Searched Locations:

/.prisma/client
/Users/tim/granular/csf-portal-next/node_modules/@prisma/client
/var/task
/var/task/chunks
/var/task/chunks
/tmp/prisma-engines
/var/task/chunks

You already added the platforms "darwin", "rhel-openssl-1.0.x" to the "generator" block
in the "schema.prisma" file as described in https://pris.ly/d/client-generator,
but something went wrong. That's suboptimal.

Please create an issue at https://github.com/prisma/prisma/issues/new
at cb (/var/task/chunks/930.js:36253:17)

[truncated]

Anyway, you see this is a big pain and it requires customizing the serverless config with custom shell scripts. And if there’s one thing I’ve learned it’s that writing shell scripts in .yml files is sign that things are going off the rails in a bad way.

Here’s my serverless config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
myNextApp:
component: "@sls-next/serverless-component@3.3.0"
inputs:
build:
env:
DATABASE_URL: ${env.DATABASE_URL}
postBuildCommands:
- PDIR=node_modules/.prisma/client/;
LDIR=.serverless_nextjs/api-lambda/;
if [ "$(ls -A $LDIR)" ]; then
cp "$PDIR"query-engine-rhel-* $LDIR;
cp "$PDIR"schema.prisma $LDIR/chunks/;
fi;
- PDIR=node_modules/.prisma/client/;
LDIR=.serverless_nextjs/default-lambda/;
if [ "$(ls -A $LDIR)" ]; then
cp "$PDIR"query-engine-rhel-* $LDIR;
cp "$PDIR"schema.prisma $LDIR/chunks/;
fi;

This puts the files in the place that prisma is looking for them on the lambda.

Of course you still need to make sure your project can actually access your database and is in the same VPC with the lambdas. There is no end to the configuration power you have with AWS, but, I heartily recommend just using Vercel and some publicly accessible hosted Postgres Database.

Or maybe I should have just used a serverlss configuraiton that put a Create-React-App build into an S3 bucket and a seperate Express API on a lambda instead of trying to put them together into a single project. My current approach could be an example of too much magic again.

AWS security roles are such a pain to deal with. It’s after midnight now but I feel like I really accomplished something. A NextJS application deployed on lambdas and cloudfront, where the API handlers connect to a postgres database using Prisma DB client. Was that so much to ask for? Apparently it is. Tomorrow I’ll probably just scrap the whole thing and put it on a plain EC2 instance. But this CI deployment script should be super simple compared to what it would take to deploy a whole next app to a EC2 instance. npm ci && npx serverless