Before you go, check out these stories!

Hackernoon logoDockerizing and Deploying Nuxt.js SSR Apps To AWS ECS by@melvinkcx2

Dockerizing and Deploying Nuxt.js SSR Apps To AWS ECS

Author profile picture

@melvinkcx2Melvin Koh

Software Engineer. Pythonista, JavaScripter. Find me on Twitter @melvinkcx2 ๐Ÿ˜

For the past few hours, I've been working on dockerizing a Nuxt.js server-side rendering app to be deployed to AWS Elastic Container Service (ECS). I hit a stone wall when environment variables are not properly injected on runtime on ECS.

In this post, I will walk us through steps to properly dockerize Nuxt.js SSR apps and share some of the lessons I learnt.

There are 2 major ways to dockerize Nuxt.js apps, and each of them has its shortcomings:

1. Nuxt build on run: The Nuxt app is built after Docker image is built, when the container is spawned. The downside of this is the container boot time takes significantly longer as it involves building the artifacts on run. This also violates the build/release/run principle of a 12-factor app.

2. Nuxt build on Docker build: For this, sensitive environment variables are injected during

docker build
stage. The upside is the boot time is much shorter now, hence, quicker revert time in case you need to revert to an older version. However, the downside is the sensitive variables are now bundled into our Docker image and it requires a rebuild every time a variable is updated.

For this post, I will be using the first method, "Nuxt build on run".

How environment variables works in Nuxt.js apps?

Let's revisit how environment variables work in Nuxt apps. Some of us may already be familiar with the

property in
, which allows us to inject sensitive values from your terminal environment to the app on runtime.

// in nuxt.config.js

export default {
  env: {
      * dbUri is accessible from both client and server side.
    dbUri: process.env.DB_URI  

From the snippet above,

is read and injected to
when we run the app for any purpose. (
nuxt start
nuxt build

When serving a production build, our environment variables are most likely different from environment to environment. Thus, if we build our app (
nuxt build
) as part of the building steps of our Docker image, any sensitive environment variables that is injected when we run our Docker image (
docker run ...
) will not work as the artifact has been built before these variables are injected.

How to safely inject environment variables into Dockerized Nuxt.js on runtime?

By adopting "Nuxt build on run", we adhere to:

Principle 1: Build and serve on runtime!
Principle 2: Never embed any sensitive value in Dockerfile
  "scripts": {
    "build": "nuxt build --modern=server",
    "start": "nuxt start",
    "prod": "yarn build && yarn start"

To serve a production build, all we need to do is to run

yarn prod

In my


FROM node:10.16.3


COPY . ./
RUN yarn install

ENV HOST   # Insensitive environment variable


CMD ["yarn", "prod"]

Here we go! Our dockerized Nuxt app is ready.

We can run our Docker image using

docker run
or alternatively with Docker Compose. I personally use Docker Compose a lot. In my case, I created a
that inject environment variables from the
file in same directory.



version: "3"
    build: .
    restart: always
      - .env
      - "3000:3000"

Once ready, we run

 docker-compose -f docker-compose.production.yml up -d
to bring up our containerized Nuxt app.

How to safely inject environment variable for dockerized Nuxt.js on AWS ECS

This section is only applicable if you choose ECS as your deployment platform of choice.

In this section, I will walk us through:

  • storing sensitive values using AWS SSM Parameter Store
  • building and pushing image to image registry
  • creating an ECS task

Step 1: Storing Sensitive Environment Variables in Parameter Store

AWS provides several products for the purpose of storing sensitive configurations, namely AWS SSM Parameter Store and AWS Secrets Manager. I use Parameter Store because of its' free 10,000 Standard tier parameters.

To add a parameter, click "Create Parameter" in the Parameter Store Management Console:

Fill up the form, then submit:

We should see the parameters created:

We will leave the parameters created for now. These will be consumed in a latter step.

Step 2: Building and Pushing Image to Image Registry

To deploy our Nuxt.js app to AWS ECS, we first require a repository
to store our Docker image. For the sake of simplicity, I use AWS Elastic
Container Registry (ECR).

The official guide provides a comprehensive list of steps to create a repository on AWS ECR.

Once the image repository is created, we can then build and push our image:

$(aws ecr get-login --no-include-email --region <region>) 

docker build -t <image_name> . 

docker tag <image_name>:latest <remote_repository_url>

docker push <remote_repository_url>

Navigating to our repository with AWS Management Console, we should see our image pushed:

Step 3: Create an ECS Task

This guide details the steps to create a Task definition in ECS. It is highly suggested to read this if you are not familiar with the concepts of Task and Service in ECS before moving forward.

While creating an ECS Task with the Management Console, you can now
reference to parameters created in SSM Parameter Store by using the ARN
of the parameters.

Once the Task is created, we can then run it on ECS. Navigating the the
endpoint of your Task, you should be able to see your app is up and


Now we have a dockerized Nuxt.js SSR app that is running on ECS with
sensitive environment variables stored on SSM Parameter Store.

Have fun hacking around!

This was first published on
Author profile picture

@melvinkcx2Melvin Koh

Read my stories

Software Engineer. Pythonista, JavaScripter. Find me on Twitter @melvinkcx2 ๐Ÿ˜


Join Hacker Noon

Create your free account to unlock your custom reading experience.