A Clearer Vue in Google Cloud

Deploying a Vue.js application to Google Cloud Platform in a few minutes

In this article, we’ll be using Vue.js, Node, Docker and Google Cloud Platform to deploy to Google Compute Engine (GCE).

Vue.js. An intuitive Javascript frontend development framework for building simple, clean user interfaces, components, and much more.

Google Cloud Platform. A cloud computing platform with an extensive service offering. In this post, GCP will be leveraged for deployment and hosting the Vue application.


Let’s get started

If you have not used Google Cloud, you can head on over to https://console.cloud.google.com and register for a free account starting with $300 in credit.

Pre-requisites

  • A Google Cloud Platform Account and Google Cloud Project
  • Node.js (v10.x)
  • npm (v5.6.0)
  • Docker (v18.x)
  • gcloud (v219.0.1)

For reference, I’ve included the versions of the libraries & SDK above. I’m also running on MacOS Mojave, but have also verified these steps using Cloud Shell (Google Cloud’s built-in terminal).

1) Create and Run the Vue App

If you’re on Mac, open the terminal and begin. Alternatively, you can also use Google Cloud Shell, which is the integrated terminal for Google Cloud.

Google Cloud Console
  1. Setup a local folder
  2. Create our vue app
  3. Add vuetify to the vue app
  4. Run the app
# let's create our workspace
mkdir vue-google-cloud
cd vue-google-cloud/
# install vue
npm install @vue/cli -g
# create the vue-app (select default settings)
vue create vue-app
cd vue-app/
# add vuetify (select default settings)
vue add vuetify
# let's test out the app locally
npm run serve

The basic vue app should be hosted locally at http://localhost:8080/.

Vue app on http://localhost:8080/

2) Running our app locally with Docker

Let’s configure a simple Dockerfile

[Referenced with modifications from a simple example from Vue’s site…]

Here we will:

  1. Create the Dockerfile
  2. Build the Docker Image
  3. Run the Docker Image
  4. Test that our App is running
  5. Stop the local Docker Image
cat > Dockerfile << EOF
FROM node:9.11.1-alpine
# install simple http server for serving static content
RUN npm install -g http-server
WORKDIR .
# copy both 'package.json' and 'package-lock.json' (if available)
COPY package*.json ./
# install project dependencies
RUN npm install
# copy project files and folders to the current working directory (i.e. 'app' folder)
COPY . .
# build app for production with minification
RUN npm run build
EXPOSE 8080
CMD [ "http-server", "dist" ]
EOF
# now let's use docker to build a docker image
docker build -t vue-google-cloud/vue-app .
# let's run it to verify it all works.  
docker run -d -p 8080:8080 --rm vue-google-cloud/vue-app
# check to see that it's working
open localhost:8080
# get the running docker containers
docker ps
# stop the container.  the id will look similar to 386ab1e23ecd
docker stop [YOUR_CONTAINER_ID from docker ps here]

3) From Docker to Google Container Registry

Google Cloud has built-in registry support for images via Google Container Registry (gcr.io).

We will push a tag of our docker image to gcr.io.

# set the current project id
PROJECT_ID=$(gcloud config get-value core/project)
echo $PROJECT_ID # just so you know which project you're pushing to
# configure gcloud docker auth, if this hasn't been configured
gcloud auth configure-docker
# create a tag
docker tag vue-google-cloud/vue-app gcr.io/$PROJECT_ID/vue-app:v1
# enable the containerregistry.googleapis.com service
gcloud services enable containerregistry.googleapis.com
# push our docker image to gcr.io
docker push gcr.io/$PROJECT_ID/vue-app:v1

4) Deploy to GCE (Google Compute Engine)

Now let’s deploy our gcr.io image to a Google Cloud GCE VM.

In this section, we will:

  1. Create a firewall rule to allow traffic to port :8080
  2. Add an IAM policy binding for the default compute service account
  3. Create a GCE VM using the “create-with-container” deployment flag
  4. Open the External IP address on port 8080
# set the current project id
PROJECT_ID=$(gcloud config get-value core/project)
# create a new service account to be run with the VM
SA_NAME="vue-app-sa"
SA_EMAIL="$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"
gcloud iam service-accounts create $SA_NAME \
--display-name $SA_NAME \
--project $PROJECT_ID
# we will need a FW rule to expose tcp:8080
gcloud compute firewall-rules create vue-fw --allow tcp:8080,icmp
# grant the default compute service account view permission to the project to pull the gcr.io image
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$SA_EMAIL \
--role='roles/viewer'
# create the VM with create-with-container
gcloud compute instances create-with-container vue-app-vm \
--container-image=gcr.io/$PROJECT_ID/vue-app:v1 \
--service-account=$SA_EMAIL \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--zone us-west1-a
# to see the VMs in our project
gcloud compute instances list
# get the external ip
EXTERNAL_IP=$(gcloud compute instances list --format="get(networkInterfaces[0].accessConfigs[0].natIP)" --filter="name='vue-app-vm'")
# in your browser, navigate to the echoed address.  NOTE: the deployment may take about a minute.
echo http://$EXTERNAL_IP:8080

And hopefully hooray! These steps should have worked (the deployment can take up to a minute, so you may need to refresh the page a few times).

A browser window, running our Vue application via Docker should have popped up and is publicly accessible to the internet.

Vue application hosted on an external IP address

5) Clean-Up

We can clean-up our instance to save on the costs of continuing to run the VM.

gcloud compute firewall-rules delete vue-fw
gcloud compute instances delete vue-app-vm --zone=us-west1-a
gcloud iam service-accounts delete $SA_EMAIL

Conclusion

We have covered a simple deployment of a Vue.js application to an external IP address hosted in Google Cloud using Docker, Google Container Registry and Google Compute Engine. Google Cloud offers a handful of complementary services which can drive our application towards production-readiness. (i.e. Cloud DNS, Cloud Load Balancing, Stackdriver, etc.).