Halo, kali ini kita akan belajar bagaimana cara menjalankan aplikasi Node.js di Docker. Sebelumnya pasti kamu sudah tau kan apa itu Docker? Kalau belum, kamu bisa baca dulu postingan tentang apa itu docker ya. Intinya Docker adalah platform virtualisasi yang banyak digunakan untuk mendevelop, mengirimkan, dan menjalankan aplikasi kita.

Persiapan

Untuk mengikuti tutorial ini, pastikan kamu sudah menginstall Docker di komputer lokal kamu. Aplikasi yang kita gunakan sebagai contoh kali ini adalah sebuah aplikasi Node.js hasil belajar kita sebelumnya tentang membuat Node.js REST API Menggunakan Express, Sequelize, dan MySQL. Kamu bisa download atau clone repository projectnya di link berikut:

https://github.com/ruangdeveloper/nodejs-rest-api

Modifikasi Konfigurasi Aplikasi

Kalau kamu perhatikan file database.config.js yang ada dalam folder src/configs berisi informasi tentang server database yang kita gunakan. Di situ sebelumnya kita menuliskan konfigurasi secara langsung. Hal ini bukanlah praktik yang baik saat membuat aplikasi, karena kita akan kesulitan mengganti konfigurasi saat aplikasi sudah menjadi docker image atau berada di server. Oleh karena itu kita akan menggantinya menggunakan nilai yang diambil dari environment variable. Silahkan modifikasi file konfigurasi menjadi seperti ini:

const process = require("process")

module.exports = {
    HOST: process.env.DB_HOST,
    USER: process.env.DB_USER,
    PASSWORD: process.env.DB_PASSWORD,
    DB: process.env.DB_NAME,
    DIALECT: "mysql",
}

Kita akan mengatur konfigurasi database melalui environment variable ketika ingin membuat docker container.

Membuat Dockerfile

Dockerfile adalah sebuah teks dokumen yang berisi semua perintah atau instruksi yang memberitahu Docker apa yang harus dilakukan ketika membuild image untuk aplikasi kita. Dokumentasi lengkapnya dapat kamu lihat di sini.

Setelah selesai menyiapkan aplikasi, buatlah sebuah file baru bernama Dockerfile (tanpa ekstensi apapun). Bukalah file tersebut menggunakan teks editor favorit kamu.

Hal yang pertama yang harus kita lakukan adalah memberitahu dari image apa aplikasi kita akan di build. Di sini kita menggunakan base image dari node:alpine. Kamu bisa melihat daftar versi yang bisa digunakan di website Docker Hub.

# Menggunakan base image node:alpine

FROM node:alpine

Berikutnya kita akan membuat directory yang menyimpan kode aplikasi kita dalam image yang kita build. Disamping itu, kita juga menentukan working directory untuk aplikasi kita.

# Membuat directory app

WORKDIR /usr/src/app

Base image node:alpine sudah terinstall Node.js dan NPM di dalamnya, sehingga kita hanya perlu menggunakannya untuk menginstall dependency aplikasi kita.

# Copy file package.json dan package-lock.json (jika ada)

COPY package*.json ./

# Menginstal dependency

RUN npm install

Setelah itu kita cunakan perintah COPY untuk membundle source aplikasi kita ke dalam image.

# Bundle source

COPY . .

Aplikasi kita dijalankan pada port 3000, maka kita gunakan perintah EXPOSE untuk memberitahu bahwa kita menggunakan port 3000.


EXPOSE 3000

Terakhir, definisikan perintah untuk menjalankan aplikasi menggunakan CMD.

CMD ["node", "src/app.js"]

Akhirnya seluruh file Dockerfile kita akan menjadi seperti ini:

# Menggunakan base image node:alpine

FROM node:alpine

# Membuat directory app, setting working directory

WORKDIR /usr/src/app

# Copy file package.json dan package-lock.json (jika ada)

COPY package*.json ./

# Menginstal dependency

RUN npm install

# Bundle source

COPY . .

# Expose port (for documentation)

EXPOSE 3000

# Run the app

CMD [ "node", "src/app.js"]

Membuat .dockerignore

