# πŸ‡¬πŸ‡§ Deploy application on OpenShift with GitLab CI

Yesterday, I explained how to set up a single OpenShift cluster in a virtual machine (opens new window). I did that because I'm using another VM to run a GitLab instance. My goal today is to deploy an application from a git repository hosted on my GitLab instance to my OpenShift cluster. For that, I need a GitLab runner (mine is in a VM too).

# GitLab runner

I'm using a Runner Shell Executor (opens new window), it's easy to install and to setup. Then, I installed the OpenShift CLI on the VM hosting my runner:

# Install OpenShift CLI
wget https://github.com/openshift/origin/releases/download/v3.11.0/openshift-origin-client-tools-v3.11.0-0cbc58b-linux-64bit.tar.gz
tar xvf openshift-origin-client-tools*.tar.gz
cd openshift-origin-client*/
mv  oc kubectl  /usr/local/bin/

# My amazing web application

I created a small nodejs webapp, did a git init and then a git push to my GitLab instance:

  • index.js
  • package.json

index.js

const http = require('http')
const port = 8080

let index_page = `
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>Hello World!</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        .container { min-height: 100vh; display: flex; justify-content: center; align-items: center; text-align: center; }
        .title { font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif; display: block; font-weight: 300; font-size: 100px; color: #35495e; letter-spacing: 1px; }
        .subtitle { font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif; font-weight: 300; font-size: 42px; color: #526488; word-spacing: 5px; padding-bottom: 15px; }
        .links { padding-top: 15px; }
    </style>
  </head>
  <body>
    <section class="container">
      <div>
        <h1 class="title">
        πŸ‘‹ Hello World πŸŒΒ˜πŸ˜€
        </h1>
        <h2 class="subtitle">
        made with πŸ’š and 🍡
        </h2>
        <h2 class="subtitle">
        proudly deployed by 🦊 GitLab CI πŸ›  and hosted on OpenShift
        </h2>                
      </div>
    </section>
  </body>
</html>  
`

const requestHandler = (request, response) => {
  console.log(request.url)
  response.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'})
  response.end(index_page)
}

const server = http.createServer(requestHandler)

server.listen(port, (err) => {
  if (err) {
    return console.log('😑 something bad happened', err)
  }
  console.log(`🌍 server is listening on ${port}`)
})

package.json

{
  "name": "hey-people",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "repository": {
    "type": "git",
    "url": ""
  },
  "keywords": [],
  "author": "@k33g",
  "license": "MIT"
}

# CI/CD Settings

Before writing the .gitlab-ci.yml file we need to add some environment variables to the project settings (the OpenShift CLI need these variable to connect and deploy on the server):

  • OPENSHIFT_IP (=192.168.1.100 see the previous blog post)
  • OPENSHIFT_PORT (=8443 see the previous blog post)
  • OPENSHIFT_TOKEN

text

To obtain the value of OPENSHIFT_TOKEN, you need:

  • to connect to the web console of your OpenShift cluster as an administrator (the default credentials are system/admin)
  • to click on the dropdown list of your profile (on the top right corner)
  • and choose this menu item: Copy Login Command

You shoul get something like that in your clipboard:

oc login https://192.168.1.100:8443 --token=8W-OX8XB-K7r7P6vmSz_aE7xM2ZK1fnHz-a3aaW89Vs

With this command you can connect in a terminal to your OpenShift cluster. So, now you can set OPENSHIFT_TOKEN with 8W-OX8XB-K7r7P6vmSz_aE7xM2ZK1fnHz-a3aaW89Vs.

Now, it's time to write the .gitlab-ci.yml file

# CI/CD script

Add a .gitlab-ci.yml file to your project with the below content:

stages:
  - πŸš€deploy
  - πŸ¦„deploy

# Yesterday, I create a project called `node` on the OpenShift server
# the application will be deployed in this OpenShift project
variables:
  OPENSHIFT_PROJECT: node

# before any action, I connect to the OpenShigt server with the appropriate credentials
# πŸ‘‹ this parameter: `--insecure-skip-tls-verify` is important because we use a certificate signed by an unknown authority
before_script:
  - oc login https://$OPENSHIFT_IP:$OPENSHIFT_PORT --token=$OPENSHIFT_TOKEN --insecure-skip-tls-verify

# this job is triggered when I commit on the `master` branch
# at each commit (or merge) on master, the application is deployed
# and you can reach it from your browser at this url:
# http://$CI_PROJECT_NAME-$OPENSHIFT_PROJECT.$OPENSHIFT_IP.nip.io
🚧production_deploy:
  stage: πŸš€deploy
  only:
    - master  
  environment:
    name: production/$CI_PROJECT_NAME
    url: http://$CI_PROJECT_NAME-$OPENSHIFT_PROJECT.$OPENSHIFT_IP.nip.io
  script: |
    oc project $OPENSHIFT_PROJECT
    oc get services $CI_PROJECT_NAME 2> /dev/null || oc new-app . --name=$CI_PROJECT_NAME
    oc start-build $CI_PROJECT_NAME --from-dir=. --follow
    oc get routes $CI_PROJECT_NAME 2> /dev/null || oc expose service $CI_PROJECT_NAME

# --- Review Application ---
# this job is triggered when I commit on a feature branch
# at each commit (or merge) on the feature, the application is deployed (or redeployed)
# and you can reach it from your browser at this url:
# http://$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-$OPENSHIFT_PROJECT.$OPENSHIFT_IP.nip.io
# πŸ‘‹ then you can "test" your web app before merge the updates on master (and deploy to production)
🚧preview_deploy:
  stage: πŸ¦„deploy
  only:
    - merge_requests
  environment:
    name: preview/$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME
    url: http://$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-$OPENSHIFT_PROJECT.$OPENSHIFT_IP.nip.io
    on_stop: πŸ—‘stop_preview_function
  script: |
    oc project $OPENSHIFT_PROJECT
    oc get services $CI_PROJECT_NAME-$CI_COMMIT_REF_NAME 2> /dev/null || oc new-app . --name=$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME
    oc start-build $CI_PROJECT_NAME-$CI_COMMIT_REF_NAME --from-dir=. --follow
    oc get routes $CI_PROJECT_NAME-$CI_COMMIT_REF_NAME 2> /dev/null || oc expose service $CI_PROJECT_NAME-$CI_COMMIT_REF_NAME

# this job is triggered when I merge the feature branch on `master` (and delete the feature branch)
# then the review application pod will be deleted from the cluster
πŸ—‘stop_preview_function:
  stage: πŸ¦„deploy
  only:
    - merge_requests
  when: manual
  environment:
    name: preview/$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME
    action: stop
  script: |
    oc project $OPENSHIFT_PROJECT
    oc delete services -l app=$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME
    oc delete all -l app=$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME

As soon as you commit the file, your first deployent will start, and you'll get a awesome web application:

text

That's all πŸ˜€

Last Articles