Tutorial Gitlab CI/CD : Auto Deploy ke Server menggunakan Docker

Muhammad Zaky
12 min readJan 30, 2021

--

Halo semua apa kabar, semoga baik2 saja ya, udah ngoding berapa baris hari ini? kalau belum mari kita ngoding!!!

hari ini saya mau sharing tentang CI/CD untuk automatisasi deploy code kita ke server, jadi gak usah lagi git pull di server setiap code berubah.

Introduction

pernah tidak teman2 merasa lelah/ribet setiap kali ngubah code di local kemudian harus masuk ke server dan ubah di server juga? kalau iya, kita sama (sama2 malas :D).

CI/CD inilah yang bisa membantu kita untuk tidak repot2 ngubah code di server agar selalu update dengan code di local/git kita teman2.

Continous Integrasi and Continous Deployment atau yang sering di sebut juga CI/CD adalah sebuah jembatan antara Backend dan DevOps untuk membuat automasi dalam pengembangan aplikasi, seperti auto deploy ke server atau auto testing dan kebutuhan — kebutuhan lain.

nah, tools untuk mengerjakan CI/CD ini ada banyak, ada gitlab-ci, jenkins dan beberapa tools2 lainnya. tetapi hari ini kita akan membuat CI/CD menggunakan gitlab-ci.

jadi kita akan buat sebuah project express sederhana, yang nantikan akan otomatis di deploy ke server setiap kali kita melakukan push ke git. sehingga apapun code yang masuk ke git akan otomatis di implement di server.

requirements

untuk dapat mengikuti tutorial ini teman2 harus sudah memiliki :

  1. Install NodeJs (baca disini kalau belum terinstall)
  2. Install Docker
  3. pemahaman dasar tentang docker
  4. akun gitlab (karena menggunakan gitlab-ci)
  5. vps/server

kalau 5 hal diatas sudah terpenuhi, kita gassss ke materi selanjutnya. kalau belum terpenuhi ya baca2 aja dulu sambil kasih claps biar saya rajin nulis.

1. Buat Project Express Sederhana

yang pertama harus kita lakukan adalah membuat project sederhana, jika teman2 sudah punya project sendiri silahkan gunakan project pribadi. jika belum punya silahkan buat project sederhana pakek express-generator agar lebih cepat.

  • install express-generator npm install -g express-generator
  • buat project express express <nama-project> --view=ejs

nama-project dengan nama project yang teman2 mau, seperti contoh gambar di bawah saya menggunakan gitlab-ci sebagai nama project.

1. 2. Buat Dockerfile untuk build image docker

jika langkah satu sudah selesai, sekarang masuk ke folder project teman2 dan buat file baru namanya Dockerfile kemudian buat code seperti berikut

FROM keymetrics/pm2:10-alpineRUN apk update && apk upgrade && \
apk add --no-cache \
bash \
git \
curl \
openssh
MAINTAINER Muhammad ZakyRUN mkdir -p /usr/src/apps
WORKDIR /usr/src/apps
COPY package*.json ./
RUN npm cache clean --force
RUN npm install
COPY . .
EXPOSE 3000CMD [ "pm2-runtime", "start", "pm2.json", "--env", "production"]

saya tidak akan menjelaskan secara detail code Dockerfile di atas, kalau teman2 banyak yang tidak mengerti tolong komentar agar nanti kita buat tutorial khusus untuk belajar docker.

intinya di code Dockerfile di atas kita ngejalanin pm2 untuk ngejalanin aplikasi expressJS kita di docker.

selanjutnya kita butuh config sederhana untuk untuk pm2, buat file dengan nama pm2.json dalam directory project kita kemudian isi code berikut(di ketik jangan dicopas)

{
"name": "gitlab-ci",
"script": "./bin/www",
"instances": "1"
}

script pm2.json berfungsi untuk konfigurasi pm2 agar menjalankan apps seperti kemauan kita. jika di project teman2 file indexnya itu index.js ganti ./bin/www ke index.js. begitu juga kalau teman2 menggunakan server.js.

didalam Dockerfile kita perintah COPY . . itu berfungsi untuk mengcopy semua isi project kita ke dalam image docker, agar folder node_modules tidak ikut tercopy, kita harus membuat file .dockerignore yang isinya

node_modules

dengan begini folder node_module tidak akan tercopy ke docker image kita.

1. 3. Build docker image

