OpenPaaS Documentation logo OpenPaaS Documentation

Table of contents

Overview

We choose Vue.js as the framework to develop new Web applications within OpenPaaS. This page describes architecture, best practices and explain choices we made.

Dependencies

Here is the (uncomplete) list of dependencies used to build a Vue app:

Environment

We use latest Vue version, Vue CLI 3 and Node 10.x:

Bootstrap a new application

A “seed” is available at https://github.com/linagora/vue-openpaas-seed. It uses all the dependencies listed above and provides an OpenPaaS compatible layout. By using this seed as basis for other apps, you will be sure to be compliant with all the good practices defined in this guide.

1. Clone the seed

(Replace my-app by your app name)

git clone git@github.com:linagora/vue-openpaas-seed.git my-app

You will have to change several things in the files, expecially the application name and description in package.json.

2. Install dependencies

cd my-app
npm install

3. Configure

The application can be configured by updating the .env files as described in the Vue CLI documentation. Values defined in the .env file are used at several places in the app (from the store), and can be adapted to your environment. For example, while in development, you can redefine your OpenPaaS instance URL in a .env.development.local file which will never be commited (so you can also push secrets in it).

VUE_APP_SUPER_SECRET=A super secret thing
VUE_APP_OPENPAAS_URL=http://localhost:8080

4. Develop

Once done, you can start developping:

The Vue CLI UI

Best practices

Project files layout

We use the default layout provided by vue-cli:

State Management

There are tons of articles around the Web to understand why managing state the Flux-way is easy and powerful. The choice was not hard, just because Vue is simple and provides just the right tools, Vuex is used as state manager, and we rely on the modular approach so that we can scale our app.

As shown in src/store/:

The Vue State

Routing

vue-router is used as the application router.

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home,
      meta: {
        auth: true
      }
    },
    {
      path: '/login',
      name: 'Login',
      component: Login,
      meta: {
        auth: false
      }
    }
  ]
});

The user will be redirected to the Login page if he is not authenticated when opening the Home page.

Authentication

The authentication is a complex subject and depends on the way application are hosted in OpenPaaS. Basically, they can be hosted as any other traditional AngularJS application, i.e. in an OpenPaaS module which is served by the OpenPaaS ESN, or they can be hosted in their own ‘runtime’, for example, in a distinct container, or as static assets.

ESN-hosted application

As described in the ESN authentication documentation, AngularJS application relies on cookies to authenticate user: A session cookie is sent with each request. This will be the same if the Vue application is hosted on a module, if not, new authentication mechanisms have to be implemented in the Vue application.

PaaS-hosted application

By ‘PaaS-hosted’, it means that the application is not hosted in an OpenPaaS ESN NodeJS module. It is hosted somewhere else, in a Docker container, served by an Apache server, etc…

JWT

websanova@vue-auth is used to implement JWT based authentication: When a user fills his login/password on the login page, a single POST /api/jwt/generate request is sent to the OpenPaaS backend, to get a JWT token for the given user. The token is then pushed in the application state and reused in all HTTP calls to OpenPaaS.

Cookies

This is not available right now and it hardly depends on how application are deployed in OpenPaaS:

If a user who is authenticated within OpenPaaS opens a Vue powered application running somewhere else in the PaaS, we should be able to not ask the password again and again. There are several ways to do this, one will be to push a JWT token in the cookie and extract this JWT token when the Vue application is launched.

T O D O: This needs to be checked

LemonLDAP

T O D O: Check how Lemon can be used, (and is already used)

Reusing components

Some frontend components are available as described in Vue Components. If for some reason, you need a component which is not provided by this module but you think it will be useful to share, please consider adding it to the module.

Using OpenPaaS Core API

T O D O: We need a dedicated module.

Build

Building the application can be done from npm npm run build or from Vue UI. It will generate the application in the dist folder.

Deploy

Vue applications such as openpaas-videoconference-app which need to be deployed in Docker environment must follow some rules:

  1. The Docker image must contain the generated assets (from npm run build)
  2. The application must not be configured at build time but at run time. This means that we can not use vue-cli resources like .env files in this case
  3. The Vue application assets must be served by an HTTP server like nginx and exposed correctly by the container

Build & Run

# Multistage build

FROM node:10.13.0-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Then to run

FROM nginx:1.13.12-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
VOLUME ["/usr/share/nginx/html/env"]
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

The important point here is the Docker volume used to put files into the container at runtime. The files in /usr/share/nginx/html/env folder is then used by the application to get all the variables needed to run. For a concrete example, check code in https://ci.linagora.com/linagora/lgs/openpaas/openpaas-videoconference-app/merge_requests/32.

This is then possible to configure the running app from the Docker run command, or any compatible Docker environment like:

docker run -it -p 8888:80 --rm --name openpaas-videoconference-app -v $PWD/.config/env:/usr/share/nginx/html/env linagora/openpaas-videoconference-app