Dockerize your Nuxt App

clock icon June 20, 2020

In this article, we’ll look at how to dockerize a nuxt app. We’ll create a nuxt app using create-nuxt-app and containerize it with Docker for both development and production environments.


What is Docker?

Docker logo: dockerize nuxt app

Docker is a software platform that simplifies the process of developing, running and distributing applications by creating a virtual environment of the operating system where it is being run.

It eliminates the age-old issue of “it works on my machine.” Docker works by putting together every required piece of software architecture/library that is required by the application on containers. In the end, developers only need to have docker installed on their system to be able to run the application.

If you are new to docker, freecodecamp has an amazing introduction to the subject that you can check out.


Installing Docker

To install Docker, follow the instructions on their website. It contains all the instructions needed to set it up on your local machine.


Creating the Nuxt App

We will use create-nuxt-app to quickly scaffold a nuxt app. Simply accept the defaults and install the necessary dependencies. Once set up, you can start writing your Dockerfile.


Dockerize Nuxt App in Development Environment

During development, we want to have things like hot-reloading available so we can quickly see changes we make to our nuxt app. Create a new file in the root of your project called Dockerfile (with no extension) and add the following contents:

FROM node:10-alpine
WORKDIR /app
COPY package.json ./app
COPY . /app
RUN npm install
EXPOSE 3000

ENV NUXT_HOST=0.0.0.0
ENV NUXT_PORT=3000

What’s happening here?

  • We pull docker’s node image which will basically allow us to run node/npm commands in docker
  • We set our working directory (/app)
  • We copy over package.json as well as every other folder/file to the /app directory in docker
  • Then install project dependencies
  • Lastly, we expose port 3000 on the container


We’ll use docker-compose to spin up our container so create a new file called docker-compose.yml and add the following contents:

version: '3'
services:
  app:
    container_name: app
    command: npm run dev
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - '3000:3000'
    volumes:
      - .:/app
      - /app/node_modules/

We specify the name of our container (app) and the command to start the app (npm run dev). In the build section, we specify the path to the Dockerfile. We bind the container’s port (3000) to our device’s port (3000). We mount the app folder as well as node_modules (this is important else node_modules will be overwritten at runtime).

Start the docker container like so:

docker-compose up -d --build

Once it’s done setting up, navigate http://localhost:3000 to confirm that the app is running successfully. You can make a change to any file and confirm that hot-reload also works.


Dockerize Nuxt App in Production Environment

In production, we don’t need hot reloading and other functionalities provided by the development server. Create a separate docker file for the production environment called Dockerfile.prod and add the following:

FROM node:lts-alpine as build-stage
WORKDIR /app

COPY package.json ./
RUN npm install
COPY . .

RUN npm run generate

# production environment
FROM nginx:1.16.0-alpine
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

The first part of the snippet above looks quite similar to the docker file in the previous section with a few differences. The first difference appears on the first line at as build-stage. Here, we take advantage of the multistage build pattern which essentially creates a temporary image which is used to build the nuxt static files that are then copied to the production image. We run npm run generate which basically generates a static copy of the app that can be hosted on any static hosting service. This outputs a dist folder with all the necessary files needed to deploy the app.

The second part of the snippet copies the output from the build-stage (dist), stores in /usr/share/nginx/html and discards the temporary image. In production, we’ll be using Nginx to serve the application so we pull the docker image. We expose port 80 on our container and set the CMD to start the Nginx server.

Create a docker-compose file for production called docker-compose.prod.yml. Add the following code:

version: '3'
services:
  nuxt_app_prod:
    container_name: nuxt_app_prod
    build:
      context: .
      dockerfile: Dockerfile.prod
    ports:
      - '8080:80'

We bind the container’s port 80 to our machine’s port 8080. Fire up the container like so:

docker-compose -f docker-compose.prod.yml up -d --build

Once it’s done building, you can navigate to http://localhost:8080 to view the app.


Conclusion

In this article, we’ve looked at how to use dockerize our Nuxt app in a development environment as well as in a production environment. If you are new to docker, you can look through this gentle introduction to docker by freecodecamp. You can check out the source code as well to compare notes.

If you found this article helpful, do share with your network and feel free to go through other awesome content on codesource.io.