I’ve been working on a small side project, more on that later, and wanted a straight forward way to deploy a serverless full-stack app. I’m using Ember.js as the front-end framework and the back-end is AWS, Amazon Web Services, Lambda and other AWS services. This post describes the minimal setup to deploy a full-stack app with Ember.js and a Lambda API endpoint.

We’re going to create a simple hello world Ember.js app that is deployed to AWS with Serverless Stack, SST, and uses a hello API endpoint. There are lots of good docs on SST at https://docs.sst.dev. We’ll use the ‘Get Started’ instructions to create the SST project and then add our Ember.js app to it.

You’ll need an AWS account and AWS credentials configured locally. We’ll use pnpm but you could also use npm or yarn. The finished app is available on github.

Create a new app

pnpm create sst ember-sst-example

Start your local dev environment.

pnpm install && pnpm sst dev

This will print the URL of your API endpoint to the console similar to https://random-string.execute-api.us-east-1.amazonaws.com.

Add an Ember.js app.

cd packages
pnpx ember-cli new web --lang en --skip-npm --skip-git
pnpm install

We’ll remove the ember-cli-sri package from the ember app as it’s not working with the SST cloudfront deployment. In future ember releases, ember-cli > 5, it’s likely the following step won’t be needed. If it fails don’t worry.

cd web && pnpm remove ember-cli-sri

stacks/MyStack.tsc

-import { StackContext, Api } from "sst/constructs";
+import { StaticSite, StackContext, Api } from "sst/constructs";

export function API({ stack }: StackContext) {
  const api = new Api(stack, "api", {
    routes: {
      "GET /": "packages/functions/src/lambda.handler",
    },
  });

+ const web = new StaticSite(stack, "web", {
+   path: "packages/web",
+   buildOutput: "dist",
+   buildCommand: "pnpm build",
+   environment: {
+     EMBER_APP_API_URL: api.url,
+   }
+ });
+
  stack.addOutputs({
    ApiEndpoint: api.url,
+   Website: web.url,
  });
}

Config the Ember.js app to use the API.

packages/web/config/environment.js

const ENV = {
+  apiUrl: process.env.EMBER_APP_API_URL,

packages/web/ember-cli-build.js

const app = new EmberApp(defaults, {
- // Add options here
+ storeConfigInMeta: false,
});

Start the ember app locally and bind SST to it.

cd packages/web
pnpm sst bind ember s

Remove the Ember.js welcome page and fetch the welcome from the hello endpoint.

packages/web/app/routes/application.js

import Route from '@ember/routing/route';
import config from 'web/config/environment';

export default class ApplicationRoute extends Route {
  async model() {
    let response = await fetch(config.apiUrl);
    return response.json();
  }
}

packages/web/app/templates/application.hbs

{{page-title "Web"}}

{{this.model.body}}

{{outlet}}

You should see the API hello message rendered by the Ember.js app.

Deploy to production.

pnpm sst deploy --stage prod

Congratulations you just deployed your app! The Website URL will be printed to the console.

Clean up

To cleanup your AWS resources you can remove the development environment and the production environment.

pnpm sst remove
pnpm sst remove --stage prod