Deploy VueJS applications on OpenShift

Recently, Vue.js became the top starred JavaScript framework on GitHub. It’s a great framework to quickly get started building single page applications in JavaScript. Its simplicity makes it easy to get started, but it’s robust enough to build large production applications.

But once your application is built, where can you deploy it? Because Vue.js will bundle up everything as static files, many options are available to you. In this post, we will explore how to deploy a Vue.js application on an Nginx server running in a Red Hat OpenShift cluster.

You will need

vue-cli

To create our application, we will use vue-cli to generate the skeleton of our application. You can install vue-cli by using a global install with npm.

$ npm install -g @vue/cli

An OpenShift instance

You can either use the official OpenShift platform or use a version that runs locally with MiniShift. If you don’t have access to an OpenShift instance and don’t want to install your own, you can sign up for the OpenShift Online service which includes a free trial or a paid tier if you require more resources and support.

Once your cluster is running, you can use oc to login and to interact with your OpenShift instance.

$ oc login

Docker or Podman

You will need the docker or the podman cli installed. My personal preference is for podman and that is what I will be using here. You can use both of them interchangeably.

Install Docker on Windows
Install Docker on Mac
Install podman on Linux

Getting Started

For this tutorial, you will deploy the skeleton application generated by vue-cli.

$ vue create vue-openshift

You can accept the default options here. Once everything is installed, you can test out the application.

$ cd vue-openshift
$ npm run serve

This will start the local server. You can make sure that your application is running by pointing your browser to http://localhost:8080. You should see the starter application here.

This is the development server. It has all those fancy features that you need for development, like file watching and hot reloads. But the development server also includes a bunch of packages like babel and eslint. To deploy to production, you will want a clean, minimalistic version of your single page application. To do so, stop the development server with Ctrl-C and run a build with:

$ npm run build

This will create the minified version of your website that is ready to be deployed in the /dist folder of your project. If you take a look in this folder, you will see an index.html file as well as all the other assets that compose your project.

Prepare Nginx

Nginx is a high performance open source web server that can be used to serve static files. It is easy to use within a container for that purpose.

To deploy a container that uses Nginx on OpenShift, you will need to do some adjustments to the default configuration.

OpenShift has many security features built in. One of them is ensuring that no container is allowed to run as root. This is why you need to create our own nginx.conf file to use with OpenShift.

First, you can start with the basic setup for nginx:

worker_processes auto;
events {
 worker_connections 1024;
}
http {
  include /etc/nginx/mime.types
  server {
    server_name _;
    index index.html
    location / {
    }
  }
}

Nginx will need read and write access to a few files. Because this container won’t run as root, we need to make sure that those files are stored in a folder that can be read by nginx. At the root of the configuration file, just under worker_processes auto;, add the following line

pid /tmp/nginx.pid;

And in the http section, right after the include /etc/nginx/mime.types, add

  client_body_temp_path /tmp/client_temp;
  proxy_temp_path       /tmp/proxy_temp_path;
  fastcgi_temp_path     /tmp/fastcgi_temp;
  uwsgi_temp_path       /tmp/uwsgi_temp;
  scgi_temp_path        /tmp/scgi_temp;

In the server section, you will need to specify a port that is over 1024 so that non-root users can run this, as well as specify the access and error log paths.

 server {
   listen 8080;
   # ...
   error_log  /tmp/error.log;
   access_log /tmp/access.log;

   location / {
     # ...
   }
 }

Finally, you will need to tell nginx which files to serve. In the next step, we will copy our files into the /code folder of our container. This is the folder you will use as a root for the application. Finally, you need to configure nginx to try to find the files or to redirect to index.html. This will be used by the vue router when you try to access a section of your site like /about. If a /about/index.html file does not exist, it will use the default /index.html file and display the information based on the vue-router configuration.

    location / {
      root /code
      try_files $uri /index.html
    }

Your final nginx.conf file should look like this.

# nginx.conf
worker_processes auto;

pid /tmp/nginx.pid;

events {
 worker_connections 1024;
}

