Automated build pipelines with GitLab CI and APPUiO

GitLab project: https://git.vshn.net/appuio/example-php-sti-helloworld

APPUiO project: https://console.appuio.ch/console/project/vshn-maetthu-demo-test/overview

Overview

“Deploy early and often” is one of the core principles of agile development. One solution to this problem are automated build and deploy pipelines.

This project uses such a pipeline, based on GitLab CI and OpenShift. A sample PHP application is built and deployed to APPUiO.

Three environments in form of OpenShift projects are used: testqual and production. Those are the most commonly used setups but can be configured and extended. The idea is to build and deploy every commit from the master branch to the test environment automatically. If a git tag is created, the previously built docker image is tagged with the git tag name and automatically deployed to qual. The deployment to production is a manual step and can be invoked on GitLab.

Pipelines

There are two pipelines setup in .gitlab-ci.yml: One is run on every commit to the master branch and consists of the stages lintbuild and deploy-test. The lint stage starts a docker container in which the PHP code is verified for correct syntax. The build stage starts a new OpenShift build (S2I), waits for its completion and shows the log output of the build. The last stage automatically deploys the built image to the test environment.

The second pipeline is started upon creation of a git tag. It consists of the stages releasedeploy-qual and deploy-production. The first stage tags the docker image that was built for the respective git commit with the name of the created git tag. The deploy-qual stage deploys the tagged docker image automatically to the qualenvironment. The stage deploy-production needs to be started manually and deploys to the production environment.

APPUiO

The application and the build is run on APPUiO which allows us to use the concepts and solutions OpenShift provides to work with builds and deployments. The directory os contains the yaml-files which describe all the used OpenShift resources. These files live together with the code in the same git repository, which guarantees that the same version of the code is always built and deployed using same version of the OpenShift resources.

Build

The build consists of an OpenShift BuildConfig which uses a PHP source-to-image builder and builds a docker image containing the application. The image is tagged with the git commit hash and stored on the OpenShift docker registry.

BuildConfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: v1
kind: BuildConfig
metadata:
  labels:
    app: ${APPNAME}
  name: ${APPNAME}
spec:
  strategy:
    type: Source
    sourceStrategy:
      from:
        kind: ImageStreamTag
        name: 'php:7.0'
        namespace: openshift
      incremental: true
  source:
    git:
      ref: ${COMMIT_SHA}
      uri: ${REPOSITORY_URL}
    type: Git
  output:
    to:
      kind: ImageStreamTag
      name: '${APPNAME}:${APP_TAG}'

Deployment

DeploymentConfig is used to run the application. With the help of rolling deployments, zero downtime deployments are possible and the end user won’t experience any service disruption during updates. The liveness and readiness probes enable OpenShift to see if the container is running properly (liveness) and able to accept incoming traffic (readiness). Additionally an OpenShift service and route are set up to route traffic from outside the cluster to the application. The URL is specific for each environment and can be opened from within GitLab.

DeploymentConfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: v1
kind: DeploymentConfig
metadata:
  name: ${APPNAME}
spec:
  replicas: 1
  selector:
    app: ${APPNAME}
  strategy:
    type: Rolling
  template:
    spec:
      containers:
      - name: ${APPNAME}
        image: "docker-registry.default.svc:5000/${OPENSHIFT_PROJECT}/${APPNAME}:${APP_TAG}"
        imagePullPolicy: Always
        ports:
        - name: web
          containerPort: 8080
        livenessProbe:
          httpGet:
            path: /
            port: web
        readinessProbe:
          tcpSocket:
            port: web
      restartPolicy: Always

Demo

To see the pipeline in action you need three things:

  1. Your own fork of the repository on GitLab with GitLab CI enabled
  2. A project on APPUiO for each stage: test, qual and production
  3. A ServiceAccount with edit membership in all projects

Step by step

  1. Set up Kubernetes/OpenShift integration in GitLab: https://docs.gitlab.com/ce/user/project/clusters/index.html#adding-an-existing-kubernetes-cluster
  2. Configure .gitlab-ci.yaml with your APPUiO projects
  3. Commit & push the changes
  4. Watch the automated pipeline build the application and deploy it to the test project
  5. Create and push a git tag
  6. Watch the automated pipeline create image tags and deploy it to the qual project
  7. Manually run a deployment to the production environemnt by visiting the pipeline on GitLab and click “play” on the deploy:production job

Outlook

To further extend this setup, feature branches could be built and deployed to OpenShift. With this in place every merge request is built and a live version of the application is available to test the introduced changes. This ensures that only buildable changes are merged into the master branch and changes can be easily reviewed.

To learn more about automated builds and deployments with GitLab and APPUiO, read the docs and create a project on APPUiO Public.