October 7, 20256 min

Vue 3 (Vite) - Deploy with Docker Compose and Nginx

A step-by-step guide to set up and deploy a Vue 3 (Vite) application using Docker Compose and Nginx.

Vue 3 - Running and Deploying with Docker Compose

vue-docker-nginx

Learn how to set up and deploy a Vue 3 (Vite) application using Docker Compose and Nginx in this tutorial.

Tags: Vue 3, Docker Compose, Nginx

Estimated reading time: 6 minutes

Prerequisites

  • Basic knowledge of the command line
  • Install Node.js version 18.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 Vue 3 App

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

Otherwise, create a new Vue 3 app (Vite) using the following commands:

npm create vue@latest
# Choose a project name, then pick the features you want (TypeScript, Router, Pinia, etc.)
cd your-vue-app
npm i
npm run dev

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

Writing a Dockerfile for the Vue App

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

This Dockerfile builds the app and serves the static dist/ files with a tiny Node web server inside the container.

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

# Build stage
FROM node:lts AS build-stage

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Production stage: serve built files
FROM node:lts AS prod-stage

WORKDIR /app

# lightweight static file server
RUN npm i -g serve

# copy build artifacts
COPY --from=build-stage /app/dist ./dist

EXPOSE 4173
CMD ["serve", "-s", "dist", "-l", "4173"]

Automating the Build Process for the Vue 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
set -euo pipefail
docker system prune -f
docker build -t yourusername/vue3-app .
docker push yourusername/vue3-app
$SHELL

Replace yourusername with your Docker Hub username.

Create a Docker Hub repo for the Vue app

As you can see in the script, we are building and pushing towards something that includes a username and a project name. This is because we are going to push the image to an external website called Docker Hub.

When we have the application at Docker Hub, we will be able to pull the image from anywhere. 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 Docker Hub, you may skip this step. Otherwise:

  1. Create an account at Docker Hub here.
  2. Create a Docker repository here.

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

Run the build script to push the Vue app

Now we can run the build script to push it to Docker Hub.

Open the command line and run:

chmod +x ./dockerhubpush.sh
./dockerhubpush.sh

Select Y to prune unused images; it’s good practice to clean up old images every time you build. Otherwise you will build up lots of space from old images.

Create a Dockerfile for Nginx

Now we must do the same things we did for the Vue app for an Nginx app that will work as our proxy and web host (TLS termination, gzip, and reverse-proxy to the Vue container).

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.com
GeoQuestr

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 whatever 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;

    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;

        # Vue container serves static files on 4173
        proxy_pass              http://vue:4173;
        proxy_read_timeout      1m;
        proxy_connect_timeout   1m;
    }
}

Create a docker-build script for Nginx

Create a new file in the nginx folder: ./dockerhubpush.sh

Add the following code to it:

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

Create another repository at Docker Hub for Nginx

Create another repository at Docker Hub called nginx.
(yourusername/nginx)

Push Nginx to Docker Hub

Now we can run the build script to push it to Docker Hub.

Open the command line and run:

chmod +x ./dockerhubpush.sh
./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:
      - vue
    volumes:
      - /etc/letsencrypt/live/yourdomain.com/:/etc/letsencrypt/live/yourdomain.com/
      - /etc/letsencrypt/:/etc/letsencrypt

  vue:
    image: yourusername/vue3-app
    container_name: vue
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
    expose:
      - '4173'
    restart: always

Place the file on whatever server you will deploy to.

Now we have everything we need.

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

Then run these commands in the command line 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 are installed on that server, and make sure that the ssl_certificate_key and ssl_certificate files are placed on your server and point to the correct paths in the nginx.conf file.

For information on how to set up a Linux VPS and how to get an SSL certificate you need to check another tutorial.

But we have so far done everything we need for Docker Compose and to deploy Vue 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