Dockerizing a Vuejs app
January 03, 2021
Docker is a great technology to handle all dependencies quickly and make sure that all developers have the same environment. That’s why here we are going to learn how to dockerize an app, what type of app, well, a Vuejs app. Vuejs is a technology which is having a huge fan base, so for all people who like Vuejs, here you will know how to dockerize a Vuejs app.
We are going to use yarn in the dockerfile and .dockerignore, if you want to use npm, just change the commands or the files to the npm equivalent, and it has to work properly.
First, we’re going to do, is to specify the base image that the container is going to inherit from, the image is going to be the latest version of node, as you can see:
FROM node:latestThen, we need to set the working directory. The working directory is where our app will be, so this is the next line of code:
WORKDIR /appAlso, we have to add node_modules/.bin to the PATH, with this we
ensures that the executables created during yarn serve (or npm run
dev) process can be found. And we do it like this:
ENV PATH /app/node_modules/.bin:$PATHNow it’s the time to copy the package.json and yarn.lock (package-lock.json if you’re using npm) and install the dependencies in our container:
COPY package.json /app/package.json
COPY yarn.lock /app/yarn.lock
RUN yarn installBecause we’re using Vue, and it has its own cli, we have to install it too:
RUN yarn global add @vue/cliAnd finally we start to run the serve:
CMD ["yarn", "serve"]Now the dockerfile is well done, the next it’s to specify which files
and folders we want to ignore. This is easy, the first is the
node_modules and the .git and .gitignore, maybe you wondering
why the node_modules, the answer is easy, we already created the
nodemodules in the containter in the Dockerfile, so we don’t want to
override the container’s nodemodules with the host’s node_modules. And
.git and .gitignore we’re going to ignore because we don’t need them
in the container. Then, the others files that we’re going to ignore is
the logs, and it’s also because we don’t need them in the container. And
the dockerignore will be like this:
node_modules
.git
.gitignore
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*Ok, now we have everything done to create our image, container and start to code like a pro 😎. The docker command to create the image with a name and a tag is:
docker build -t my-app:dev .This command create a container with the name my-app and the tag
dev. And to run the container is with the docker run command like
you will see:
docker run -v ${PWD}:/app -v /app/node_modules -p 8080:8080 --rm my-app:devWhat is going on here?
Well, let me explain:
-v ${PWD}:/appcreates a volume with the path of the project with the path of the project in the container, this allow to see all changes done in the host also in the container.-v /app/node_modulescreates a anonymous volume. This allow that the host’s nodemodules is use instead of the host’s nodemodules.-p 8080:8080exposes the port of the container with the port of the host. By the way, you can change the port of the host (e.g. 8081), the left is the port of the host, and the right the port of the container.--rmremoves the container and the volumes when the container execution ends.
Now you can go to localhost:8080 and see the app. This is great, but you have to run the above docker run command every time you want to run the app, and this could be painful if you add more settings, so this is why I always use docker compose, because it lets me to set all the configuration, and then the command to execute the container is always the same.
To use docker compose, first we have to create a docker-compose.yml
file. And add the following lines:
version: '3.7'
services:
my-app:
container_name: my-app
build:
context: .
dockerfile: Dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
ports:
- '8080:8080'Well, here there are a lot of things to explain, but some of them are self-explanatory. First, we set the version of the docker compose, then we list all services we want to create (each service is a container), in this example we just have one container, so the name of the service is my-app. Now we specify the name of the container, later we build our container, we specify the context and the Dockerfile to use. The container is pretty straightforward to analyze and finaly we expose the ports.
So then the command to create the image is:
docker-compose buildNow, the command to create the container is:
docker-compose up -dFinally, the commands to start and stop the container are:
docker-compose start
docker-compose stopAnd that’s it, with docker compose is pretty easy to create and run containers.
All files finally
Dockerfile:
# Setting the base image
FROM node:lts-alpine
# Set working directory
WORKDIR /app
# Add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
# Install and cache app dependencies
COPY package.json /app/package.json
COPY yarn.lock /app/yarn.lock
RUN yarn install
# Installing the vue cli
RUN yarn global add @vue/cli
# Start app
CMD ["yarn", "serve"].dockerignore:
node_modules
.git
.gitignore
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*docker-compose.yml:
version: '3.7'
services:
web:
container_name: prueba
build:
context: .
dockerfile: Dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
ports:
- '8080:8080'