Container Port
Secara default, saat kita membuat container menggunakan docker create
atau docker run
kita tidak akan bisa mengakses container tersebut dari internet. Untuk membuat sebuah container dapat diakses dari internet. Kita perlu menambahkan --publish
atau -p
. Berikut adalah contoh command nya :
Syntax:
docker create -p publishPort:containerPort --name containerName imageName:tag
publishPort
: port yang diatur agar bisa diakes dari internet
containerPort
: port yang dihasilkan oleh container
studi kasus: Saya akan mencoba membuat container menggunakan image nginx. Secara default, nginx akan menghasilkan port 80 untuk diakses. Dan agar nginx bisa diakes dari internet, saya akan mempublish nginx ini ke port 3222. Jadi jika dirunutkan adalah sebagai berikut:
image: nginx:latest
containerPort: 80
publishPort: 3222
Command:
docker run -d --publish 3222:80 --name nginx-2 nginx:latest
Hasil:
Container Environment Variable
Selanjutnya adalah Environment Variable. Untuk mengatur Env Variable saat membuat sebuah container menggunakan docker create
atau docker run
kita bisa menambahkan --env KEY="value"
. Sebagai contoh praktik saya akan menggunakan image mongo. Pada image mongo, kita bisa mengatur user dan password yang nanti digunakan sebagai auth ketika ingin menggunakan db nya. Detail nya adalah sebagai berikut:
image: mongo:latest
user ENV: MONGO_INITDB_ROOT_USERNAME
pw ENV: MONGO_INITDB_ROOT_PASSWORD
publishPort: 3113
containerPort: 27017 (default)
Command:
docker run -d --name mongodb-2 -p 3113:27017 \
--env MONGO_INITDB_ROOT_USERNAME=hifni \
--env MONGO_INITDB_ROOT_PASSWORD=hifni \
mongo:latest
Hasil:
Test koneksi menggunakan MongoDB Compass:
Container Resource Limit
Ketika kita membuat sebuah container. Maka container bisa memakai seluruh resource (CPU, RAM, dsb) yang kita miliki. Jika terjadi sebuah accident yang membuat aplikasi didalam container yang kita miliki maka akan ber-impact terhadap container yang lainnya dan berdampak terhadap server/host dari container. Contoh kita memiliki 4 container aktif yang tidak kita limit reource nya. Kemudian ada 1 container yang error dan menyebabkan ia jadi menggunakan 100% dari kapasitas CPU. Maka container lainnya pun akan terdampak. Untuk menghindari kejadian seperti itu, maka salah satu langkahnya adalah dengan menetapkan "Resource Limit".
Untuk membatasi penggunaan maksimal dari CPU saya akan menggunakan opsi --cpus=<value>
. Misal saya memiliki CPU dengan 4 core dan saya ingin container hanya boleh menggunakan maksmal 2 core maka begini cara nya --cpus=2
atau container hanya boleh menggunakan 1/2 core. Maka seperti ini format nya--cpus=0.5
.
Setelah itu, untuk mengatur limit dari penggunaan RAM saya akan menggunakan opsi --memory=<value>
dan suffix yang tersedia adalah sebagai berikut:
b = bytes
k = kilobytes
m = megabytes
g = gigabytes
Jadi jika saya ingin membatasi container hanya boleh menggunakan maksimal 2gb dari keseluruhan ram yang saya miliki format penulisannya adalah seperti ini --memory=2g
atau --memory=2000m
Contoh penggunaan lengkap nya adalah sebagai berikut:
image: nginx:latest
containerName: nginx-with-limit
publishPort: 3114
CPU limit: 1 core
memory/RAM limit: 1.5gb
Command:
docker run -d --name nginx-with-limit -p 3114:80 \
--cpus=1 --memory=1500m nginx:latest
Hasil:
*note: untuk CPU memang tidak terlihat inforasi limit nya berapa ketika kita monitor menggunakan command docker stats
, hanya memory yang ditampilkan informasi limit nya.
Bind Mounts
Secara default, saat kita membuat sebuah container maka storage dari container itu sendiri akan terisolasi dengan storage host maupun storage container lain. Untuk membuat container dapat mengakses directory tertentu dari host atau sebaliknya maka kita bisa menambahkan opsi --mount
ketika membuat container. Berikut parameter yang dibutuhkan.
Parameter | Deskripsi |
type | Jenis mount yang akan dilakukan. Tersedia bind , volume , atautmpfs . Untuk bind mount, gunakan nilai bind . |
source atau src | Lokasi/path di host sistem file yang akan di-mount ke kontainer. |
target atau dst | Lokasi/path di dalam kontainer tempat file atau direktori host akan di-mount. |
readonly | Opsional. Jika diatur ke true , membuat mount menjadi hanya-baca. |
Contoh command:
docker run -d \
-p 3115:80 \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
nginx:latest
Untuk memastikan mount bind nya sudah berhasil, kita bisa mengeceknya menggunakan command docker inspect <containerId/containerName>
Hasil :
Volume
Docker Volume
Selain menggunakan Bind Mounts, kita juga bisa menggunakan volumes sebagai "external storage" dari container yang kita buat.
Fitur Bind Mounts sudah ada sejak Docker versi awal, di versi terbaru direkomendasikan menggunakan Docker Volume
Docker Volume mirip dengan Bind Mounts, bedanya adalah terdapat management Volume, dimana kita bisa membuat Volume, melihat daftar Volume, dan menghapus Volume
Volume sendiri bisa dianggap storage yang digunakan untuk menyimpan data, bedanya dengan Bind Mounts, pada bind mounts, data disimpan pada sistem host, sedangkan pada volume, data di manage oleh Docker
List volume
Untuk menampilkan daftar volume bisa menggunakan command berikut:
docker volume ls
Create volume
Untuk membuat volume bisa menggunakan command berikut:
docker volume create <volumeName>
Remove volume
Dan untuk menghapus volume bisa menggunakan command berikut:
docker volume rm <volumeName>
# CATATAN
# sebelum menghapus volume, pastika volume tidak terkonek dengan
# container tertentu, jika tidak. Maka volume tidak bisa dihapus.
Container Volume
Volume yang sudah kita buat, bisa kita gunakan di container
Keuntungan menggunakan volume adalah, jika container kita hapus, data akan tetap aman di volume
Untuk menghubungkan container dengan volume contoh command nya adalah sebagai berikut:
#contoh 1
docker run -d \
-p 3115:80 \
--name devtest \
-v volumeName:/app \
nginx:latest
# contoh 2
docker run -d \
-p 3115:80 \
--name devtest \
--mount type=volume,source=volumeName,target=/app \
nginx:latest
Contoh Detail
Studi Kasus
Saya sedang mengembangkan aplikasi Node.js yang berjalan di port 3000
. Aplikasi ini menyimpan log di dalam folder /usr/src/app/logs
di container. Dan saya ingin:
Mengedit kode aplikasi di host dan langsung melihat perubahan di container tanpa harus membangun ulang image.
Menyimpan log aplikasi secara persisten di volume Docker agar tidak hilang saat container dihentikan atau dihapus.
Dengan konfigurasi di atas:
Bind mount menghubungkan direktori kode lokal dengan container, sehingga perubahan pada kode di host akan langsung terlihat di container.
Volume
node_logs
akan menyimpan log aplikasi secara persisten.
Command:
# Command 1: Membuat volume
docker volume create node_logs
# Command 2: Menjalankan container sekaligus menghubungkannya
# dengan storage di host dan volume
docker run -d -p 3000:3000 --name node_app \
-v type=bind,source="$(pwd)"/app,destination=/usr/src/app \
-v type=volume,source=node_logs,destination=/usr/src/app/logs \
node:latest
Penjelasan command diatas:
Penjelasan:
-v type=bind,source="$(pwd)"/app,destination=/usr/src/app
:type=bind
: Menghubungkan direktori dari host ke container (bind mount).source="$(pwd)/app"
: Direktori di host (lokal) di mana kode aplikasi Node.js berada.destination=/usr/src/app
: Direktori dalam container di mana kode Node.js akan dimuat.
-v type=volume,source=node_logs,destination=/usr/src/app/logs
:type=volume
: Menggunakan volume Docker untuk menyimpan log yang dihasilkan oleh aplikasi.source=node_logs
: Volume bernamanode_logs
untuk menyimpan log aplikasi.destination=/usr/src/app/logs
: Direktori dalam container di mana log aplikasi akan disimpan.
Network
Docker Network
Saat kita membuat container di docker, secara default container akan saling terisolasi satu sama lain
Docker memiliki fitur Network yang bisa digunakan untuk membuat jaringan di dalam Docker
Dengan menggunakan Network, kita bisa mengkoneksikan container dengan container lain dalam satu Network yang sama
Jika beberapa container terdapat pada satu Network yang sama, maka secara otomatis container tersebut bisa saling berkomunikasi
Saat kita membuat Network di Docker, kita perlu menentukan driver yang ingin kita gunakan, ada banyak driver yang bisa kita gunakan, tapi kadang ada syarat sebuah driver network bisa kita gunakan. Beberapa network driver di docker:
- bridge (default), Semua kontainer dalam satu network bridge dapat saling terhubung, mirip seperti perangkat yang terhubung ke router WiFi di rumah.
host, yaitu driver yang digunakan untuk membuat network yang sama dengan sistem host tanpa isolasi. Seperti menjalankan aplikasi langsung di komputer tanpa pembungkus kontainer. host hanya jalan di Docker Linux, tidak bisa digunakan di Mac atau Windows.
none, yaitu driver untuk membuat network yang tidak bisa berkomunikasi
Contoh penggunaan:
# Command 1: membuat network
docker network create my_network
# Command 2: menjalankan node_app + menghubungkannya dengan my_network
docker run -d --name app --network my_network node_app
# Command 3: menjalankan db + menghubungkannya dengan my_network
docker run -d --name db --network my_network db_image
Dengan cara ini, app
dan db
bisa saling berkomunikasi.
Network List
Berikut adalah cara melihat daftar dari network yang ada di docker:
docker network ls
Output:
Create Network
Berikut adalah cara untuk membuat network di docker:
# Syntax: docker network create network_name
docker network create demo_app_network
Secara default, ketika kita menggunakan command diatas. Maka akan membuat sebuah network yang menggunakan driver “bridge“.
Output:
Delete Network
Berikut adalah cara untuk menghapus docker network:
# Syntax: docker network rm network_name
docker network rm demo_app_network
Output:
Container Network
Setelah kita membuat Network, kita bisa menambahkan container ke network
Container yang terdapat di dalam network yang sama bisa saling berkomunikasi (tergantung jenis driver network nya)
Container bisa mengakses container lain dengan menyebutkan hostname dari container nya, yaitu nama container nya
Berikut adalah contoh penggunaanya:
Buat bridge network:
Jalankan perintah ini untuk membuat jaringan Docker dengan driver bridge:
docker network create my_bridge_network
Jalankan container pertama (misalnya container untuk aplikasi Node.js):
docker run -d --name node_app --network my_bridge_network node:14
Ini akan menjalankan container
node_app
yang terhubung ke jaringanmy_bridge_network
.Jalankan container kedua (misalnya container database seperti MongoDB):
docker run -d --name mongo_db --network my_bridge_network mongo
Container
mongo_db
juga akan terhubung ke jaringan yang sama, sehingga containernode_app
dapat berkomunikasi denganmongo_db
.Koneksikan antar container:
Dalam container
node_app
, kamu bisa mengakses MongoDB dengan menggunakan nama containermongo_db
sebagai hostname.Misalnya, dari aplikasi Node.js di dalam container, kamu bisa konek ke MongoDB seperti ini:
const MongoClient = require('mongodb').MongoClient; const url = 'mongodb://mongo_db:27017'; // Gunakan 'mongo_db' sebagai hostname
Karena kedua container berada dalam jaringan
my_bridge_network
, mereka bisa saling berkomunikasi dengan nama container masing-masing.
Connected Container to Network
Jika containernya sudah terlanjur dibuat, kita juga bisa mengkoneksikan container yang sudah dibuat ke network yang ada. Berikut caranya:
# Syntax: docker network connect network_name container_name
docker network demo_app_network demo_app_1
Disconnected Container from Network
Selain bisa menghubungkan container ke network, kita juga bisa memutuskan koneksinya dari network tersebut. Contoh:
# Syntax: docker network disconnect network_name conainer_name
docker network demo_app_network demo_app_1
Docker Inspect
Docker inspect adalah perintah yang digunakan untuk menampilkan informasi detail tentang objek Docker tertentu, seperti container, image, volume, atau jaringan. Informasi ini meliputi metadata, pengaturan konfigurasi, status, dan detail teknis lainnya terkait objek Docker tersebut.
Pada langkah sebelumnya saya menggunakan docker inspect
untuk memastikan mount bind telah berhasil dilakukan.
Command:
docker inspect <containerId/containerName>
Contoh output:
Dengan docker inspect
kita bisa melihat banyak hal, diantaranya adalah:
Metadata: Informasi metadata tentang objek Docker, termasuk ID, nama, dan label.
Konfigurasi: Pengaturan konfigurasi yang digunakan oleh objek Docker, seperti environment variables, command, dan entrypoint.
Jaringan: Informasi tentang jaringan yang terhubung dengan objek Docker, termasuk alamat IP, port mapping, dan konfigurasi jaringan lainnya.
Volume: Detail volume yang terkait dengan objek Docker, seperti lokasi mount dan konfigurasi volume.
Status: Status saat ini dari objek Docker, seperti apakah objek tersebut sedang berjalan atau berhenti.
Informasi Teknis: Informasi teknis tambahan, seperti path ke direktori yang terkait dengan objek Docker dan detail internal lainnya.
Docker Prune
Docker prune adalah sebuah perintah yang digunakan untuk membersihkan resource Docker yang tidak digunakan, seperti images, containers, networks, dan build caches yang tidak sedang aktif. Tujuan utamanya adalah untuk menghemat ruang penyimpanan dengan menghapus resource yang tidak diperlukan lagi.
Beberapa contoh penggunaan docker prune:
docker prune: Menghapus semua resource yang tidak digunakan, termasuk images, containers, networks, dan build caches.
docker image prune: Menghapus semua images yang tidak digunakan.
docker container prune: Menghapus semua containers yang berhenti atau dihentikan.
docker network prune: Menghapus semua networks yang tidak digunakan.
docker builder prune: Menghapus semua build caches yang tidak digunakan.
docker system prune: Ini merupakan perintah yang paling komprehensif, yang menghapus semua resource yang tidak digunakan, termasuk images, containers, networks, dan build caches.
Kita bisa menambahkan opsi --force
atau -f
untuk memaksa penghapusan tanpa konfirmasi, dan --volumes
untuk juga menghapus volume yang tidak digunakan.
Sebagai contoh, jika kita ingin menghapus semua images yang tidak digunakan dan memaksa penghapusan tanpa konfirmasi, kita dapat menggunakan perintah berikut:
docker image prune -f
Docker prune sangat berguna untuk membersihkan resource yang tidak dibutuhkan lagi dan menghemat ruang penyimpanan, terutama setelah melakukan banyak percobaan atau eksperimen dengan Docker.
Artikel ini adalah catatan saya dari belajar di Programmer Zaman Now - TUTORIAL DOCKER DASAR (BAHASA INDONESIA)