Harden your Docker Containers using a Gitlab pipeline



  1. RapidFort Server (SaaS or On-Premises)
  2. RapidFort Service Account
  3. GitLab Runner with RapidFort CLI tools installed on it.
  4. Deployment Environment (for example, Kubernetes, Docker, Docker-Compose, AWS Fargate) must:
    1. have HTTPS access to the RapidFort server
    2. provide support for adding the SYS_PTRACE Linux kernel capability
  5. Container Registry (for example, Amazon Elastic Container Registry, Docker Hub, Microsoft Azure Container Registry, and so forth)

Instrument (Stub), Test, and Harden the NGINX Docker Image

The following example documents how to stub, test, and harden a NGINX Docker image. It will entail deploying and testing/exercising the stub image on the GitLab runner. The images will not be pushed on to a container registry.

  1. Download the sample .gitlab-ci.yml file.
  2. Update the following variables in the yml file:
    • For SaaS users, specify https://frontrow.rapidfort.com.
    • For On-Premises users, specify the hostname or IP address of your RapidFort on-premises server (for example, https://rapidfort.example.com).
  • RF_ACCESS_ID: Specify the access id for your RapidFort service account.
  • RF_SECRET_ACCESS_KEY: Specify the secret access key for your RapidFort service account.
  • RF_CLI_UPDATE: Specify "no" to download and install the RapidFort CLI tools only if they are not already installed on the runner or "yes" to always download and install the tools (even if they are already installed).
  • RF_CLI_PATH: Specify the location where the RapidFort CLI tools will be installed on the GitLab runner.




  TAG: latest

  RF_ROOT_URL: https://frontrow.rapidfort.com

  # generate service account & replace these

  RF_ACCESS_ID: RFabcdefghijkl123456

  RF_SECRET_ACCESS_KEY: 01234567891011abcdefghijklmnopqrstuvwxyz


  RF_CLI_PATH: /home/gitlab-runner/.local/bin



    - ubuntu


    - |

      if [ -z "$(command -v rflogin)" ] || [ "${RF_CLI_UPDATE}" == "yes" ]; then

        curl -ks "${RF_ROOT_URL}"/cli/ | bash


      export PATH="$RF_CLI_PATH:$PATH"


  - Build

  - Stub

  - Deploy

  - Test

  - Harden


  stage: Build


    - |

      docker pull $DOCKER_IMAGE_NAME:$TAG



  stage: Stub


    - |

      # ** GENERATE STUB **


      docker images | grep $DOCKER_IMAGE_NAME | grep $CI_PIPELINE_ID


  stage: Deploy


    - |

      # Run & test stub

      docker run --rm --name $DOCKER_IMAGE_NAME-$TAG-$CI_PIPELINE_ID -p9999:80 --cap-add=SYS_PTRACE -d $DOCKER_IMAGE_NAME:$TAG-$CI_PIPELINE_ID-rfstub


  stage: Test


    - |

      STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:9999 || /bin/true)

      until [ "${STATUS_CODE}" == 200 ]; do

        sleep 1

        STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:9999 || /bin/true)


      # Load test

      ab -n 10 -c 10 http://localhost:9999/

      # Remove running stub



  stage: Harden


    - |


      rfharden $DOCKER_IMAGE_NAME:$TAG-$CI_PIPELINE_ID-rfstub && echo "Hardened Done" || echo "Hardened Failed"

      docker images | grep $DOCKER_IMAGE_NAME | grep $CI_PIPELINE_ID

  when: manual

In the above example, the Stub stage executes rfstub to generate a stub image - an instrumented image, but does not push the image to a container registry. If that is desired, add necessary steps to the .yaml file. During this stage RapidFort platform also scans the image to detect vulnerabilities and computes the estimated risk reduction opportunity by hardening. 

In the Deploy & Test stages RapidFort platform traces the runtime behavior of the application and builds the runtime profile.

The Harden stage is manual since it requires a runtime profile which is only generated after deploying and testing the stub image.