Skip to content

Express on AWS with SST

Create and deploy an Express app to AWS with SST.

You can use SST to deploy an Express app in a container to AWS. It uses Fargate and ECS.

We’ll build a simple app below.


Examples

We also have a few other Express examples that you can refer to.


We are going to build a hit counter using Express and Redis. We’ll the deploy it to AWS in a container.

Before you get started, make sure to configure your AWS credentials.


1. Create a project

Let’s start by creating our Express app.

Terminal window
mkdir aws-express && cd aws-express
npm init -y
npm install express

Init Express

Create your app by adding an index.mjs to the root.

index.mjs
import express from "express";
const PORT = 80;
const app = express();
app.get("/", (req, res) => {
res.send("Hello World!")
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});

Init SST

Now let’s initialize SST in our app.

Terminal window
npx sst@latest init
npm install

This’ll create a sst.config.ts file in your project root.


2. Add a Cluster

To deploy our Express app, let’s add an AWS Fargate container with Amazon ECS. Update your sst.config.ts.

sst.config.ts
async run() {
const vpc = new sst.aws.Vpc("MyVpc", { bastion: true });
const cluster = new sst.aws.Cluster("MyCluster", { vpc });
cluster.addService("MyService", {
loadBalancer: {
ports: [{ listen: "80/http" }],
},
dev: {
command: "node --watch index.mjs",
},
});
}

This creates a VPC with a bastion host, an ECS Cluster, and adds a Fargate service to it.

The dev.command tells SST to instead run our Express app locally in dev mode.


3. Add Redis

Let’s add an Amazon ElastiCache Redis cluster. Add this below the Vpc component in your sst.config.ts.

sst.config.ts
const redis = new sst.aws.Redis("MyRedis", { vpc });

This shares the same VPC as our ECS cluster.


Now, link the Redis cluster to the container.

sst.config.ts
cluster.addService("MyService", {
// ...
link: [redis],
});

This will allow us to reference the Redis cluster in our Express app.


Install a tunnel

Since our Redis cluster is in a VPC, we’ll need a tunnel to connect to it from our local machine.

Terminal window
sudo npx sst tunnel install

This needs sudo to create a network interface on your machine. You’ll only need to do this once on your machine.


Start dev mode

Start your app in dev mode.

Terminal window
npx sst dev

This will deploy your app, start a tunnel in the Tunnel tab, and run your Express app locally in the MyServiceDev tab.


4. Connect to Redis

We want the / route of our API to increment a counter in our Redis cluster. Let’s start by installing the npm package we’ll use.

Terminal window
npm install ioredis

Add the relevant imports to your index.mjs.

index.mjs
import { Resource } from "sst";
import { Cluster } from "ioredis";
const redis = new Cluster(
[{ host: Resource.MyRedis.host, port: Resource.MyRedis.port }],
{
dnsLookup: (address, callback) => callback(null, address),
redisOptions: {
tls: {},
username: Resource.MyRedis.username,
password: Resource.MyRedis.password,
},
}
);

Let’s update the / route.

index.mjs
app.get("/", async (req, res) => {
const counter = await redis.incr("counter");
res.send(`Hit counter: ${counter}`);
});

Test your app

Let’s head over to http://localhost:80 in your browser and it’ll show the current hit counter.

You should see it increment every time you refresh the page.


5. Deploy your app

To deploy our app we’ll first add a Dockerfile.

Dockerfile
FROM node:18-bullseye-slim
WORKDIR /app/
COPY package.json /app
RUN npm install
COPY index.mjs /app
ENTRYPOINT ["node", "index.mjs"]

This just builds our Express app in a Docker image.

Let’s also add a .dockerignore file in the root.

.dockerignore
node_modules

Now to build our Docker image and deploy we run:

Terminal window
npx sst deploy --stage production

You can use any stage name here but it’s good to create a new stage for production. This’ll give the URL of your Express app deployed as a Fargate service.

Terminal window
Complete
MyService: http://jayair-MyServiceLoadBala-592628062.us-east-1.elb.amazonaws.com

Connect the console

As a next step, you can setup the SST Console to git push to deploy your app and monitor it for any issues.

SST Console Autodeploy

You can create a free account and connect it to your AWS account.