diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 20128f48bac5ed423faed7d664012004ac93ef50..d519eeb07df600191848d8883f20d95f52c10047 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,15 +1,8 @@
 stages:
   - deploy
 
-variables:
-  OPENSHIFT_SERVER: $OPENSHIFT_DEV_SERVER
-  INSTALLATION_ROOT: $INSTALLATION_ROOT
-  SPACKIFIED_ENV: $SPACKIFIED_ENV
-  OP: $OPERATION
-  #SPACK_ENV_TAR_FILE: ebrains-spack-builds${CI_PIPELINE_ID}.tar.gz
-  SPACK_ENV_TAR_FILE: ebrains-spack-builds.tar.gz
-
-deploy-build-environment:
+# start an OpenShift Job that will build the Spack environment
+.deploy-build-environment:
   stage: deploy
   before_script:
     - oc login "$OPENSHIFT_SERVER" --token="$OPENSHIFT_TOKEN"
@@ -22,7 +15,7 @@ deploy-build-environment:
     - ./create_job.sh $INSTALLATION_ROOT $SPACKIFIED_ENV $OP $SPACK_ENV_TAR_FILE $CI_PIPELINE_ID
     - cat simplejob.yml
     # select the project in openshift
-    - oc project jupyterhub-int
+    - oc project $OC_PROJECT
     # start the deploy job
     - oc create -f simplejob.yml
     ## wait for job to finish https://stackoverflow.com/questions/5073453wait-for-kubernetes-job-to-complete-on-either-failure-success-using-command-line
@@ -39,9 +32,43 @@ deploy-build-environment:
     - if [ $(cat log.txt |grep "Error:"|wc -l) -gt 0 ]; then exit 1;fi;
     # delete the job from OpenShift as we have the logs here
     - oc delete job simplejob${CI_PIPELINE_ID} || true
-  resource_group: shared-NFS-mount
   tags:
     - shell-runner
 
+# deploy on the dev environment
+# runs on protected branches only as the token variable is protected
+deploy-dev-environment:
+  extends: .deploy-build-environment
+  variables:
+    OPENSHIFT_SERVER: $OPENSHIFT_DEV_SERVER
+    OPENSHIFT_TOKEN: $OPENSHIFT_DEV_TOKEN
+    INSTALLATION_ROOT: $INSTALLATION_ROOT_DEV
+    SPACKIFIED_ENV: $SPACKIFIED_ENV_DEV
+    OP: $OPERATION_DEV
+    #SPACK_ENV_TAR_FILE: ebrains-spack-builds${CI_PIPELINE_ID}.tar.gz
+    SPACK_ENV_TAR_FILE: ebrains-spack-builds.tar.gz
+    OC_PROJECT: jupyterhub-int
+  resource_group: shared-NFS-mount-dev
+  only:
+    - master
+
 
+# deploy on the production environment
+# runs on protected branches only as the token variable is protected
+deploy-prod-environment:
+  extends: .deploy-build-environment
+  variables:
+    OPENSHIFT_SERVER: $OPENSHIFT_PROD_SERVER
+    OPENSHIFT_TOKEN: $OPENSHIFT_PROD_TOKEN
+    INSTALLATION_ROOT: $INSTALLATION_ROOT_PROD
+    SPACKIFIED_ENV: $SPACKIFIED_ENV_PROD
+    OP: $OPERATION_PROD
+    #SPACK_ENV_TAR_FILE: ebrains-spack-builds${CI_PIPELINE_ID}.tar.gz
+    SPACK_ENV_TAR_FILE: ebrains-spack-builds.tar.gz
+    OC_PROJECT: jupyterhub
+  resource_group: shared-NFS-mount-prod
+  rules:
+    - if: '$CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_COMMIT_BRANCH =~ /release/'
+      when: manual
+      allow_failure: false