Halo Bakat Digital! Selamat datang kembali di blog Sandi Dharma, kali ini kita akan belajar bagaimana Metode menggunakan multi stage build Ketika Membangun docker image Kepada project laravel kita. Kepada mengikuti materi ini, saya harap Engkau sudah mengetahui apa itu docker ya. Oke, langsung kita mulai.
Dockerfile
Ketika kita Mau Membangun docker image, kita menuliskan perintah-perintah yang digunakan Kepada membangun image yang Mau kita buat dalam sebuah file bernama Dockerfile. Di dalam file Dockerfile, kita menggunakan sebuah base image sesuai dengan stack teknologi project kita. Misalnya, ketika kita Membangun image Kepada project laravel, maka kita Pandai menggunakan base image dari apache. Ketika project kita menggunakan Node JS, maka kita menggunakan base image dari Node. Berikut ini Misalnya Dockefile Kepada project Node JS.
# Menggunakan base image node:alpine
FROM node:alpine
# Membangun directory app, setting working directory
WORKDIR /usr/src/app
# Copy file package.json dan package-lock.json (Kalau Terdapat)
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"]
Apa Itu Multi Stage Build?
Multi stage build adalah menggunakan lebih dari satu statement FROM
dalam Dockerfile. Tiap statement FROM
menggunakan base image yang berbeda sesuai dengan stack yang digunakan. Pada Misalnya Dockerfile di atas, hanya terdapat satu buah statement FROM
Kepada menggunakan image node:alpine
. Hal ini disebabkan karena Misalnya projectnya hanya menggunakan stack Node JS saja. Lampau bagaimana Kalau project kita menggunakan laravel?
Seperti yang kita ketahui, laravel merupakan full stack web framework. Di dalam project laravel, biasanya kita menggunakan composer Kepada depenedency management Node JS Kepada compile asset. Ini berarti kita menggunakan dua buah stack yang berbeda pada project laravel. Sehingga, ketika kita Mau Membangun docker image Kepada project laravel, kita Pandai menggunakan multi stage build.
Apa Keuntungan Menggunakan Multi Stage Build?
Sebenarnya, kita Pandai Membangun docker image Kepada larave tanpa multi stage build, Yakni dengan menginstall Seluruh stack teknologi dalam satu buah base image. Tetapi, hal ini akan Membangun ukuran docker image kita akan menjadi lebih besar. Hal ini akan menjadi sebuah pemborosan ketika kita mendeploy aplikasi kita di server production. Ukuran image yang besar tentunya memerlukan resource server yang besar pula, sehingga berakibat pada biaya server yang membengkak.
Membangun Multi Stage Build Kepada Project Laravel
Oke, setelah penjelasan singkat tentang multi stage build, kita akan mencoba Membangun multi stage build Kepada project laravel. Sebagai informasi, di sini saya akan menggunakan laravel versi 8.0.
Dalam root folder project, buat sebuah file bernama .dockerignore
yang berisi kode berikut:
vendor/
node_modules/
File tersebut berfungsi Kepada mengabaikan file Ketika melakukan perintah copy dalam Dockerfile.
Berikutnya, Tetap dalam root folder project, buatlah sebuah file baru bernama Dockerfile
(tanpa Ekspansi). Berikut ini beberapa perintah yang harus kita tulis dalam file Dockerfile
.
Stage 0: Vendor
Pada stage ini kita akan menggunakan Composer sebagai base image dan menginstall dependency Kepada project laravel kita.
FROM composer:latest AS vendor
WORKDIR /app
COPY composer.json composer.json
COPY composer.lock composer.lock
RUN composer install \
--no-interaction \
--no-plugins \
--no-scripts \
--no-dev \
--prefer-dist
COPY . .
RUN composer dump-autoload
Stage 1: Frontend
Pada stage ini kita akan menggunakan Node JS sebagai base image dan menginstall node modules.
FROM node:alpine AS frontend
WORKDIR /app
COPY resources/css ./resources/css
COPY resources/js ./resources/js
COPY package*.json webpack.mix.js ./
RUN mkdir -p /app/public
RUN npm install
RUN npm run production
Stage 2: App
Pada stage ini kita mengumpulkan kembali file-file yang telah kita install sebelumnya ke dalam satu buah base image yang digunakan Kepada menjalankan aplikasi laravel Yakni php apache.
FROM php:8.0-apache
COPY . /var/www/html
COPY --from=vendor /app/vendor/ /var/www/html/vendor/
COPY --from=frontend /app/public/js/ /var/www/html/public/js/
COPY --from=frontend /app/public/css/ /var/www/html/public/css/
COPY --from=frontend /app/mix-manifest.json /var/www/html/mix-manifest.json
RUN chown -R www-data:www-data /var/www/html
Berikut ini hasil keseluruhan file Dockerfile
Kepada project kita.
FROM composer:latest AS vendor
WORKDIR /app
COPY composer.json composer.json
COPY composer.lock composer.lock
RUN composer install \
--no-interaction \
--no-plugins \
--no-scripts \
--no-dev \
--prefer-dist
COPY . .
RUN composer dump-autoload
FROM node:alpine AS frontend
WORKDIR /app
COPY resources/css ./resources/css
COPY resources/js ./resources/js
COPY package*.json webpack.mix.js ./
RUN mkdir -p /app/public
RUN npm install
RUN npm run production
FROM php:8.0-apache
COPY . /var/www/html
COPY --from=vendor /app/vendor/ /var/www/html/vendor/
COPY --from=frontend /app/public/js/ /var/www/html/public/js/
COPY --from=frontend /app/public/css/ /var/www/html/public/css/
COPY --from=frontend /app/mix-manifest.json /var/www/html/mix-manifest.json
RUN chown -R www-data:www-data /var/www/html
Sekarang kita Pandai coba membuild imagenya menggunakan perintah berikut:
Sebagai Komparasi, saya juga membuild project yang sama, Tetapi dengan menggunakan Metode tradisional Yakni satu stage saja dengan Dockerfile berikut:
FROM php:8.0-apache
# NPM
RUN apt-get update && apt-get install -y npm zip unzip
# Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Copy project
COPY . .
# Composer Install
RUN composer install \
--ignore-platform-reqs \
--no-interaction \
--no-plugins \
--no-scripts \
--prefer-dist
# NPM Install dan compile production
RUN npm install \
&& npm run production
Berikut ini hasil Komparasi ukuran image yang dibuild menggunakan multi stage (tag: 1.0) dan single stage (tag: traditional)
image name | tag | image id | size |
---|---|---|---|
laravel-docker | traditional | b7c3f1233f02 | 1.08GB |
laravel-docker | 1.0 | 4e12df5bace0 | 498MB |
Wow, dapat kita lihat perbedaan yang cukup besar ya Kepada ukuran image.
Hasil
Oke, setelah kita mencoba multi stage build. Kita mendapatkan ukuran image yang cukup lebih kecil dibandingkan dengan menggunakan Metode tradisional. Maka dari itu, mulai sekarang kita biasakan Kepada menggunakan multi stage build Kalau Mau membuild docker image Kepada project laravel. Hal ini selain Ekonomis resource di production, juga Ekonomis resource di komputer local kita.