di langkah 2 kita sudah membuat Dockerfile, sekarang waktunya kita eksekusi Dockerfile, dan ngebuild image docker yang isinya project kita. ketikkan perintah berikut (DIKETIK jangn di copas).

docker build --tag <nama-project>:<tag> .
  • nama-project ganti dengan nama project teman2
  • tag ganti dengan versi tag yang kalian mau.

berikut contohnya :

jika langkah di atas berhasil, sekarang seharusnya di laptop teman2 sudah ada images docker baru dengan nama yang teman2 buat tadi. untuk memastikan gunakan perintah docker images.

1. 4. Menjalankan Docker Image

sekarang kita sudah punya sebuah image docker yang isinya adalah project express sederhana yang baru saja kita buat tadi dengan nama gitlab-ci. nah sekarang kita akan menjalankan image tersebut ke dalam container dengan nama gitlabCIContainer kemudian nge mapping port 3000 yang di gunakan di container ini. berikut perintah untuk menjalankan container

docker run -p 3000:3000 -d --name <nama-container> <nama-image>:<tag>

karena nama-container yang saya inginkan gitlabCiContainer, nama-image = gitlab-ci dan tag = 1.0 jadi perintah untuk menjalankan container jadi seperti berikut

docker run -p 3000:3000 -d --name gitlabCiContainer gitlab-ci:1.0

jika perintah di atas berhasil, seharusnya sekarang kita sudah punya container yang sedang berjalan di local kita, untuk mengecek container yang sedang berjalan bisa menggunakan perintah docker ps. berikut contohnya

sekarang kita bisa mencoba mengakses ke localhost:3000 dan hasilnya akan sebagai berikut :

Yeaaaayyy… kita sudah berhasil menjalankan express menggunakan docker di local kita, sekarang kita akan membuat pipeline di gitlab-ci untuk membuat automation deploy code dan menjalankan code kita di server.

2. Setup Gitlab-CI

sebelum membuat pipeline Gitlab-CI kita harus pastikan code kita menggunakan repository gitlab, boleh github gak? ya tidak boleh, kan kita pakek gitlab-ci masak malah pakek repository github.

2. 1. Membuat Project di Gitlab

pastikan teman2 sudah mempunya akun gitlab, kemudikan login ke akun gitlab dan buat project baru di gitlab. seperti gambar di bawah ini atau bisa langsung klik link berikut https://gitlab.com/projects/new#blank_project

isi data yang di perlukan sesuai dengan kebutuhan teman2, kemudian klik Create Project. jika sudah sekarang waktunya kita nge push project di local kita tadi ke gitlab, dengan cara seperti berikut

cd existing_folder
git init
git remote add origin <url-repository>
git add .
git commit -m "Initial commit"
git push -u origin master

url-repository ganti dengan url repository teman masing2, berikut contohnya :

jika sudah dan berhasil, seharusnya sekarang di gitlab teman2 sudah ada isi file dan code teman2 seperti punya saya di bawah ini.

2. 2. Membuat Pipeline .gitlab-ci.yml

sekarang waktunya kita membuat pipeline, balik ke project teman2. kemudia buat file baru dengan nama .gitlab-ci.yml dan isi code seperti di bawah ini, di ketiiik jangan di copaaaaas

stages:
- build
- deploy
build:
stage: build
image: node
script:
- echo "Disini Build Docker"
- echo "Build successfully!"
test:
stage: deploy
image: node
script:
- echo "Disini Deploy Docker"
- echo "Deploy successfully!"

penjelasan script :

stages di baris merupakan perintah untuk menentukan ada berapa stage atau job di pipeline kita, nah disini saya membuat ada 2 job yaitu untuk membuild image docker di build dan mendeploy code ke server kita di stage deploy.

image merupakan perintah untuk inisialiasi penggunaan image docker apa untuk menjalankan script di bawahnya.

script perintah yang akan kita gunakan untuk tiap2 stage/job.

jika code .gitlab-ci.yml di rasa sudah benar, teman2 bisa commit dan push ke gitlab.

- git add .
- git commit -m "add gitlab-ci pipeline"
- git push

2. 3. Mengecek Status Pipeline

untuk mengecek apakah pipeline yang kita buat tadi sudah work atau tidak teman2 bisa cek di menu CI/CD -> Pipelines di gitlab masing2, seperti contoh di bawah.

jika pipeline teman2 sudah benar, akan ada kelihatan di sana pipeline yang passed itu artinya job/stage di pipeline tadi sudah berhasil di kerjakan semua.

