All about Deployment: Docker and CI/CD

Fajrin Kingwijati
Scrum Booster
Published in
5 min readApr 29, 2019
Docker

Docker

Docker is a computer program that performs operating-system-level virtualization. Docker is used to run software packages called containers. Containers are isolated from each other and bundle their own application, tools, libraries and configuration files; they can communicate with each other through well-defined channels.

Salah satu hal menarik dari Docker adalah logonya, yaitu sebuah container, ya memang tujuan dari Docker sendiri mirip container, yaitu “membungkus” environment suatu aplikasi yang ada agar aplikasi tersebut bisa berjalan. Lalu kenapa kita menggunakan Docker? Karena selain untuk proses otomatisasi pada CI/CD, akan lebih mudah jika kita membungkus environment aplikasi kita, karena tidak akan mengganggu environment server kita untuk menjalankan aplikasi tersebut.

Pada Scrum Booster, Docker kita gunakan khusus untuk Backend API, di mana backend API kami menggunakan framework Django Rest Framework. Semua kode konfigurasi API tersebut kami taruh ke dalam suatu Docker Image, dan image tersebut disimpan di suatu Docker Registry yang disediakan oleh PPL Fasilkom UI. Docker Image & Container kami ditaruh di docker image & container management system berbasis GUI yang bernama Portainer. Berikut adalah image-image dari Scrum Booster yang sudah di push ke registry PPL.

Docker Image API Scrum Booster

Terdapat 2 container, yaitu untuk staging dan untuk development.

Docker Orchestration

Dibuat sebuah file yang bernama Dockerfile, berisikan konfigurasi dari docker container.

Dockerfile

# Dockerfile

# FROM directive instructing base image to build upon
FROM python:3-onbuild

WORKDIR /app

COPY . /app

EXPOSE 8000

CMD ["./start.sh"]

Fungsi dari Docker file tersebut adalah untuk melakukan Docker Image Importing dari image python:3-onbuild. Lalu ditentukan working directory pada dir /app dan semua file dipindahkan ke dir /app yang ada pada Docker Image. Lalu Django app dijalankan pada port 8000 dan selanjutnya dijalankan sebuah script bash yang bernama file start.sh

start.sh

#!/bin/bash
python manage.py makemigration
python manage.py migrate
python manage.py populatedb2
# Start Gunicornn processes
echo Starting Gunicorn.
exec gunicorn api.wsgi:application \
--bind 0.0.0.0:8000 \
--workers 3

script start.sh tersebut selain menjalankan migrasi database, juga menjalankan Gunicorn, sebuah environment tempat Django bisa berjalan.

Deployment and CI/CD

Deployment kami bagi ke 3 fase, yaitu fase Development, Staging, dan Production, di sini saya akan menjelaskan fase Deployment pada Flutter app Scrum Booster.

Untuk deployment pada android, kami menggunakan 3rd party app yaitu Hockey App. Deployment pada Hockey app mengandalkan CI/CD gitlab runner yang kodenya ada di .gitlab-ci.yml

Hockey App

Development

Fase ini adalah lingkungan pengembangan yang diperuntukkan dalam pengujian kode dan dipergunakan dalam melakukan unit testing. Ditandai dengan nama branch US-nomor_task-user_story.

Berikut potongan kode CI/CD kami yang bertanggung jawab atas deployment app Development pada gitlab runner dan hockey app:

FlutterDeployToDevelopment:
variables:
ENV_NAME: "development"
image: runmymind/docker-android-sdk:latest
stage: deploy
tags:
- docker
- build
only:
refs:
- /^US-.*$/
except:
changes:
- scrum-booster-api/**/*
before_script:
- wget --quiet --output-document=flutter.tar.xz https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_v1.0.0-stable.tar.xz && tar xf flutter.tar.xz -C /
- export PATH=$PATH:/flutter/bin
- apt-get update && apt-get install gnupg -y
- curl -sL https://deb.nodesource.com/setup_11.x | bash - && apt-get install -y nodejs
- flutter doctor -v
- flutter packages get
- npm install --global appcenter-cli
script:
- flutter build apk --release --build-name=$APP_NAME-$ENV_NAME --build-number=1
- appcenter
- appcenter login --token $APP_CENTER_API_KEY
- appcenter distribute release -f build/app/outputs/apk/release/app-release.apk --app $APP_CENTER_APP_NAME_DEV --group $APP_CENTER_GROUP_TARGET
environment:
name: development

Berikut hasil build tersebut pada Hockey app

Ini berhasil karena CI/CD dijalankan pada Gitlab Runner di environment development yang ditarik dari branch development

Staging

Environment ini merupakan tujuan deployment untuk code GIT branch staging dan merupakan environment yang digunakan saat sprint review. Seluruh branch UserStory[1..n] yang sudah di-merge ke branch staging, seharusnya secara otomatis dapat dilihat pada environment STAGING ini.

Berikut potongan kode CI/CD kami yang bertanggung jawab atas deployment app Staging pada gitlab runner dan hockey app:

FlutterDeployToStaging:
variables:
ENV_NAME: "staging"
image: runmymind/docker-android-sdk:latest
stage: deploy
tags:
- docker
- build
only:
refs:
- staging
before_script:
- wget --quiet --output-document=flutter.tar.xz https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_v1.0.0-stable.tar.xz && tar xf flutter.tar.xz -C /
- export PATH=$PATH:/flutter/bin
- apt-get update && apt-get install gnupg -y
- curl -sL https://deb.nodesource.com/setup_11.x | bash - && apt-get install -y nodejs
- flutter doctor -v
- flutter packages get
- npm install --global appcenter-cli
script:
- flutter build apk --release --build-name=$APP_NAME-$ENV_NAME --build-number=1
- appcenter
- appcenter login --token $APP_CENTER_API_KEY
- appcenter distribute release -f build/app/outputs/apk/release/app-release.apk --app $APP_CENTER_APP_NAME_STAGING --group $APP_CENTER_GROUP_TARGET
environment:
name: staging

Berikut hasil build tersebut pada Hockey app:

Ini berhasil karena CI/CD dijalankan pada Gitlab Runner di environment staging yang ditarik dari branch staging:

CI/CD untuk Testing

Selain untuk deployment, CI/CD juga kita gunakan untuk Testing pada gitlab runner, berikut potongan kode untuk menjalankan Test Backend maupun Frontend:

FlutterTest:
stage: test
image: jro7/flutter_lcov
script:
- echo Testing $APP_NAME
- flutter doctor -v
- flutter test --coverage
- lcov --summary coverage/lcov.info
- genhtml coverage/lcov.info --output=coverage
coverage: '/lines......: \d+\.\d+\%/'
artifacts:
name: mobile-coverage
paths:
- $CI_PROJECT_DIR/coverage

BackendTest:
stage: test
image: python:3.6
only:
changes:
- scrum-booster-api/**/*
before_script:
- cd scrum-booster-api
- pip install -r requirements.txt
- python manage.py makemigrations
- python manage.py migrate
- python manage.py collectstatic --no-input
- python manage.py runserver 8000 &
when: on_success
script:
- coverage run manage.py test
- coverage report -m

Kode ini akan menjalan Flutter test dan Backend test pada gutlab runner.

Pipeline test dan deployment pada gitlab runner

Semua ini memungkinkan karena kami menggunakan otomatisasi CI/CD gitlab runner.

--

--