http {
 include /etc/nginx/mime.types; 
  client_body_temp_path /tmp/client_temp;
 proxy_temp_path       /tmp/proxy_temp_path;
 fastcgi_temp_path     /tmp/fastcgi_temp;
 uwsgi_temp_path       /tmp/uwsgi_temp;
 scgi_temp_path        /tmp/scgi_temp;

 server {
   listen 8080;
   server_name _;

   index index.html;
   error_log  /tmp/error.log;
   access_log /tmp/access.log;

   location / {
     root /code;
     try_files $uri /index.html;
   }
 }
}

Containerize Your Application

The next step will be to prepare a container that can be deployed on OpenShift. For this application, a container that runs Nginx will be used to serve those static files that you generated in the first step.

The first step to prepare the container is to create a Dockerfile in the root folder of your application (/vue-openshift). The file will contain the following

FROM nginx:1.17

This image will be based on the official Nginx image provided on Docker Hub.

As explained in the previous step, nginx needs a special configuration in order to run as a non-root user in OpenShift. You can copy the new configuration to overwrite the default one provided in the base container.

COPY ./nginx.conf /etc/nginx/nginx.conf

Now that nginx is ready, you can copy over your files from the /dist folder into the /code folder of your container. This is the folder nginx will serve files from.

WORKDIR /code
COPY ./dist .

We will also need OpenShift to create a service at port 8080 so we can create a new route for nginx. This can be done by exposing the port 8080.

EXPOSE 8080

Finally, we will to start the nginx server with the following command that will be executed when the container runs.

CMD ["nginx", "-g", "daemon off;"]

Your final Dockerfile should look like this:

# Dockerfile
FROM nginx:1.17
COPY ./nginx.conf /etc/nginx/nginx.conf
WORKDIR /code
COPY ./dist .
EXPOSE 8080:8080
CMD ["nginx", "-g", "daemon off;"]

Build, Run And Publish Your Container

Now that your container is ready to go, you will need to build it and then push it to a registry. To build your container, run:

$ podman build -t vue-openshift .

Or, if you have Docker installed:

$ docker build -t vue-openshift .

The -t flag gives a tag to your build. It’s just a label to help you refer to your container later.

You can test your image by running:

$ podman run -d --rm --name vue-test -p 3000:8080 vue-openshift

This will start the container. The -d argument tells podman to run in the background. The –rm is used so that the container image is destroyed once you run ‘podman stop’. The –name is a label for your container. The -p maps port 3000 on your local machine to port 8080 in our container. This is the port on which nginx is running according to our config file. Finally, vue-openshift is the name you gave to the container you built.

Now that your container is running, you should be able to point your browser to http://localhost:3000 and see the skeleton Vue application.

You can stop this container by using:

$ podman stop vue-test

If you can see the application, your container is working and ready to be published. Many registries are available for you to push your images to. In this example, you can use the docker.io registry.

$ podman push vue-openshift docker://docker.io/<your-username>/vue-openshift

Now that your container is publicly available, you will be able to install it on OpenShift.

Deploy To OpenShift

You now have a working container that runs nginx and the build code for your Vue.js application. The last thing to do is to deploy it on OpenShift. This can be done through the web interface or through the command line tool oc.

First, start by creating a new project on OpenShift.

$ oc new-project vue-app

Then, deploy your new application by using the container you’ve just published.

$ oc new-app docker.io/<your-username>/vue-openshift

To verify that you application was deployed, you can use:

$ oc status

This should list you a service (svc) as well as a deployment configuration (dc). If you open up the web console, you should see the application with one pod running.

The last step to make your Vue.js application publicly available is to create a route that maps to the port 8080 in your pod. You can use the following command to create that route:

$ oc expose service vue-openshift --port=8080

If you look back at your application, you will now see a link under the Routes – External Traffic label.

This is the link to your Vue.js application. By clicking on this link, you should now see the deployed application that you built earlier.

All Done!

And that’s it! You now have a fully running Vue.js application served by an Nginx server in your OpenShift cluster. If you make changes to your application, you will need to re-create the Vue.js build, rebuild your container, push it to your registry and deploy your application. This is actually easier that it sounds.

$ npm run build
$ podman build -t vue-openshift .
$ podman push vue-openshift docker://docker.io/<your-username>/vue-openshift
$ oc rollout latest vue-openshift
Categories
OpenShift Ecosystem
Tags
, ,