๐Ÿ‡ฌ๐Ÿ‡ง Deploy application on OpenShift with GitLab CI

Yesterday, I explained how to set up a single OpenShift cluster in a virtual machine. 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, 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


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

let index_page = `
<!doctype html>
    <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">
        .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; }
    <section class="container">
        <h1 class="title">
        ๐Ÿ‘‹ Hello World ๐ŸŒย˜๐Ÿ˜€
        <h2 class="subtitle">
        made with ๐Ÿ’š and ๐Ÿต
        <h2 class="subtitle">
        proudly deployed by ๐ŸฆŠ GitLab CI ๐Ÿ›  and hosted on OpenShift

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

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}`)


  "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 (= see the previous blog post)
  • OPENSHIFT_PORT (=8443 see the previous blog post)


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 --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:

  - ๐Ÿš€deploy
  - ๐Ÿฆ„deploy

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

# 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
  - 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:
  stage: ๐Ÿš€deploy
    - master  
    name: production/$CI_PROJECT_NAME
  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:
# ๐Ÿ‘‹ then you can "test" your web app before merge the updates on master (and deploy to production)
  stage: ๐Ÿฆ„deploy
    - merge_requests
    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
  stage: ๐Ÿฆ„deploy
    - merge_requests
  when: manual
    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:


That's all ๐Ÿ˜€

Last Articles

Last Updated: 7/26/2019, 6:14:48 AM