DEV Community

Cover image for A step-by-step guide to develop and deploy Vue apps with docker, part one

Posted on • Updated on • Originally published at

A step-by-step guide to develop and deploy Vue apps with docker, part one

Previously, I've described a very simple way to develop and deploy a Vue.js app using a combination of git and npm. This works fine to quickly prototype an app and see how it behaves in the wild. In case you're in for a productive project, you probably want to use a more predictable end-to-end workflow.

This series of articles will equip you with the knowledge to create, develop and deploy a Vue project with Docker. With some tweaks, you can also use the featured Dockerfiles to deploy any project, using other frameworks such as React or Svelte.

Introducing Docker

Docker is a tool to build and deploy containerized units of software. So next to the source code for the application, a Docker project will also bring the environment to run it.

In a nutshell, compared to the quick & dirty approach I've described previously, there are several significant advantages, such as:

  • Node.js is not required on the hosting machine, neither on your local device, for development, testing, or productive usage.
  • The installation of node modules and the building of the app can be done inside the container(s).
  • We can easily replace the static express folder with a 'real' server. In this case, we'll use nginx to serve the web app.
  • Sharing code and replicating errors in a team context is much easier.
  • Docker itself comes with some goodies, such as networks and docker-compose, making it easy to manage apps, APIs, and databases altogether.

Docker is built around two core structures: Containers and Images.

To not confuse these two, keep the following in mind when reading ahead:

  1. Images are blueprints for containers. They include the source code and the required runtime, like Python or Node.js
  2. Containers are living units of software. They are running based on an underlying image.

If you would like to dig deeper into how Docker helps you with your development workflow, you can find some references at the end of this article.

Installing Docker

For the scope of this article, we want to make use of all of Docker's capabilities. That means: You need to have no other tool installed but Docker itself. We'll use it to execute all further setup steps for the Vue development and build process.

Linux (Ubuntu) quick setup

Taken from

# Remove previous versions of docker
sudo apt-get remove docker docker-engine containerd runc

# Update package list & install necessary dependencies
sudo apt-get update
sudo apt-get install \
  apt-transport-https \
  ca-certificates \
  curl \
  gnupg \

# Add Docker's GPG key to your local mashine
curl -fsSL | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Install Docker
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Enter fullscreen mode Exit fullscreen mode

Windows setup

As Windows does not support containerization out of the box, you will need Docker Desktop to keep following along. You can download it using the link below.

Setting up the project

It is common for web frameworks to require some steps in between project initialization and deployment. To make sure this process can be replicated, Docker makes use of Dockerfiles, single files that describe steps to build an Image.

Naturally, you can use a local Node.js setup for development and containerize the app when it's ready for shipping. In this case, however, I'd like to leave the whole setup to Docker. So before we jump into development, let's start by setting an image that creates our project's structure and enables us to extend it.

The initial project structure

Change into a directory of your choice and create the following folder structure:

| - /dockerfiles
|   | - Setup.Dockerfile  # 1
|   | - Dev.Dockerfile    # 2
|   | - Deploy.Dockerfile # 3
Enter fullscreen mode Exit fullscreen mode

To give you an idea of what these three Dockerfiles will help us achieve:

  1. This image is responsible to scaffold a basic project structure, as well as installing further npm packages.
  2. We will use the second one to serve the project during development.
  3. Image three is responsible for building and shipping the app once we're ready to do so.

So much for the theory. Let's walk through these steps now, one by one.

Step 1: Initialize the app

While it is common to use Docker for app development and deployment, in this case, we will also use it to set up our initial project structure. Like so, we can reduce the amount of software to be installed on our local machine and keep the setup process lean & replicable.

We'll start by using the Vue CLI to set up our app's structure. Since it depends on Node.js, we'll start FROM node:14 and add some additional command layers on top.

Into the Setup.Dockerfile, add the following content:

FROM node:14

WORKDIR /vue-setup

RUN npm install -g @vue/cli

# The following commands ensure access to our files
# If we left them out, changing files on our local setup
# would fail due to insufficient permissions. 
RUN userdel -r node



RUN addgroup --gid $GROUP_ID user

RUN adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID user

# Set the active user and open the interactive terminal
USER user

ENTRYPOINT [ "bash" ]
Enter fullscreen mode Exit fullscreen mode

We can then build our vue_helper image using the following command.

# Build an image named vue_helper using the Setup.Dockerfile
# The build args manage permissions when executing commands from inside the container
docker build \
  --build-arg USER_ID=$(id -u) \
  --build-arg GROUP_ID=$(id -g) \
  -t vue_helper - < ./dockerfiles/Setup.Dockerfile
Enter fullscreen mode Exit fullscreen mode

Executing the next command will bind the container's working directory to our local machine, using a bind-mount.

Make sure the replace /path/to/project/ with your own project path.

docker run -v /path/to/project/:/vue-setup -it vue_helper
Enter fullscreen mode Exit fullscreen mode

Next, a terminal from inside the container will open. Here, we can now install the Vue app itself and add more npm modules, if necessary.

user@b24a617a1dfa:/vue-setup$ vue create vue_app
Enter fullscreen mode Exit fullscreen mode

You will then be prompted through the standard Vue CLI setup. In case you are unsure what to choose, just confirm all standard steps.

Given everything till this point went well, you will notice a new directory named vue_app appearing in your project folder. It origins from inside the container and means that everything went according to plan and our project is ready to be worked on.

Let's recapitulate what happened till this point:

  • We've used Docker to create a new image named vue_helper.
  • It uses a bind-mount and an interactive session terminal to help us scaffold our Vue project.
  • By using Vue create inside the container with a dedicated user, we have a basic project boilerplate available on our local device - without ever installing anything on it.

Stay tuned for the next part, where we will:

  • Explore how to serve the containerized app during development.
  • Build an application image and have it run on our local machine.
  • Deploy the image to Dockerhub and serve it on a Digital Ocean Droplet


Docker 101 - self-paced tutorial

Official Docker documentation

This post was originally published at
Thank you for reading. If you enjoyed this article, let's stay in touch on Twitter 🐤 @qbitme

Top comments (3)

tqbit profile image
tq-bit • Edited

Hi Dimitri. Thank you for reading & your feedback. I plan to release the 2nd part in the mid of this month.

The remaining code is already in its Github repos, feel free to take a peak. I haven't given it the final cut, but you might find it useful already. If you find something breaking, please let me know :-)

dberardi2020 profile image
Dimitri Berardi

When is part 2 coming?? This was exactly what I need, but I don't know what the other Dockerfile's should look like? This was so helpful, I would love to know the rest!

tqbit profile image