Vue 3 - Running and Deploying with Docker Compose
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:
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
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.