Docker

Kelly William
Basic People
Published in
5 min readApr 17, 2019

Seiring berjalannya waktu, proses pengembangan suatu aplikasi menjadi semakin mudah dengan berbagai tools yang tersedia.

Dalam membangun sebuah program, pengembang perlu menjalankan virtualisasi pada server untuk mengecek apakah program dapat berjalan pada berbagai platform maupun konfigurasi. Masalah yang dihadapi disini adalah virtualisasi memerlukan satu OS secara utuh, sehingga dapat dibayangkan dengan banyaknya virtualisasi yang berjalan di sebuah server akan memberatkan sistem.

Dari situ, muncullah sebuah teknologi yang dinamakan container. Dengan adanya container, sebuah program ‘digabungkan’ dengan library-nya, file konfigurasi, dan seluruh hal yang dibutuhkan. Perbedaan yang sangat terlihat dibandingkan dengan virtualisasi adalah container memakan memori yang lebih sedikit karena tidak perlu menyiapkan OS secara penuh, sehingga sering disebut juga sebagai lightweight platform. Aplikasi yang berjalan menggunakan container pun jauh lebih cepat dan lebih efisien.

Docker merupakan salah satu platform yang dibangun berdasarkan teknologi container. Docker dilengkapi dengan fitur sandbox yang menjamin pengerjaan pengembang dan sysadmin tidak terganggu. Sandbox pada istilah keamanan komputer adalah mekanisme pemisahan aplikasi atau program tanpa menggangu host (isolasi). Sandbox menjamin aplikasi dapat berjalan tanpa ada gangguan atas perubahan lingkungan host. Docker dapat menjamin program yang dibuat akan selamanya berjalan seperti seharusnya dan dapat berjalan lancar pada kondisi lingkungan manapun.

Kenapa kita memakai docker?

  • Docker menyediakan portabilitas. Sebuah kontainer dapat dengan mudah di porting antar lingkungan yang mencapai konsistensi dan fungsi serupa (asalkan host OS mendukung Docker).
  • Kontainer Docker memastikan konsistensi di beberapa siklus pengembangan dan rilis, standarisasi lingkungan. Wadah Docker bekerja seperti repository GIT, yang memungkinkan untuk melakukan perubahan ke Image Docker dan mengendalikan versi.
  • Docker memastikan aplikasi dan sumber daya yang terisolasi seara terpisah.
  • Docker menggunakan OS host mount point sensitif (‘/proc’, ‘/sys’) sebagai read-only mount point dan menggunakan file system copy-on-write untuk memastikan kontainer tidak bisa membaca data satu sama lain.

Pengimplementasian Docker pada projek KSP:

Untuk membuat sebuah docker image, diperlukan sebuah file yang dinamakan Dockerfile pada root directory. Setiap Dockerfile merupakan sebuah skrip, yang terdiri dari beberapa commands (instruksi) dan argumen yang disusun secara berurutan untuk melakukan tindakan secara otomatis pada images untuk membuat images yang baru.

Isi dari dockerfile pada projek kami

Dockerfile diawali dengan FROM yang mendefinisikan base image untuk memulai build process [Command: FROM [image name]]. Disini kami menggunakan base image nginx:alpine sebagai konfigurasi dalam pembuatan docker image. Setelah itu, terdapat COPY (hampir mirip ADD) yang memberitahu file file apa saja yang harus di copy ke docker image dengan catatan memberi lokasi spefisik file file tersebut [Command: COPY [spesific location]]. Kemudian, terdapat EXPOSE yang digunakan untuk menentukan port mana saja secara spesifik yang dapat digunakan untuk mengaktifkan jaringan antara proses yang sedang berjalan didalam container dengan lainnya [Command: EXPOSE [port]] (Disini, kami menggunakan port 21650, 21600, dan 21630 yang telah disediakan oleh pihak PPL Fasilkom). Terakhir, terdapat CMD (hampir mirip RUN) yang digunakan untuk mengeksekusi command yang diberikan secara spesifik [Command: CMD application “argument”, “argument”, …].

*tambahan: terdapat instruksi instruksi lain yang dapat dilihat disini.

Untuk membuat image, kita dapat menggunakan syntax:

docker build -t my-react-app .

pada syntax diatas, kita menyimpan app menjadi image dengan tag (-t) “my-react-app .”