jika teman2 meng klik tombol passed di atas, akan keluar detail job dari pipeline tersebut. teman2 bisa klik di job masing2 untuk melihat proses job secara detail.

sampai disini kita sudah berhasil membuild image docker untuk project kita dan membuat pipeline di gitlab-ci.

3. Build Image Docker di Gitlab-CI dan Push ke Registry Gitlab

agar image docker dari project kita mudah di gunakan di mana saja, kita harus menyimpan image tersebut di sebuah registry, bisa menggunakan hub.docker.com atau gitlab registry . karena di tutorial ini kita menggunakan gitlab-ci, jadi sekalian saja kita akan menggunakan gitlab registry untuk menyimpan image docker kita.

sekarang kembali ke file .gitlab-ci.yml di project kita masing2, kemudian ubah code di bagian build sebagai berikut

stages:
- build
- deploy
build:
stage: build
image: docker:latest
services:
- name: docker:19.03.8-dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- echo "Disini Build Docker"
- docker build --pull -t "$CI_REGISTRY_IMAGE" .
- docker push "$CI_REGISTRY_IMAGE"
- echo "Build successfully!"
test:
stage: deploy
image: node
script:
- echo "Disini Deploy Docker"
- echo "Deploy successfully!"

disini kita menambah perintah before-script yang artinya perintah ini akan di jalankan sebelum perintah di dalam script di jalankan.

docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"

perintah di atas kita gunakan untuk login ke gitlab registry, variable $CI_REGISTRY_USER dan $CI_REGISTRY_PASSWORD merupakan variable default dari gitlab, ada beberapa variable yang sudah di sediakan oleh gitlab teman2 bisa cek disini.

docker build --pull -t "$CI_REGISTRY_IMAGE" .

perintah ini kita gunakan untuk build image di dalam gitlab-ci, dengan nama image sesuai dengan nama registry repository kita di gitlab.

docker push "$CI_REGISTRY_IMAGE"

perintah di atas berfungsi untuk nge push image yang sudah berhasil di build ke registry gitlab.

sekarang commit dan push perubahan kita terakhir ke gitlab, tunggu job di pipelinenya selesai. untuk memastikan bahwa image berhasil di push ke gitlab registry teman2 bisa buka dipackages & registries -> container registry seperti gambar di bawah

sampai disini kita sudah berhasil build image dan push ke gitlab registry, langkah selanjutkan adalah menjalankan image ini di server kita masing2.

4. Automation Deploy To Server/VPS

sebelum membuat automation deploy melalui gitlab-ci.yml kita harus memastikan server kita sudah terinstal docker dan sudah punya akses SSH menggunakan private key.

4. 1. Running Docker di Server

sekarang login ke server teman2

ssh root@<server-ip>

setelah login pastikan docker sudah berjalan di server dengan docker -v jika ternyata docker belum berjalan silahkan install docker di server teman2. jika sudah berjalan hasilnya sebagai berikut :

4. 2. Login dan pull image dari registry gitlab

jika docker sudah berjalan di server, sekarang kita akan login ke registry gitlab seperti perintah berikut :

docker login registry.gitlab.com

isi username dan password sesuai dengan akun teman2, seperti contoh di bawah :

jika sudah berhasil login, sekarang teman2 sudah punya akses untuk pull image dari registry gitlab, gunakan perintah berikut untuk pull image

docker pull <url-registry-repository>

url-registry-repository di ganti dnegan url registry project teman masing2. untuk mendapatkan link url registry repository buka di halaman container registry, kemudian klik icon file di depan nama image. seperti contoh di bawah.

berikut di bawah contoh jika pull image berhasil.

jika pull image sudah berhasil, sekarang seharusnya di server teman2 sudah ada image docker baru dengan nama sesuai url registry teman masing2. untuk mengecek apakah image sudah tersedia gunakan peruntah

docker images

kita bisa lihat ada image baru dari gitlab, sekarang kita akan jalankan image tersebut seperti yang kita jalan di local tadi sebelumnya.

docker run -p 3000:3000 -d --name <nama-container> <nama-image>

dan jika sudah berhasil silahkan buka di browser teman2 dengan url <server-ip>:<port> seperti contoh bawah

dan tadaaaaa…. kita berhasil jalanin expressjs di server. caranya mudahkan? tapi kita bisa buat lebih mudah lagi dengan automation. mari lanjutkan

4. 3. Generate SSH Private Key

