How you can do continuous delivery with Vue, Docker, and Azure

How you can do continuous delivery with Vue, Docker, and Azure

How you can do continuous delivery with Vue, Docker, and Azure

A few weeks ago at ng-conf, I announced the launch of vscodecandothat.com — a project I worked on with Sarah Drasner to centralize all of my favorite VS Code tips into a collection of short, silent video clips. It’s like a site full of GIFs, except without the 600 megabyte payload and crashed browser tab.

Sarah designed and built the site using Vue. I put together the video clips with excessive pug references.

Sarah and I both work on the Azure team, so it was a good chance for us to use our own tools here at Microsoft to work with a real application. In this article, I’m going to break down how we do continuous delivery with vscodecandothat.com, and how you can do it yourself using the same tools we use.

Before we talk about the setup, I want to define exactly what I mean by “continuous delivery.”

Continuous something-or-other

The term Continuous Delivery refers to making releases easy, fast, and streamlined. We can argue about the exact definition of the term, but just remember that I am a front-end developer so my eyes may glaze over. I may snore. But go on. I swear I’m listening.

For our purposes, “Continuous Delivery” means that the process of building and deploying the site is completely automated. Here’s how that looks in real life:

  • Developer checks code into Github master branch
  • Build server pulls code from Github
  • Build server runs a build (npm script)
  • Build server creates a Docker container
  • Build server pushes Docker container to registry
  • Burke finds the source of broccoli smell in his office
  • Website pulls in updated container

Got all that? Basically, we’re going to automate everything that you would normally do as a developer so that checking code into Github is all you have to worry about. And lord knows that’s hard enough as it is.

OK, let’s begin at the beginning. The first thing we need to do is look at the application to see how it runs. And how it runs is “In a Docker, y’all.”

Running Vue on Docker

vscodecandothat.com is entirely front-end driven. It’s all HTML, JavaScript, and CSS in your browser. That being the case, all we want to do is serve up the index.html page from the dist folder. We use an nginx web server.

When you are just serving up static assets, the Dockerfile is very simple…

FROM nginx
WORKDIR /app
# Copy in the static build assetsCOPY dist/ /app/
# Copy in the nginx config fileCOPY misc/nginx.conf /etc/nginx/nginx.conf
# All files are in, start the web serverCMD ["nginx"]

Sarah created an nginx configuration file that we just copy in when the container gets built. Because you do not want to be in the business of configuring nginx (OMG you don’t), Sarah has posted her config file to a gist.

