Deploying your node backend [Express / Koa] in AWS Lambda
GitHub link: https://github.com/chenchunaidu/koa-lambda-template
Why do we need to deploy your node backend application on AWS Lambda?
There are many ready-made options like vercel, netlify to deploy frontend applications on the cloud. We also have free services like Heroku (Not free anymore), and fly.io but the capacity of the free machine is limited only. AWS lambda is a free alternative for deploying your nodejs application on the cloud.
Setting up the Koa application
In this demo project, we are going to use koa as the node backend framework along with typescript.
Tech stack
Koa + Typescript
Prisma [Node ORM]
Serverless http [For converting your node application into lambda]
Create a node package
mkdir myapp
cd myapp
npm init -y
Install required dependencies
npm install koa koa-bodyparser koa-jwt @koa/cors @prisma/client prisma serverless-http dotenv koa-router
Install required dev dependencies
npm install -D @types/koa @types/koa__cors @types/koa__router @types/koa-bodyparser @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser esbuild eslint nodemon ts-node typescript @types/koa-router
Folder structure
# create new folder called src inside your myapp folder
mkdir src
cd src
# create two new files called index.ts and router.ts
touch index.ts
touch router.ts
Copy and paste the following code into the index.ts
file
import ServerlessHttp from "serverless-http";
import cors from "@koa/cors";
import koa, { Context } from "koa";
import bodyParser from "koa-bodyparser";
import router from "./router";
import * as dotenv from "dotenv";
import { PrismaClient } from "@prisma/client";
dotenv.config();
// create prisma client
const prisma = new PrismaClient();
// initialize app
const app = new koa();
app
.use(cors())
.use(bodyParser())
.use(async (ctx: Context, next) => {
ctx.prisma = prisma;
await next();
})
.use(router.routes())
.use(router.allowedMethods());
app.listen(3000, () => {
console.log("app listening on port 3000");
});
Copy and paste the following code into the router.ts
file
import Router from '@koa/router';
const router = new Router();
router.get("/api", (ctx, next) => {
ctx.body = "Hello world";
});
export default router;
Initialize the Prisma
npx prisma init --datasource-provider sqlite
The above command will create a file prisma/schema.prisma
add the following code to schema.prisma
file
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
Enter the following command to migrate your schema
npx prisma migrate dev --name init
Add the following line to your package.json
scripts. By adding start:dev
to your package.json
scripts you can use npm run start:dev
to run your application
"scripts": {
"build-esbuild": "rm -rf dist && esbuild ./src/index --entry-names=[dir]/[name]/index --bundle --minify --sourcemap --platform=node --target=node14.14 --outdir=dist",
"build": "npm run build-esbuild && npm run copy-prisma-schema && npm run zip", // for building your application
"start:dev": "nodemon --ignore tests/ --watch src -e ts,tsx --exec ts-node src/index.ts",
"copy-prisma-schema": "cp -r prisma/schema.prisma dist/index", // for copying your prisma schema
"zip": "zip -r sam/dist.zip dist/" // for zipping your application
},
run the following command to start your application
npm run start:dev
Now the application will be running on localhost:3000 go to http://localhost:3000 to check your application
Converting your application serverless
currently, your application is served through HTTP to convert it into a lambda function we will use serverless-http package.
install serverless-http npm package by entering the following command in terminal
npm i serverless-http
In the index.js file, change listen app.listen
code with the following code
The following code will convert your application into a lambda function
export const handler = ServerlessHttp(app);
Building application
run the following command to build your application
npm run build
npm run build will run the following 4 commands
npm run build-esbuild
- this will build your package along with all node module dependencies.
npm run copy-prisma-schema
- copies your Prisma schema into your build folder
npm run zip
- Compresses your build folder into zip format and copy it into the sam folder
Setup with AWS SAM
Install AWS sam in your local machine by following the steps in this documentation
AWS sam installation documentation
Create a folder inside the root folder and create a file called template.yaml
inside it
copy the following YAML config into your template.yaml
file
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Resources:
EasySchoolBackendFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./dist.zip
Handler: dist/index/index.handler
Runtime: nodejs14.x
Timeout: 900
PackageType: Zip
Events:
ApiEvent:
Type: Api
Properties:
Path: /{any+}
Method: ANY
now cd into your sam folder and sam build and sam local start-API
cd sam
sam build # builds sam
sam local start-api # start local api
now go to http://localhost:3000/api to check your application.
CI/CD setup
Create a file called deploy-lambda.yaml
inside .github/workflows
folder and copy and paste the following code into it
touch .github/workflows/deploy-lambda.yaml
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
name: Node.js Package
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
- run: npm ci
- run: npm run build
- uses: aws-actions/setup-sam@v2
- uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-south-2
- run: |
cd sam
sam build --use-container
# Prevent prompts and failure when the stack is unchanged
- run: |
cd sam
sam deploy --no-confirm-changeset --no-fail-on-empty-changeset
now add the following secrets to your GitHub account
following these steps to create access keys if you don't have it already
https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/
AWS_ACCESS_KEY_ID (Your AWS access key)
AWS_SECRET_ACCESS_KEY (Your AWS secret access key)
Subscribe to my newsletter
Read articles from chenchunaidu maddineni directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by