langkah awal agar gitlab-ci bisa otomatis menjalankan perintah untuk running docker di server kita adalah dengan memberi akses ke gitlab-runner(service yang jalan di gitlab ci). sekarang kita akan generate private ssh key, gunakana perintah berikut, jika teman2 sudah pernah generate skip perintah ini.

ssh-keygen -m PEM -t rsa -b 4096 -C "emailkamu@zakyganteng.com"

jika berhasil, seharusnya sekarang punya file id_rsa di machine kita, sekarang copy isi dari file tersebut. kalau belum tau cara jalankan

cat ~/.ssh/id_rsa

kemudian copy isi dari file yang sudah keluar di terminal kita. kita akan gunakan isi file ini sebagai variable di gitlab. kemudian jalan perintah berikut untuk memberikan akses

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

4. 4. Membuat Variable di Gitlab

sekarang buka menu setting -> CI/CD di halaman project di gitlab teman2. seperti di bawah

di halaman setting->CI/CD scroll sampai ketemu variable kemudian klik di add variable

dan isi ke dengan SSH_PRIVATE_KEY kemudian paste isi file id_rsa yang sudah kita copy tadi column value, sekarang di paste jangan di ketik, keriting jari kalau di ketik ini. dan di type pilih file.

4. 5. Menambah Script Deploy Code di Gitlab-CI

oke, sekarang kembali ke file gitlab-ci.yml di folder project masing, dan ubah script di bagian deploy seperti berikut :

stages:
- build
- deploy
build:
stage: build
image: docker:latest
services:
- name: docker:19.03.8-dind
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- echo "Disini Build Docker"
- docker build --pull -t "$CI_REGISTRY_IMAGE" .
- docker push "$CI_REGISTRY_IMAGE"
- echo "Build successfully!"
test:
stage: deploy
image: kroniak/ssh-client
before_script:
- exho "mulai deploy ke server"
script:
- chmod 400 $SSH_PRIVATE_KEY
- ssh -o StrictHostKeyChecking=no -i $SSH_PRIVATE_KEY root@198.211.43.48 "docker pull registry.gitlab.com/muhammad.zaky/gitlab-ci"
- ssh -o StrictHostKeyChecking=no -i $SSH_PRIVATE_KEY root@198.211.43.48 "docker stop gitlab-ci-container || true && docker rm gitlab-ci-container || true"
- ssh -o StrictHostKeyChecking=no -i $SSH_PRIVATE_KEY root@198.211.43.48 "docker run -p 3000:3000 -d --name gitlab-ci-container registry.gitlab.com/muhammad.zaky/gitlab-ci"

sekarang commit dan push perubahan terakhir ke gitlab, jika code teman2 sudah benar hasilnya akan seperti di bawah ini, untuk buka ini buka job di pipeline gitlab teman2.

jika gagal karena error connet ke server menggunakan ssh, pastikan folder ~/.ssh sudah di beri akses 755 . gunakan perintah berikut :

- sudo chmod 755 ~/.ssh
- sudo chmod 600 ~/.ssh/id_rsa
- sudo chmod 600 ~/.ssh/id_rsa.pub

5. Tes Gitlab CI/CD

nah, kita sudah sampai di penghujung acara kita hari ini. jika semua langkah sudah teman2 ikuti, sekarang kita akan coba ubah code di local kita kemudian kita push ke gitlab, dan kita lihat apakah code di server juga akan berubah! jika iya, berarti kita sudah berhasil membuat automation deploy.

buka file view/index.ejs dan ubah seperti berikut : atau terserah teman2 mau ubah gimana

<!DOCTYPE html>
<html>
<head>
<title>
<%= title %>
</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1>
<%= title %>
</h1>
<p>Welcome bro Muhammad Zaky, jangan lupa bahagia</p>
</body>
</html>

sekarang commit dan push perubahan code terakhir kita, tunggu beberapa saat sampai job di pipeline gitlab kita selesai semua. kalau sudah selesai coba buka lagi url server kita tadi. daaaaan hasiiiiiillllnyaaa tadaaaaaaaa kita berhasiiiil…..

Penutup

teman2 kita sudah berhasil membuat pipeline CI/CD menggunakan gitlab-ci, masih ada banyak hal yang bisa teman2 explore lebih dari artikel ini. CI/CD itu sangat luat.

Terima kasih buat yang sudah like, share and subcribe, eh sorry ini bukan youtube ya. pokoknya terima kasih buat yang udah baca sampai sini.

sampai jumpa di tutorial lainnya, semoga bermanfaat.

jangan lupa bahagia.

--

--