Table of Contents

Nuxt 3 - Running and Deploying with Docker Compose

nuxt-docker-nginx

Learn how to setup and deploy a Nuxt 3 application using Docker Compose and Nginx in this tutorial.

Tags: Nuxt 3, Docker Compose, Nginx

Estimated reading time: 6 minutes

Prerequisites

  • Basic knowledge of the command line
  • Install Node.js version 16.0 or later
  • Install Docker and Docker Compose. The simplest way is through Docker Desktop, which includes both. Follow the installation guide here.

Setting Up a Nuxt 3 App

If you already have a Nuxt 3 app, skip this step and proceed to the next section.

Otherwise, create a new Nuxt 3 app using the following commands:

npx nuxi init nuxt3-app
cd nuxt3-app
npm i
npm run dev

Visit your app at http://localhost:3000/

Writing a Dockerfile for the Nuxt App

With a Nuxt app in place, we now need a Dockerfile to containerize the application for deployment with Docker Compose.

Create a new file named Dockerfile and add the following contents:

FROM node:lts as build-stage

WORKDIR /nuxtapp

COPY . .

RUN npm install

RUN npm run build

RUN rm -rf node_modules && \
  NODE_ENV=production npm install \
  --prefer-offline \
  --pure-lockfile \
  --non-interactive \
  --production=true

FROM node:lts as prod-stage

WORKDIR /nuxtapp

COPY --from=build-stage /nuxtapp/.output/  ./.output/

CMD [ "node", ".output/server/index.mjs" ]

Automating the Build Process for the Nuxt App

Create a script that also cleans up your old images and containers before building the new image, and pushing it to Docker Hub.

Create a new file: ./dockerhubpush.sh

Insert the following script:

#!/bin/bash
docker system prune
docker build -t yourusername/nuxt3-app .
docker push yourusername/nuxt3-app
$SHELL

Create a docker hub repo for the Nuxt app

As you can see in the script, we are building and pushing towards something that includes a userame and a projectname. This is because we are going to push the image to an external website called dockerhub.

When we have the application at dockerhub, we will be able to pull the image from any where, this will make it much easier to deploy the application to whichever server you want.

If you already have a username and repository set up at dockerhub, you may skip this step. Otherwise:

  1. Create an account at dockerhub here.
  2. Create a docker repository here.

Now go back to your docker-build script and make sure that yourusername/nuxt3-app aligns with your username and repository name at dockerhub.

Run the build script to push the Nuxt app

Now we can run the buildscript to push it to dockerhub.

Open the commandline and run:

./dockerhubpush.sh

Select Y to prune unused images, this is good practice to clean up old images everytime you build. Otherwise you will build up lots of space from old images.

Create a docker file for Nginx

Now we must do the same things we did for the nuxt app for a nginx app that will work as our proxy and web host.

Create a new folder named Nginx and add a file to it called: Dockerfile

Add the following code to the file:

FROM nginx:1.23.1-alpine

RUN rm -rf /etc/nginx/conf.d/default.conf

COPY nginx.conf /etc/nginx/conf.d

Too much time indoors, in front of the computer? Find an activity to do Outside at GeoQuestr.comGeoQuestr

Create a config file for Nginx

In the same nginx folder, create a new file called: nginx.conf

Add the following code to the file:

(remember to replace "yourdomain.com" with what ever domain name you are deploying to.)

server {
    listen 80;
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 256;

    gzip_types
        application/atom+xml
        application/geo+json
        application/javascript
        application/x-javascript
        application/json
        application/ld+json
        application/manifest+json
        application/rdf+xml
        application/rss+xml
        application/xhtml+xml
        application/xml
        font/eot
        font/otf
        font/ttf
        image/svg+xml
        text/css
        text/javascript
        text/plain
        text/xml;

    # This is a cache for SSL connections
    # ssl_session_cache shared:le_nginx_SSL:1m;
    # ssl_session_timeout 1440m;

    rewrite ^/(.*) /$1 break;

    location / {
        proxy_set_header        Host $host;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto $scheme;
        proxy_redirect          off;
        proxy_buffering         on;
        proxy_cache_valid   200 1d;
        proxy_cache_use_stale   error timeout invalid_header updating http_500 http_502 http_503 http_504;

        proxy_pass              http://nuxt:3000;
        proxy_read_timeout  1m;
        proxy_connect_timeout   1m;
    }

}

Create a docker-build script for Nginx

create a new file in the nginxfolder: ./dockerhubpush.sh

add the following code to it:

#!/bin/bash
docker system prune
docker build -t yourusername/nginx .
docker push yourusername/nginx
$SHELL

Create another repository at dockerhub for Nginx

Create another repository at dockerhub called nginx. (yourusername/nginx)

Push Nginx to dockerhub

Now we can run the buildscript to push it to dockerhub.

Open the commandline and run:

./dockerhubpush.sh

Create docker compose file

Create a new file called docker-compose.yml

version: '3.9'
services:

  nginx:
    image: yourusername/nginx
    container_name: nginx
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
    ports:
      - '80:80'
      - '443:443'
    depends_on:
      - nuxt
    volumes:
      - /etc/letsencrypt/live/yourdomain.com/:/etc/letsencrypt/live/yourdomain.com/
      - /etc/letsencrypt/:/etc/letsencrypt

 nuxt:
    image: yourusername/nuxt3-app
    container_name: nuxt
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
    depends_on:
      - postgres
    ports:
      - '3000:3000'
    restart: always

Place the file on what ever server you will to deploy to.

Now we have everything we need.

Place the docker-compose.yml file where ever you wish to deploy the applications to.

Then just run these commands in the commandline in the same folder that you placed the file:

docker compose pull
docker compose up

If you wish to run your app on a linux VPS, just add the file to that server, make sure docker and docker compose is installed on that server, make sure that the ssl_certificate_key and ssl_certificate files are placed on your server and points at the correct place in the nginx.nconf file.

For information on how to setup a linux vps and how to get SSL certificate you need to check another tutorial.

But we have so far done everything we need for docker compose and to deploy nuxt 3 and nginx.

Did you like this tutorial?

You can support me, so that i can continue to make more tutorials like this one.

buy-me-a-coffee