Coba-coba docker, menggunakan laptop rekan saya

Untuk run image, kita dapat menggunakan syntax:

docker run -p 80:80 my-react-app

pada syntax diatas, kita melakukan run image “my-react-app” pada port (-p) 80. Perlu diketahui bahwa 80 pertama menunjukkan host’s port dan 80 kedua menunjukkan container’s port.

Pada code diatas, dapat dilihat bahwa kita mengassign host port ke 80 dan container port ke 80 juga, namun kenapa port yang dapat digunakan sebagai hasil kompilasi docker adalah port 21650?

Pertama-tama, kita harus dapat membedakan EXPOSE dan PORTS.

Pada PORTS, port-port yang disebutkan dalam docker-compose.yml akan dibagi di antara berbagai layanan yang dimulai oleh docker-compose.

Pada EXPOSE, port-port tidak terpapar ke mesin host, hanya terpapar ke layanan lain.

Secara garis besar, PORT digunakan apabila container harus mendengarkan port tertentu dari luar maupun dalam docker itu sendiri, dan EXPOSE digunakan apabila container hanya mendengarkan port dari dalam docker itu sendiri (TIDAK BERLAKU UNTUK LUAR DOCKER).

Pada EXPOSE juga berlaku hanya 1 PORT yang dapat dispesifikasikan. Di awal dockerfile, telah dituliskan bahwa hasil dari docker akan ditampilkan pada PORT 21650, 21600, dan 21630. Disini, akan dilakukan pengecekan PORT (tulisan terawal / dari kiri) mana yang sedang senggang, kemudian akan menampilkannya pada PORT tersebut (dalam kasus ini PORT 21650 karena ditulis pada PORT paling awal). 80:80 hanya berperan sebagai host port dan container port, dimana hanya berperan sebagai port untuk berbagi layanan.

Hasil dari docker image:

Penggunaan Docker dalam Continous Integration dan Quality Assurance pada projek KSP:

Projek yang kami buat menggunakan gitlab yang menyediakan layanan CI/CD pipeline. Dalam penyiapan CI, kita dapat menggunakan pipeline gitlab dengan mengedit/menambahkan .gitlab-ci.yml

isi dari .gitlab-ci.yml pada projek kami

Terdapat 3 stages, yaitu stage build, test, dan deploy-staging

Stage build digunakan untuk membangun react app menggunakan syntax npm run build. Fungsi dari stage ini adalah untuk mengupdate react app yang kami buat ke versi terbarunya.

Stage test digunakan untuk mengetes react app menggunakan syntax npm run test. Fungsi dari stage ini adalah untuk memastikan semua fungsi berjalan dengan baik. Test ini juga terbagi lagi menjadi dua, yaitu test coverage dan test lint.

Test coverage memastikan apakah test yang dibuat telah mencakupi seluruh fungsi yang ada. Apabila terdapat fungsi yang belum tercakupi, nilai coverage menurun. Test lint memastikan penulisan code sudah sesuai dengan ketentuan yang berlaku. Apabila penulisannya tidak sesuai, test-lint akan memberikan letak penulisan yang tidak sesuai tersebut.

Contoh Test Coverage pada projek kami. Saat ini mencapai 90%!
Salah satu kegunaan dari test-lint, apabila terdapat var yang diassign tapi tidak dipakai, akan muncul warning dan menyebabkan build failed (karena process.env.CI = true yang menyebabkan semua warning sebagai error)

Stage terakhir adalah deploy-staging, yang digunakan untuk melakukan deploy ke branch staging kami. Di stage ini, kita mendeploy image untuk ditest sebelum dimasukkan ke staging. Stage ini menggunakan image gitlab/dind:latest yang menyediakan layanan dan dapat dijalankan di docker. Pertama-tama, kita pull docker images yang tersedia pada web docker kami, yaitu pada registry.docker.ppl.cs.ui.ac.id/ppla6/stagingimage. Kemudian, menjalankan docker build berdasarkan images yang tersedia pada gitlab/dind:latest. Setelah itu, kita menambahkan tag docker pada docker image yang baru di build + latest. Terakhir, kita push docker image tersebut ke web docker.

Sekian dari saya mengenai Docker dan Implementasi CI + QA kami. Terima kasih~

--

--