Untuk menghindari module npm di local komputer kita tersalin ke dalam docker image, kita perlu membuat file baru bernama .dockerignore. Isi dari file ini kurang lebih seperti berikut:

node_modules

Membuat Docker Compose

Karena aplikasi kita memerlukan database, maka kita akan memanfaatkan fitur docker compose untuk mempermudah kita menjalankan aplikasi. Pada root folder project buatlah sebuah file baru bernama docker-compose.yaml, yang didalamnya berisi kode seperti berikut ini:

# optional since v1.27.0
version: "3.9"
# list service
services:
  # mendefinisikan database service
  database:
    # menggunakan image mysql:latest
    image: "mysql:latest"
    # port untuk database mysql
    ports:
      - "3306:3306"
    # setting environment variable untuk mysql
    environment:
      MYSQL_DATABASE: nodejs_rest_api
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: db_user
      MYSQL_PASSWORD: db_password
  # mendefinisikan web service
  web:
    # build image berdasarkan Dockerfile
    build: .
    # port untuk web service
    ports:
      - "3000:3000"
    # jalankan web service setelah database service berjalan
    depends_on:
      - database
    # setting environment variable untuk koneksi Database
    # (sesuaikan dengan database service)
    environment:
      DB_HOST: database
      DB_USER: db_user
      DB_PASSWORD: db_password
      DB_NAME: nodejs_rest_api
    # restart saat terjadi error
    restart: always

Menjalankan Aplikasi

Nah ini adalah bagian yang kita tunggu…

Dockerfile sudah dibuat, .dockerignore sudah dibuat, docker-compose.yaml juga sudah dibuat. Kini saatnya kita jalankan aplikasi kita.

Buka terminal, pastikan kamu berada dalam folder root project. Kemudian jalankan perintah berikut ini.

docker compose up -d

output:

$ docker compose up -d
[+] Building 0.3s (10/10) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                   0.0s
 => => transferring dockerfile: 32B                                                                                                                    0.0s
 => [internal] load .dockerignore                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                        0.0s
 => [internal] load metadata for docker.io/library/node:alpine                                                                                         0.0s
 => [1/5] FROM docker.io/library/node:alpine                                                                                                           0.0s
 => [internal] load build context                                                                                                                      0.0s
 => => transferring context: 4.21kB                                                                                                                    0.0s
 => CACHED [2/5] WORKDIR /usr/src/app                                                                                                                  0.0s
 => CACHED [3/5] COPY package*.json ./                                                                                                                 0.0s
 => CACHED [4/5] RUN npm install                                                                                                                       0.0s
 => [5/5] COPY . .                                                                                                                                     0.1s
 => exporting to image                                                                                                                                 0.1s
 => => exporting layers                                                                                                                                0.0s
 => => writing image sha256:436b4327e640e3221d913ed99f3a64fc1b2ce08ad102c80f89dcef0c877a37fc                                                           0.0s
 => => naming to docker.io/library/nodejs-rest-api_web                                                                                                 0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[+] Running 3/3
 - Network nodejs-rest-api_default       Created                                                                                                       1.0s
 - Container nodejs-rest-api-database-1  Started                                                                                                       2.1s
 - Container nodejs-rest-api-web-1       Started                                                                                                       3.3s

(note: output tidak akan terlihat sama persis dengan yang ada di komputer kamu)

Docker compose akan membuild image untuk aplikasi kita dan menjalankan dua buah container, satu untuk database dan satu lagi untuk aplikasi kita.

Setelah container dijalankan, kamu bisa mencoba mengakses api endpoint menggunakan browser atau aplikasi rest client seperti Insomnia atau Postman dengan alamat host berikut:

http://127.0.0.1:3000/api/books

Berikut ini adalah response yang akan kamu dapat ketika mengakses endpoint

{
  "status": 200,
  "success": true,
  "message": "ok",
  "data": {
    "books": [ ]
  },
  "error": null
}

Data buku kosong karena memang database kita masih kosong ya. Tapi dari sini bisa kita simpulkan bahwa aplikasi kita dapat berjalan menggunakan Docker.

Source code hasil tutorial ini dapat kamu lihat di sini

comments powered by Disqus
Lightbox