Table of Contents

Nuxt 3 - Run and Deploy with Docker Compose.

nuxt-docker-nginx

Tutorial on how to deploy a Nuxt 3 application with docker compose and Nginx.

Tags: Nuxt 3, Docker Compose, Nginx

Time to read: 6 min

Prerequisites

  • Familiarity with the command line
  • Install Node.js version 16.0 or higher
  • Install Docker and Docker Compose. Easiest way is to install Docker Desktop which includes both. Read more how to install here.

Setup a Nuxt 3 app

Incase you already have a Nuxt 3 app that you wish to deploy, you can skip this step and move on to the next.

Otherwise run below commands to create a nuxt 3 app.

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

View app at http://localhost:3000/

Create a docker file for the Nuxt app

Now that we have a Nuxt app, we will add a docker file that will build the application into a container which we later can orchestrate with docker compose.

Create a new file and name it Dockerfile Add the following code to the file:

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" ]

Create a docker-build script for the Nuxt app

Now that we have a docker file, we are able to build the application into a docker image. Building to a docker image is something we will want to do everytime we have made a change in the application that we want to deploy. So lets create a script to automate this process.

create a new file: ./dockerhubpush.sh

add the following code to it:

#!/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

Create an config file for Nginx

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

Add the following code to the file:

(dont forget 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.

Thats all for today! :) Cya

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