I use the [Docker extension for VS Cod](https://marketplace.visualstudio.com/items?itemName=PeterJausovec.vscode-docker&WT.mc_id= vscodecandothat-medium-buhollan)e so that I can see and manage all of my images and containers. I’m not afraid of the terminal, but my brain can only remember so many flags.

Now we need a registry to push the container to. We’re going to configure Azure Container Services (ACR) for that.

You can create an ACR repository from the web portal, but to prove I’m not afraid of the terminal, we’ll do it with the Azure CLI.

First, we need a group for resources. I called mine “vsCodeCanDoThat”.

az group create — name vsCodeCanDoThat — location eastus

Now create the ACR repository. I called mine “hollandcr”.

az acr create --resource-group vsCodeCanDoThat --name hollandcr --sku Basic

Now we can push our image to that by tagging it with the path to the Azure Container Registry.

hollandcr.azurecr.io/vscodecandothat:latest

In the video you can watch me login to the Azure Container Registry from the terminal. This is important because your push will fail if you are not logged in.

OK — now we need a site to host our container. For that we use Azure App Service.

Creating The App Service

First create a Linux service plan. For that, you need your app name and your resource group.

So

az appservice plan create -n appName -g resourceGroupName --is-linux -l "South Central US" --sku S1 --number-of-workers 1

Becomes

az appservice plan create -n vsCodeCanDoThatSP -g vsCodeCanDoThat --is-linux -l "South Central US" --sku S1 --number-of-workers 1

Now create the web app and point it at the container that was pushed to the AKS registry. This takes 4 parameters.

  • Service Plan
  • Resource Group
  • App Name (you haven’t defined this yet)
  • Docker image that you pushed earlier
az webapp create -n vsCodeCanDoThatSP -g vsCodeCanDoThatRG -p vscodecandothat -i hollandcr.azurecr.io/vscodecandothat:latest

And that’s it. You’ll get back a URL, and you should be able to open it and see your site running.

Now what we want to do is automate everything that we just did. We never ever want to have to go through any of these steps again.

The first thing we will do is to set up our site for “Continuous Deployment” from our container registry.

If you are using the App Service extension for VS Code, all of your Azure sites will show up right in the editor. You can just right-click and say “Open in Portal.”

Select the “Docker Container” menu option…

On this page you will see the container you configured from the terminal. There is an option at the bottom to turn on “Continuous Deployment.”

When you toggle this on and click “save,” a webhook will get created in your Azure Container Registry for this specific container. Now, anytime the image with tag “latest” is updated, the webhook will fire and notify App Service which automatically pulls in your image.

So we’ve automated some of this already. Once we push the image, it will be deployed. There is nothing we have to do besides push it. But we don’t want to push it. We want someone else to that.

And who will do it? The robots, that’s who. Or whom? OR WHOMST. Fortunately I’m not in high school English anymore. I failed it once and that was enough.

Setting up a build server

This is the point at which I tell you that we are going to use Visual Studio Team Services (VSTS). Then you say, “Visual Studio? I’m not using .NET”. And I say, “I know, it’s confusing.”

We need a system specifically designed to automate builds and deployment. This is exactly what VSTS is/does. Also, it’s free for 5 users or less (in a project space) and “free” is the only word in my love language. The only word besides “beer.”

Create a VSTS account if you don’t have one. Once you do, you land on the dashboard screen.

From here, you want to create a new team project.

Give your project a name and a description that nobody will find helpful. Leave the version control at Git.

The next screen gives you a Git URL to check your code into. But we already have Github, so just ignore that and select the “or build code from an external repository” option.

Authorize VSTS to Github and select the repo…

The next screen is offering to help you start with a template. In this case we are going to roll from an empty process. Because we are hard core like that.

Now we are going to start adding steps for VSTS to perform to do the build and deployment. The pull from source control is already happening, so the first thing we need to do is to run npm install on our code. To do that, add a task to “phase 1”. There is only 1 phase in our build / deployment.

Search for “npm” and add the npm task.

By default, you get the npm install task, which is exactly what we want. You don’t need to add any options to this task.

Next, we’ll be running the npm run build command, which will build a production instance of our Vue app with all of its Webpacking magic. For that, add another npm task. This time, change the name to “npm run build.” Set the “command” to “custom” and the “command and arguments” to “run build.”

Great! We’ve got the build, now we’re ready to Dockerize it. Add a new task and find the “Docker” one.

This is a big screen, so here’s the image and then we’ll walkthrough the highlights.

  • You are selecting the “Azure Container Registry”
  • Specify your Azure subscription
  • Specify your registry name (which we created earlier)
  • Set the “Image Name” to $(Build.Repository.Name)
  • Make sure you check the “Include Latest Tag”

Lastly, we want to push the image. Add another Docker task. This time, set the “Action” to “Push an image”. Set the “Image Name” to $(Build.Repository.Name) — just like before.

DO NOT SELECT THE “PUSH IMAGES” ACTION. If you do, your build will fail and you will blame god and all humanity before you figure out that you selected the wrong action. Don’t ask me how I know that.

And that’s it for defining the Build definition. You can now click “save and queue” at the top. Make sure that you select a “Hosted Linux Preview” agent. The Docker tasks needs the Linux agent.

Now sit back and wait for a build to kick off. If you’ve done everything right, you have now setup a completely automated build and deployment system for a Vue app that utilizes Docker and Azure. That’s the most buzzwords I’ve ever squeezed into one sentence.

Deploy and be happy

This seems like a lot to setup, but once you have it just like you want it, all you have to do is check in code to your Github repo and all of this manual deployment 💩 happens automatically. Your customers will love you. Your developers will love you. Heck — even YOU might love you.

I hope you find this helpful. I’m off to update my résumé with all of these buzzwords.

30s ad

Vue.js 2 Academy: Learn Vue Step by Step

Vue.js 2 Essentials: Build Your First Vue App

Nuxt: Supercharged Vue JS

Vue.js Fast Crash Course

Vue JS 2: From Beginner to Professional (includes Vuex)

Top Vue.js Developers in USA

Top Vue.js Developers in USA

Vue.js is an extensively popular JavaScript framework with which you can create powerful as well as interactive interfaces. Vue.js is the best framework when it comes to building a single web and mobile apps.

We, at HireFullStackDeveloperIndia, implement the right strategic approach to offer a wide variety through customized Vue.js development services to suit your requirements at most competitive prices.

Vue.js is an open-source JavaScript framework that is incredibly progressive and adoptive and majorly used to build a breathtaking user interface. Vue.js is efficient to create advanced web page applications.

Vue.js gets its strength from the flexible JavaScript library to build an enthralling user interface. As the core of Vue.js is concentrated which provides a variety of interactive components for the web and gives real-time implementation. It gives freedom to developers by giving fluidity and eases the integration process with existing projects and other libraries that enables to structure of a highly customizable application.

Vue.js is a scalable framework with a robust in-build stack that can extend itself to operate apps of any proportion. Moreover, vue.js is the best framework to seamlessly create astonishing single-page applications.

Our Vue.js developers have gained tremendous expertise by delivering services to clients worldwide over multiple industries in the area of front-end development. Our adept developers are experts in Vue development and can provide the best value-added user interfaces and web apps.

We assure our clients to have a prime user interface that reaches end-users and target the audience with the exceptional user experience across a variety of devices and platforms. Our expert team of developers serves your business to move ahead on the path of success, where your enterprise can have an advantage over others.

Here are some key benefits that you can avail when you decide to hire vue.js developers in USA from HireFullStackDeveloperIndia:

  • A team of Vue.js developers of your choice
  • 100% guaranteed client satisfaction
  • Integrity and Transparency
  • Free no-obligation quote
  • Portal development solutions
  • Interactive Dashboards over a wide array of devices
  • Vue.js music and video streaming apps
  • Flexible engagement model
  • A free project manager with your team
  • 24*7 communication with your preferred means

If you are looking to hire React Native developers in USA, then choosing HireFullStackDeveloperIndia would be the best as we offer some of the best talents when it comes to Vue.js.

Dockerizing a Vue Application

Dockerizing a Vue Application

This tutorial looks at how to Dockerize a Vue app, built with the Vue CLI, using Docker along with Docker Compose and Docker Machine for both development and production. We’ll specifically focus on

This tutorial looks at how to Dockerize a Vue app, built with the Vue CLI, using Docker along with Docker Compose and Docker Machine for both development and production. We’ll specifically focus on-

  1. Setting up a development environment with code hot-reloading
  2. Configuring a production-ready image using multistage builds

We will be using:

  • Docker v18.09.2
  • Vue CLI v3.7.0
  • Node v12.2.0
Project Setup

Install the Vue CLI globally:

$ npm install -g @vue/[email protected] 

Generate a new app, using the default preset:

$ vue create my-app --default 
$ cd my-app 
Docker

Add a Dockerfile to the project root:

# base image
FROM node:12.2.0-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
RUN npm install
RUN npm install @vue/[email protected] -g

start app

CMD ["npm", "run", "serve"]

Add a .dockerignore as well:

node_modules
.git
.gitignore

This will speed up the Docker build process as our local dependencies and git repo will not be sent to the Docker daemon.

Build and tag the Docker image:

$ docker build -t my-app:dev .

Then, spin up the container once the build is done:

$ docker run -v ${PWD}:/app -v /app/node_modules -p 8081:8080 --rm my-app:dev

What’s happening here?

  1. The docker run command creates a new container instance, from the image we just created, and runs it.
  2. -v ${PWD}:/app mounts the code into the container at “/app”.
{PWD} may not work on Windows. See this Stack Overflow question for more info.

3. Since we want to use the container version of the “nodemodules” folder, we configured another volume: -v /app/nodemodules. You should now be able to remove the local “node_modules” flavor.

4. -p 8081:8080 exposes port 8080 to other Docker containers on the same network (for inter-container communication) and port 8081 to the host.

For more, review this Stack Overflow question.

5. Finally, --rm removes the container and volumes after the container exits.

Open your browser to http://localhost:8081 and you should see the app. Try making a change to the App component (src/App.vue) within your code editor. You should see the app hot-reload. Kill the server once done.

What happens when you add -it?
$ docker run -it -v ${PWD}:/app -v /app/node_modules -p 8081:8080 --rm my-app:dev
Check your understanding and look this up on your own.

Want to use Docker Compose? Add a docker-compose.yml file to the project root:

version: '3.7'

services:

 my-app:
  container_name: my-app
  build:
   context: .
   dockerfile: Dockerfile
  volumes:
   - '.:/app'
   - '/app/node_modules'
  ports:
   - '8081:8080'

Take note of the volumes. Without the anonymous volume ('/app/node_modules'), the node_modules directory would be overwritten by the mounting of the host directory at runtime. In other words, this would happen:

  • Build - The node_modules directory is created in the image.
  • Run - The current directory is mounted into the container, overwriting the node_modules that were installed during the build.

Build the image and fire up the container:

$ docker-compose up -d --build

Ensure the app is running in the browser and test hot-reloading again. Bring down the container before moving on:

$ docker-compose stop
Windows Users: Having problems getting the volumes to work properly? Review the following resources:
Docker on Windows–Mounting Host Directories
Configuring Docker for Windows Shared Drives
You also may need to add COMPOSE_CONVERT_WINDOWS_PATHS=1 to the environment portion of your Docker Compose file. Review the Declare default environment variables in file guide for more info.
Docker Machine

To get hot-reloading to work with Docker Machine and VirtualBox you’ll need to enable a polling mechanism via chokidar (which wraps fs.watchfs.watchFile, and fsevents).

Create a new Machine:

$ docker-machine create -d virtualbox my-app
$ docker-machine env my-app
$ eval $(docker-machine env my-app)

Grab the IP address:

$ docker-machine ip my-app

Then, build the images:

$ docker build -t my-app:dev .

And run the container:

$ docker run -it -v ${PWD}:/app -v /app/node_modules -p 8081:8080 --rm my-app:dev

Test the app again in the browser at http://DOCKER_MACHINE_IP:8081 (make sure to replace DOCKER_MACHINE_IP with the actual IP address of the Docker Machine). Also, confirm that auto reload is not working. You can try with Docker Compose as well, but the result will be the same.

To get hot-reload working, we need to add an environment variable: CHOKIDAR_USEPOLLING=true.

$ docker run -it -v ${PWD}:/app -v /app/node_modules -p 8081:8080 -e CHOKIDAR_USEPOLLING=true --rm my-app:dev

Test it out again. Then, kill the server and add the environment variable to the docker-compose.yml file:

version: '3.7'

services:

 my-app:
  container_name: my-app
  build:
   context: .
   dockerfile: Dockerfile
  volumes:
   - '.:/app'
   - '/app/node_modules'
  ports:
   - '8081:8080'
  environment:
   - CHOKIDAR_USEPOLLING=true

Production

Let’s create a separate Dockerfile for use in production called Dockerfile-prod:

# build environment
FROM node:12.2.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json /app/package.json
RUN npm install --silent
RUN npm install @vue/[email protected] -g
COPY . /app
RUN npm run build

production environment

FROM nginx:1.16.0-alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Here, we take advantage of the multistage build pattern to create a temporary image used for building the artifact – the production-ready Vue static files – that is then copied over to the production image. The temporary build image is discarded along with the original files and folders associated with the image. This produces a lean, production-ready image.

Check out the Builder pattern vs. Multi-stage builds in Docker blog post for more info on multistage builds.

Using the production Dockerfile, build and tag the Docker image:

$ docker build -f Dockerfile-prod -t my-app:prod .

Spin up the container:

$ docker run -it -p 80:80 --rm my-app:prod

Assuming you are still using the same Docker Machine, navigate to http://DOCKER_MACHINE_IP/ in your browser.

Test with a new Docker Compose file as well called docker-compose-prod.yml:

version: '3.7'

services:

 my-app-prod:
  container_name: my-app-prod
  build:
   context: .
   dockerfile: Dockerfile-prod
  ports:
   - '80:80'

Fire up the container:

$ docker-compose -f docker-compose-prod.yml up -d --build

Test it out once more in your browser.

If you’re done, go ahead and destroy the Machine:

$ eval $(docker-machine env -u)
$ docker-machine rm my-app
Vue Router and Nginx

If you’re using Vue Router, then you’ll need to change the default Nginx config at build time:

RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d

Add the changes to Dockerfile-prod:

# build environment
FROM node:12.2.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json /app/package.json
RUN npm install --silent
RUN npm install @vue/[email protected] -g
COPY . /app
RUN npm run build

production environment

FROM nginx:1.16.0-alpine
COPY --from=build /app/dist /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Create the following folder along with a nginx.conf file:

└── nginx
└── nginx.conf

nginx.conf:

server {

 listen 80;

 location / {
  root  /usr/share/nginx/html;
  index index.html index.htm;
  try_files $uri $uri/ /index.html;
 }

 error_page  500 502 503 504 /50x.html;

 location = /50x.html {
  root  /usr/share/nginx/html;
 }

}

Thank you for taking the time to read my article. If you liked this post, share it with all of your programming buddies!

How To Publish Your Vue.js Component On NPM - Vue.js Developers

How To Publish Your Vue.js Component On NPM - Vue.js Developers

How To Publish Your Vue.js Component On NPM. You’ve made an awesome component with Vue.js that you think other developers could use in their projects. How can you share it with them?