# **Modul 1: Introduction of Container** ## 1. Container Docker Container dibutuhkan untuk mengatasi permasalahan kompabilitas di dalam suatu server yang memiliki beberapa aplikasi yang berjalan sekaligus. Biasanya setiap aplikasi membutuhkan dependesi eksternal, permasalahaan muncul disaat dua aplikasi membutuhkan dependesi yang sama tapi beda versi atau ketika ada aplikasi yang akan diupdate. Solusi dari masalah tersebut adalah menggunakan **Container** yang berfungsi sebagai virtual machine ringan yang berisi aplikasi, frameworks, dan libraries. Container sangat berguna karena lebih aman dibandingkan dengan aplikasi yang tidak menggunakan container, karena container menggunakan Linux kernel namespaces untuk sandbox aplikasi yang berbeda di komputer yang sama. Selain itu kita dapat dengan mudah mensimulasikan production-like environment. Yang terakhir container berguna untuk penyediaan infrastruktur dan menjalankan serta memantau aplikasi dalam produksi. berikut adalah contoh Containerized Technology: * Docker * Podman * LXC * LXD ## **2. Host, Virtual Machine and Container** ![image](https://hackmd.io/_uploads/ryVd6V1Cp.png) Bisa dilihat, yang membedakan dedicated machine dan virtual machine adalah dedicated machine menajalankan aplikasi dalam satu software stack, sedangkan virtual machine menjalankan tiga aplikasi dalam dua software stack yang berbeda. ![image](https://hackmd.io/_uploads/ByItAVJR6.png) Diagram ini menjelaskan bahwa docker dapat menghilangkan kebutuhan untuk menggunakan beberapa OS. # **Modul 2: Introduction to Docker** ## **1. Lab 2.1: Instalasi Docker** 1. Lakukan instalasi pada kedua node. Jalankan perintah berikut ``` sudo apt-get update sudo apt-get install ca-certificates curl gnupg lsb-release -y sudo mkdir -m 0755 -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y ``` 2. Setelah melakukan instalasi tambahkan user ke docker group. ``` groupadd docker sudo usermod -aG docker $USER sudo chmod 666 /var/run/docker.sock ``` 3. Tes instalasi docker dengan: ``` docker run registry.adinusa.id/btacademy/hello-world docker image ls ``` ![image](https://hackmd.io/_uploads/BkW3L-lRp.png) Untuk menampilkan container ``` docker container ls -a ``` ![image](https://hackmd.io/_uploads/BJAkDZgCa.png) ## **2. Lab 2.2: Docker Run - Part 1** ### **2.1. Practice 01** 1. Cari image redis dari dockerhub & harbor ``` # From DockerHub docker search redis # From Harbor skopeo list-tags docker://registry.adinusa.id/btacademy/redis ``` 2. Jalankan image redis ``` docker run registry.adinusa.id/btacademy/redis docker run -d registry.adinusa.id/btacademy/redis docker run -d --name redis1 registry.adinusa.id/btacademy/redis ``` ![image](https://hackmd.io/_uploads/Hk2D5-xCa.png) 3. Tampilkan docker yang sedang dijalankan ``` docker ps -a docker container ls -a ``` ![image](https://hackmd.io/_uploads/r1E0cWx0T.png) 4. Untuk menampilkan status-status container dapat menggunakan ``` # docker inspect CONTAINER_NAME/CONTAINER_ID docker inspect redis1 # docker logs CONTAINER_NAME/CONTAINER_ID docker logs redis1 # docker stats CONTAINER_NAME/CONTAINER_ID docker stats redis1 # docker top CONTAINER_NAME/CONTAINER_ID docker top redis1 ``` 5. Matikan container ``` # docker stop CONTAINER_NAME/CONTAINER_ID docker stop redis1 ``` ![image](https://hackmd.io/_uploads/SkI_oWlAp.png) ### **2.2. Practice 02** 1. Cari image nginx di dockerhub dan harbor ``` # From DockerHub docker search nginx # From Harbor skopeo list-tags docker://registry.adinusa.id/btacademy/nginx ``` ![image](https://hackmd.io/_uploads/HJogxGxRT.png) 2. Jalankan image nginx dan ekspos ke port host 80 ``` docker run -d --name nginx1 -p 80:80 registry.adinusa.id/btacademy/nginx:latest ``` ![image](https://hackmd.io/_uploads/S1bpnWeC6.png) 2. Untuk menampilkan deskripsi nginx container dapat menggunakan: ``` docker inspect nginx1 ``` 4. Menjalankan image nginx dan deklarasi container port ``` docker run -d --name nginx2 -p 80 registry.adinusa.id/btacademy/nginx:latest ``` ![image](https://hackmd.io/_uploads/HkozpWgCT.png) 5. Test browsing ``` curl localhost:$(docker port nginx2 80 | cut -d : -f 2) ``` ![image](https://hackmd.io/_uploads/HJ_P6-xCp.png) 6. Menampilkan container (activate/exit) dan image docker ``` # Container docker ps -a docker container ls -a # Image docker docker images ``` ## **3. Lab 2.3: Docker Run - Part 2** ### **3.1. Practice 03** 1. Cari image nginx di dockerhub dan harbor ``` # From DockerHub docker search nginx # From Harbor skopeo list-tags docker://registry.adinusa.id/btacademy/nginx ``` ![image](https://hackmd.io/_uploads/BkxWlzgRa.png) 2. Menjalankan nginx engine dengan nama nginx1 dan ekspos port 8080 ``` docker run -d --name nginx1 -p 8080:80 registry.adinusa.id/btacademy/nginx:latest ``` ![image](https://hackmd.io/_uploads/rygzxzeCa.png) 3. Untuk menampilkan deskripsi nginx container dapat menggunakan: ``` docker inspect nginx1 ``` 4. Menjalankan nginx engine dengan nama nginx2 dan ekspos port 8081 ``` docker run -d --name nginx2 -p 8081:80 registry.adinusa.id/btacademy/nginx:latest ``` ![image](https://hackmd.io/_uploads/BysugGeRa.png) 5. Menampilkan container (activate/exit) ``` docker ps -a docker container ls -a ``` ![image](https://hackmd.io/_uploads/BJCpgMxCa.png) 6. Menampilkan nginx yang ada di container ``` curl localhost:8080 curl localhost:8081 ``` ![image](https://hackmd.io/_uploads/HyTxbMlAp.png) 7. Mengakses container dan update & install editor ``` # Mengakses container docker exec -it nginx2 /bin/bash # Update dan install editor apt-get update -y && apt-get install nano -y ``` ![image](https://hackmd.io/_uploads/ByTOZfgA6.png) 8. Mengubah index.html ``` nano index.html /usr/share/nginx/html/index.html ``` ![image](https://hackmd.io/_uploads/BkObzzlRp.png) 9. restart nginx dan jalankan ulang containernya ``` # Restart nginx service nginx restart # Jalankan container docker start nginx2 ``` 10. Menampilkan nginx output di container ``` curl localhost:8080 curl localhost:8081 ``` ![image](https://hackmd.io/_uploads/B1uaGGe06.png) 11. Menampilkan status-status nginx yang ada di container ``` # Deskripsi container docker inspect nginx1 docker inspect nginx2 # Log content docker logs nginx1 docker logs nginx2 # Resource yang digunakan docker stats nginx1 docker stats nginx2 # Running process docker top nginx1 docker top nginx2 ``` ### **3.2. Practice 04** 1. Cari image ubuntu dari DockerHub & Harbor ``` # From DockerHub docker search ubuntu # From Harbor skopeo list-tags docker://registry.adinusa.id/btacademy/ubuntu ``` ![image](https://hackmd.io/_uploads/SJyKEGlAp.png) 2. Pull image dari harbor ``` docker pull registry.adinusa.id/btacademy/ubuntu ``` 3. Menajalankan ubuntu dan akses console ``` docker run -it --name ubuntu1 registry.adinusa.id/btacademy/ubuntu Exit the container with Ctrl+D or exit docker ps -a ``` ![image](https://hackmd.io/_uploads/S1dmqfxRp.png) 4. Jalankan container ubuntu dan hapus jika ingin keluar dari container ``` docker run -it --rm --name ubuntu2 registry.adinusa.id/btacademy/ubuntu Exit the container with Ctrl+D or exit docker ps -a ``` ## **4. Lab 2.4: Docker Run - Part 3** ### **4.1. Practice 05** 1. Menjalankan container mysql dengan parameter tambahan ``` docker run -d --name my-mysql -e MYSQL_ROOT_PASSWORD=RAHASIA -e MYSQL_DATABASE=latihan05 -p 3306:3306 registry.adinusa.id/btacademy/mysql ``` ![image](https://hackmd.io/_uploads/BJ7I6fx06.png) 2. Pull image phpmyadmin dari harbor. ``` docker pull registry.adinusa.id/btacademy/phpmyadmin:latest ``` ![image](https://hackmd.io/_uploads/Hkr5J7eAp.png) 3. Menjalankan phpmyadmin container dan sambungkan ke mysql container. ``` docker run --name my-phpmyadmin -d --link my-mysql:db -p 8090:80 \ registry.adinusa.id/btacademy/phpmyadmin ``` 4. Tes browsing ``` Buka http://10.10.10.11:8090/ lalu login dengan user: `root` dan password: `RAHASIA` ``` ![image](https://hackmd.io/_uploads/SkXQMmxRa.png) ### **4.2. Practice 06** 1. Jalankan container ubuntu dengan nama ubuntu1 & ubuntu2 lalu lihat list container ``` docker run -dit --name ubuntu1 registry.adinusa.id/btacademy/ubuntu docker run -dit --name ubuntu2 registry.adinusa.id/btacademy/ubuntu docker ps ``` ![image](https://hackmd.io/_uploads/r1veXQe06.png) 2. Pause container ubuntu, lalu bandingkan dengan list container yang sebelumnya ``` docker pause ubuntu1 docker pause ubuntu2 docker ps ``` ![image](https://hackmd.io/_uploads/HyVSXQg0T.png) 3. Untuk melihat penggunaan resource terhadap ubuntu yang dipause dapat menggunakan: ``` docker stats ubuntu1 docker stats ubuntu2 ``` 4. Unpause container ubuntu1. ``` docker unpause ubuntu1 ``` ### **4.3. Practice 07** 1. Menjalankan container database dengan spesifikasi yang dibatasi ``` docker container run -d --name ch6_mariadb --memory 256m --cpu-shares 1024 --cap-drop net_raw \ -e MYSQL_ROOT_PASSWORD=test registry.adinusa.id/btacademy/mariadb:5.5 ``` 2. Membuat container wordpress dan sambungkan ke database container ``` docker container run -d -p 80:80 -P --name ch6_wordpress --memory 512m --cpu-shares 512 \ --cap-drop net_raw --link ch6_mariadb:mysql -e WORDPRESS_DB_PASSWORD=test \ registry.adinusa.id/btacademy/wordpress:5.0.0-php7.2-apache ``` ![image](https://hackmd.io/_uploads/ByNomVgRp.png) 3. Cek log, process, dan resource ``` docker logs ch6_mariadb docker logs ch6_wordpress docker top ch6_mariadb docker top ch6_wordpress docker stats ch6_mariadb docker stats ch6_wordpress ``` ![image](https://hackmd.io/_uploads/BkQ7E4gAp.png) ![image](https://hackmd.io/_uploads/SJWHEVxRp.png) ![image](https://hackmd.io/_uploads/rkt1VVl06.png) 4. Tes Browsing ``` Buka website http://10.10.10.11 ``` ![image](https://hackmd.io/_uploads/SJe5VEeR6.png) # **Modul 3: Managing Docker Container** ## **1. Managing the Life Cycle of Containers** ![image](https://hackmd.io/_uploads/rJU_ZSlCT.png) ![image](https://hackmd.io/_uploads/H1juZBlRT.png) ### **1.1. Membuat container** ![image](https://hackmd.io/_uploads/SJ1iQre0p.png) Docker akan menjalankan command run untuk membuat container baru dari image dan menjalankan proses didalam container. Jika tidak ada container image maka akan secara otomatis mendownload imagenya ![image](https://hackmd.io/_uploads/H1ok4BlAa.png) Setiap kali container dibuat, docker akan membuat **Container ID** secara acak dan unik dan **Name** yang dibuat secara manual. Untuk memberi nama pada container dapat menggunakan --name untuk mendefinisikan nama ### **1.2. Menjalankan Perintah di Container** ![image](https://hackmd.io/_uploads/r1ABBHx06.png) Untuk menjalankan perintah di dalam container dapat menggunakan perintah **exec** diikuti dengan nama container atau container ID. Setelah menjalankan perintah exec, kita dapat menjalankan perintah di dalam container. ## **2. Registry** Registry adalah image storage yang terpusat. Di dalam Registry akan ada banyak image seperti hub.docker.com. Docker Registry diatur oleh Docker Repositories, dimana repository menyimpan semua versi di dalam suatu image. Registry memungkinkan user untuk mengambil image secara lokal serta push image ke dalam registry. Docker private registry sama seperti Docker Registry tapi kita bisa menentukan siapa yang dapat mengakses registry ## **3. Docker Volume** Volume adalah mekanisme untuk menyimpan data oleh Docker container dan digunakan oleh Docker container. Volume memiliki lebih banyak keuntungan dibandingkan Bind Mounts salah satunya adalah Volume lebih mudah untuk back up atau migrasi, Volume lebih aman untuk di bagi ke beberapa container, dan memiliki performa lebih tinggi. ## **4. Docker Network** ### **4.1. Network drivers** Ada beberapa drivers untuk memenuhi kebutuhan networking: * **bridge** * **host** * **overlay**, menyambungkan beberapa Docker daemon dan digunakan untuk melakukan komunikasi swarm service dan container * **macvlan**, untuk memberi container MAC address * **none**, untuk mematikan semua networking disebuah container * **Network plugins**, untuk install plugin third-party ### **4.2. Bridge Networks** Bridge network digunakan untuk memungkinkan container melakukan komunikasi sekaligus menyediakan isolasi dar container yang tidak tersambung ke bridge network ![image](https://hackmd.io/_uploads/H1shQqg0T.png) ### **4.3. Overlay Networks** Overlay network driver membuat network terdistribusi di beberapa Docker daemon hosts. Network yang dibuat berada di atas host-specific networks, memungkinkan container untuk menyambungkan ke network. ![image](https://hackmd.io/_uploads/HySKL9eAT.png) ### **4.3. Host Networking** Jika host network dibuat di sebuah container, network stack container tersebut tidak terisolasi dari Docker host dan containernya tidak mempunyai ip address ## **5. Lab 3.1: Mount Volume** 1. Membuat direktori ``` cd $HOME mkdir -p latihan/latihan01-volume cd latihan/latihan01-volume ``` 2. Membuat file dan container untuk data volume ``` for i in {1..10};do touch file-$i;done sudo docker create -v /my-volume --name my-volume registry.adinusa.id/btacademy/busybox sudo docker cp . my-volume:/my-volume ``` ![image](https://hackmd.io/_uploads/H1WxKqeAp.png) 3. Mount volume ke container ``` docker run --volumes-from my-volume registry.adinusa.id/btacademy/ubuntu ls /my-volume ``` ![image](https://hackmd.io/_uploads/Hyiz5cxRa.png) ## **6. Lab 3.2: Mount Volume with NFS Server** 1. Membuat direktori dan membuat NFS Server dengan docker (di node 01) ``` sudo mkdir -p /data/nfs-storage01/ docker run -itd --privileged --restart unless-stopped -e SHARED_DIRECTORY=/data -v /data/nfs-storage01:/data -p 2049:2049 registry.adinusa.id/btacademy/nfs-server-alpine:12 ``` ![image](https://hackmd.io/_uploads/SJTli9xCa.png) 2. Install package, mount volume di NFS client dan buat file untuk cek volume (di node 02) ``` ssh 10.7.7.20 sudo apt install nfs-client -y sudo mount -v -o vers=4,loud 10.7.7.10:/ /mnt sudo touch /mnt/file1.txt sudo touch /mnt/file2.txt exit ``` ![image](https://hackmd.io/_uploads/H1fRocxRT.png) 3. Lakukan verifikasi di node 01 ``` ls /data/nfs-storage01/ ``` ![image](https://hackmd.io/_uploads/HyJfhqg0T.png) ## **7. Lab 3.3: Mount Volume with Read-only mode** 1. Membuat docker volume, lihat listnya, dan lihat docker volume detail ``` docker volume create my-vol docker volume ls docker volume inspect my-vol ``` ![image](https://hackmd.io/_uploads/S1ef6clAT.png) ![image](https://hackmd.io/_uploads/SykKp5gAa.png) 2. Menjalankan container dengan volume read dan write access ``` docker run -d --name=nginx-rwvol -v my-vol:/usr/share/nginx/html -p 4005:80 registry.adinusa.id/btacademy/nginx:latest ``` ![image](https://hackmd.io/_uploads/BJf5JsgCa.png) 3. Menampilkan ip address dari kontainer ``` docker inspect nginx-rwvol | jq -r '.[].NetworkSettings.IPAddress' ``` ![image](https://hackmd.io/_uploads/B1ao1oeAT.png) 4. Membuat index.html dan pindahkan ke direktori source volume lalu tes browsing ``` sudo echo "This is from my-vol source directory" > index.html sudo mv index.html /var/lib/docker/volumes/my-vol/_data curl http://172.17.0.2 ``` ![image](https://hackmd.io/_uploads/rJfWgsx0a.png) 5. Menjalankan container dengan volume read-only access dan melihat detil nginx-rovol container ``` docker run -d --name=nginx-rovol -v my-vol:/usr/share/nginx/html:ro registry.adinusa.id/btacademy/nginx:latest docker inspect nginx-rovol | jq '.[].Mounts' ``` ![image](https://hackmd.io/_uploads/BJNEgolC6.png) ## **8. Lab 3.4: Volume Driver** 1. Buat /share dan index.html di node02 ``` sudo mkdir /share sudo chmod 777 /share echo "Hello Adinusa!" > /share/index.html ``` 2. Instal plugin sshfs dan set plugin sshfs di node 01 ``` docker plugin install --grant-all-permissions vieux/sshfs docker plugin ls docker plugin disable ffc82daabc2e docker plugin set vieux/sshfs sshkey.source=/home/student/.ssh/ docker plugin enable ffc82daabc2e docker plugin ls ``` ![image](https://hackmd.io/_uploads/rksH7ieAT.png) 3. Membuat docker volume dengan driver sshfs lalu test running container dengan volume ``` docker volume create --driver vieux/sshfs -o sshcmd=student@10.7.7.20:/share -o allow_other sshvolume docker run -d --name=nginxtest-sshfs -p 8090:80 -v sshvolume:/usr/share/nginx/html registry.adinusa.id/btacademy/nginx:latest ``` 4. Tes browsing ``` docker ps curl http://localhost:8090 ``` ![image](https://hackmd.io/_uploads/HJACEjlCp.png) ## **9. Lab 3.5: Default Bridge Network** 1. Lihat list network ``` sudo docker network ls ``` ![image](https://hackmd.io/_uploads/B1t0Ssx06.png) 2. Jalankan 2 alpine container yang menjalankan ash shell ``` docker run -dit --name alpine1 registry.adinusa.id/btacademy/alpine ash docker run -dit --name alpine2 registry.adinusa.id/btacademy/alpine ash docker container ls ``` ![image](https://hackmd.io/_uploads/HJ6kLoeRa.png) 3. Buat docker network dan sambungkan ke container alpine1 dan cek ip address alpine2 ``` docker network create --driver bridge bridge1 docker network connect bridge1 alpine1 docker inspect alpine2 | jq -r '.[].NetworkSettings.IPAddress' ``` ![image](https://hackmd.io/_uploads/HJ9PLigAp.png) 4. Akses alpine1 dan tampilkan ip addressnya ``` docker exec -it alpine1 sh ip add ``` ![image](https://hackmd.io/_uploads/r1LsUilRp.png) 5. Ping ip alpine1, ip alpine2, dan nama alpine2 ``` ping -c 3 8.8.8.8 ping -c 3 172.17.0.3 ping -c 3 alpine2 ``` ![image](https://hackmd.io/_uploads/rJPnDilCT.png) ## **10. Lab 3.6: Host Network** 1. Jalankan container nginx dengan network host dan tes browsing localhost ``` docker run -itd --network host --name my_nginx registry.adinusa.id/btacademy/nginx curl http://localhost ``` ![image](https://hackmd.io/_uploads/ry2lKig0a.png) 2. Verifikasi ip address dan bound port 80 ``` ip add sudo netstat -tulpn | grep :80 ``` ![image](https://hackmd.io/_uploads/r1LHtsl06.png) # **Modul 4: Creating Custom Docker Container Image** ## **1. Docker Image** Image adalah wadah yang menampung layered filesystem. Dalam layered filesystem terdapat base layer yang berada di layer pertama. Di setiap layer terdapat file dan folder yang berisi perubahan pada filesystem sehubungan dengan layer dibawahnya. Layer yang berada di container image adalah immutable yang artinya saat dibuat, layer tersebut tidak bisa diubah hanya bisa dihapus ![image](https://hackmd.io/_uploads/B1J00TlRT.png) Saat Docker Engine membuat container dari image, akan ada writable container layer di layer paling atas ![image](https://hackmd.io/_uploads/BkkrJCxAa.png) ## **2. Lab 4.1: Exploring Dockerfile** ### **2.1. Practice 01** 1. Clone repository dan buat image ``` git clone https://github.com/spkane/docker-node-hello.git --config core.autocrlf=input latihan01 cd latihan01 docker build -t node-latihan01 . ``` ![image](https://hackmd.io/_uploads/ByldWAl0p.png) 2. jalankan container dan akses container ``` docker run -d --rm --name node-latihan01 -p 8080:8080 node-latihan01 curl localhost:8080 ``` ![image](https://hackmd.io/_uploads/Sk9YZ0eAa.png) ### **2.2. Practice 02** 1. Buat direktori latihan2 dan buat dockerfile ``` cd $HOME mkdir latihan02 cd latihan02 vim Dockerfile ``` ![image](https://hackmd.io/_uploads/S1BgzClC6.png) 2. buat image dari Docker file dan tampilkan ``` docker build -t docker-whale . docker image ls ``` ![image](https://hackmd.io/_uploads/Hk_kNReRa.png) ## **2. Lab 4.1: Exploring Dockerfile (Flask Apps)** Login docker terlebih dahulu 1. Buat direktori latihan03 & buat file flask, requirements.txt, Dockerfile ``` cd $HOME mkdir latihan03 cd latihan03 vim app.py vi requirements.txt vim Dockerfile ``` ![image](https://hackmd.io/_uploads/ry7jHCx0a.png) ![image](https://hackmd.io/_uploads/BJQZ8Ax0T.png) ![image](https://hackmd.io/_uploads/H1mXURlCT.png) 2. Buat image dari Dockerfile dan tag image dengan username docker ``` docker build -t flask-latihan03 . docker tag flask-latihan03 alvanm/flask-latihan03:latest ``` ![image](https://hackmd.io/_uploads/BkZsP0eAp.png) 3. Push image ke dockerhub dan jalankan image ``` docker push alvanm/flask-latihan03:latest docker run -d -p 5000:5000 --name flask03 alvanm/flask-latihan03 ``` ![image](https://hackmd.io/_uploads/SJEqO0gR6.png) 4. Tes browsing ``` curl localhost:5000 ``` ![image](https://hackmd.io/_uploads/Skpn9AeCp.png) ## **3. Lab 4.3: Exploring Dockerfile (Quiz)** 1. Buat direktori latihan-quiz01 lalu git clone, setelah itu buat docker file ``` mkdir latihan-quiz01 cd latihan-quiz01/ git clone https://github.com/rivawahyuda/mywebsite.git nano Dockerfile ``` ![image](https://hackmd.io/_uploads/BJuYld-C6.png) ![image](https://hackmd.io/_uploads/HJIdldbR6.png) 2. Buat image latihan-quiz01-image ``` docker build -t latihan-quiz01-image . ``` ![image](https://hackmd.io/_uploads/rJfvbuWAp.png) 3. Jalankan container dengan image tersebut, ekspos dengan port 80 dengan nama quiz01 ``` docker run -d -p 80:80 --name quiz01 latihan-quiz01-image ``` 4. Tes browsing ``` Buka website dengan alamat ip node01 atau http://10.10.10.11 ``` ![image](https://hackmd.io/_uploads/B1ABmdZCa.png) # **Modul 5: Docker Compose** Docker Compose adalah tool yang digunakan untuk menjalankan dan mengatur container yang berjalan di dalam satu docker host. Docker Compose menggunakan file yaml/yml sebagai input yang memiliki sifat deklaratif. ## 1. **Lab 5.1: Using Docker Compose** 1. Download dan install Compose di kedua node lalu lihat versinya ``` sudo curl -L --resolve raw.githubusercontent.com:443:185.199.108.133 https://github.com/docker/compose/releases/download/v2.24.6/docker-compose-linux-x86_64 -o /usr/bin/docker-compose && \ sudo chmod 755 /usr/bin/docker-compose ``` ![image](https://hackmd.io/_uploads/HJE3AdWAT.png) 2. Buat direktori my_wordpress dan buat file docker-compose didalamnya ``` cd $HOME mkdir -p latihan/my_wordpress cd latihan/my_wordpress vim docker-compose.yml ``` ![image](https://hackmd.io/_uploads/Sy3JgF-Ca.png) ![image](https://hackmd.io/_uploads/BkeUxFWA6.png) 3. Jalankan container dan lihat list container ``` docker-compose up -d docker container ls ``` ![image](https://hackmd.io/_uploads/Sy_Q5tb0T.png) ![image](https://hackmd.io/_uploads/BJhVqY-Ap.png) # **Modul 6: Docker Continous Integration (CI)** ## **1. CI Menggunakan Docker** Continuous Integration (CI) adalah praktik mengintegrasikan kode ke shared repository. Setiap check-in akan diverifikasi oleh automated build, memudahkan tim untuk mencari dan menghilangkan masalah dengan cepat. ![image](https://hackmd.io/_uploads/Hklj3FWCT.png) Karena Docker bisa integrasi dengan Jenkins dan GitHub, developer bisa submit code ke GitHub, tes kode dan secara otomatis melakukan build pakai Jenkins, dan setelah build, image bisa ditambahkan ke docker registries. ## **2. Docker Hub Automated Build** Docker Hub bisa secara otomatis membangun image dari source code menggunakan repositori eksternal dan push ke Docker repository # **Modul 7: Docker Swarm dan Portainer** ## **1. Docker Swarm** Docker Swarm adalah sekumpulan komputer yang berjalan di Docker. Setelah kumpulan komputer dikelompokan, Docker command yang dijalankan akan berlaku ke semua komputer yang ada di kelompok ## **2. Portainer untuk Docker** Portainer adalah universal container management tool untuk melakukan deployment dan pengelolaan dari ontainerized applications dan services. ## **3. Lab 7.1 - Create Swarm** 1. Inisialisasi Docker Swarm ``` docker swarm init --advertise-addr 10.7.7.10 ``` ![image](https://hackmd.io/_uploads/ByTxl9-Rp.png) 2. Copy command docker join di node02 ``` docker swarm join --token SWMTKN-1-13nlc7oojz2c6lsr3uticm2qfiqbrjwwn67zxy2z0x6t7kg05s-egod0z9otq1p68wx45402ekiv 10.7.7.10:2377 ``` ![image](https://hackmd.io/_uploads/B1uze9bAp.png) 3. Cek apakah node02 sudah join ``` docker node ls ``` ![image](https://hackmd.io/_uploads/BkMrlqZ06.png) ## **4. Lab 7.2 - Deploy Service to Swarm** 1. Buat service nginx dengan 2 replika dan ekspos ke port 80 ``` docker service create --name web --replicas 2 -p 80:80 registry.adinusa.id/btacademy/nginx:latest ``` ![image](https://hackmd.io/_uploads/ByHIHqZA6.png) 2. Periksa apakah kodenya berjalan dan tes browsing dari node01 dan node 02 ``` docker service ls curl http://10.7.7.10 curl http://10.7.7.20 ``` ![image](https://hackmd.io/_uploads/SJcoBcWA6.png) 3. Periksa informasi tentang service ``` docker service inspect --pretty web ``` ![image](https://hackmd.io/_uploads/ByMCrqZR6.png) 4. Buat container dengan cpu dan memori yang terbatas ``` docker service create --name alvan --reserve-cpu 1 --limit-cpu 1 \ --reserve-memory 256mb --limit-memory 128mb registry.adinusa.id/btacademy/httpd:latest ``` ![image](https://hackmd.io/_uploads/BkRuPqZ0T.png) 5. Periksa container yang baru dibuat ``` docker service inspect --pretty alvan ``` ![image](https://hackmd.io/_uploads/Syxdv5-A6.png) ## **5. Lab 7.3 - Docker swarm Scale & Update** 1. Buat service nginx dengan 3 replica ``` docker service create --name web2 --replicas 3 -p 80:80 registry.adinusa.id/btacademy/nginx:latest ``` ![image](https://hackmd.io/_uploads/BJLBd5Z06.png) 3. Ubah replica service ``` docker service scale web2=1 ``` ![image](https://hackmd.io/_uploads/r1XIOqbC6.png) 4. Periksa apakah replica sudah diubah ``` docker service ls docker service ls ``` ![image](https://hackmd.io/_uploads/r1K3u9bAp.png) 5. Melakukan update ke service di swarm ``` docker service update --image sistyo/myweb web2 docker service inspect --pretty web2 ``` ![image](https://hackmd.io/_uploads/By8Gt5ZRp.png) ## **6. Lab 7.4 - Install Portainer and configuration** 1. Install portainer di node01 ``` docker volume create portainer_data docker run -d -p 8000:8000 -p 9000:9000 --name portainer --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest ``` ![image](https://hackmd.io/_uploads/H1D3j9Z0a.png) ![image](https://hackmd.io/_uploads/SyO2i9b0a.png) 2. Akses Portainer Dashboard ``` Buka 10.10.10.11:9000 di browser ``` 3. Click menu Environments -> Add environmets -> Select Docker Swarm -> Start Wizard -> Select Agent -> Copy command ke node01 ![image](https://hackmd.io/_uploads/rkTzn9bCp.png) ``` docker network create \ --driver overlay \ portainer_agent_network docker service create \ --name portainer_agent \ --network portainer_agent_network \ -p 9001:9001/tcp \ --mode global \ --constraint 'node.platform.os == linux' \ --mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock \ --mount type=bind,src=//var/lib/docker/volumes,dst=/var/lib/docker/volumes \ portainer/agent:2.19.4 ``` ![image](https://hackmd.io/_uploads/S1x565ZR6.png) 4. Di portainer board * isi NAME Column dengan hostname node02 pod-username-node02 * isi Environment URL dengan ip address node02 10.7.7.20:9001 * klik connect ![image](https://hackmd.io/_uploads/r1sbAcWAT.png) ## **7. Lab 7.5 - Running Container from Portainer** 1. Buka Portainer lalu: * Ke Home -> node02 -> Containers -> + Add Container * Isi name Column dengan [username]-web * Isi image dengan nginx:latest * Klik Publish a new network port -> isi host coloumn 8080 dan container coloumn 80 ![image](https://hackmd.io/_uploads/Hkr5yiZ0T.png) 2. Akses container dengan membuka laman http://10.10.10.12:8080 ![image](https://hackmd.io/_uploads/BJ96yib06.png) ## **8. Lab 7.6 - Build & Push Image from Portainer** 1. Membuat Image dari Dockerfile ![image](https://hackmd.io/_uploads/r1x0xs-0a.png) 2. Buat registry DockerHub di Portainer ![image](https://hackmd.io/_uploads/Hyilmi-AT.png) 3. Periksa di DockerHub ![image](https://hackmd.io/_uploads/S18frj-0T.png) # **Modul 8: Logging Driver** Docker menyediakan Logging Driver yang berfungsi untuk membantu melihat informasi dari container dan service yang sedang berjalan. Docker menggunakan json-file logging driver untuk melakukan cache container sebagai JSON ## **1. Lab 8.1: Configuring Logging Driver** 1. Membuat file daemon.json ``` sudo vim /etc/docker/daemon.json ``` ![image](https://hackmd.io/_uploads/r1UH16-RT.png) 2. Restart Daemon dan Docker ``` sudo systemctl daemon-reload sudo systemctl restart docker ``` 3. Jalankan container ``` docker run --log-driver json-file --log-opt max-size=10m registry.adinusa.id/btacademy/alpine echo hello world ``` ![image](https://hackmd.io/_uploads/B1i6kT-Ra.png) 4. Periksa log di direktori docker ``` sudo cat /var/lib/docker/containers/$(docker ps --no-trunc -a | grep 'alpine' | awk '{print $1}')/$(docker ps --no-trunc -a | grep 'alpine' | awk '{print $1}')-json.log | jq . ``` ![image](https://hackmd.io/_uploads/S1gxQxa-0T.png) # **Modul 9: Health Check** **Health Check** digunakan untuk menentukan apakah aplikasi sudah siap dan bisa melaksanakan fungsinya. instruksi **HEALTHCHECK** memerintahkan docker untuk memeriksa apakah container masih berjalan dengan benar. Exit code menandakan health status containernya. Value dari exit code-nya adalah: * 0: success - the container is healthy and ready for use * 1: unhealthy - the container is not working correctly * 2: reserved - do not use this exit code ## **1. Lab 9.1: Health Check** ### **1.1. Practice 01** 1. Buat working direktori ``` cd $HOME mkdir hc-latihan01 cd hc-latihan01 ``` 2. Buat image dari Dockerfile ``` vim Dockerfile ``` ![image](https://hackmd.io/_uploads/B1bSxASR6.png) 3. Buat image dan jalankan ``` docker build -t http-healthcheck . ``` ![image](https://hackmd.io/_uploads/r1BWWCBAT.png) 4. Cek image dan browser ``` docker ps curl http://localhost/ # periksa yang unhealthy curl http://localhost/unhealthy ``` ![image](https://hackmd.io/_uploads/S1WdWAB0p.png) ![image](https://hackmd.io/_uploads/S1nuW0HRp.png) ![image](https://hackmd.io/_uploads/SymWf0HRT.png) 5. Cek status container dan cek dengan curl ``` docker container ls curl http://localhost/ ``` ![image](https://hackmd.io/_uploads/H1QOf0HA6.png) ### **1.2. Practice 02** 1. Buat working direktori ``` cd $HOME mkdir hc-latihan02 cd hc-latihan02 ``` 2. Buat file server.js ``` vim server.js ``` ![image](https://hackmd.io/_uploads/Hy_d70BAp.png) 3. Buat image dari Dockerfile ``` vim Dockerfile ``` ![image](https://hackmd.io/_uploads/SyLjQRr0T.png) 4. Buat image dan jalankan ``` docker build -t node-server . docker run -d --name nodeserver -p 8080:8080 -p 8081:8081 node-server ``` ![image](https://hackmd.io/_uploads/HJ3tR0SCp.png) 5. Cek container di kedua port ``` # Port 8080 curl 127.0.0.1:8080 docker ps docker inspect --format "{{ json .State.Health }}" nodeserver | jq . curl 127.0.0.1:8081 docker ps docker inspect --format "{{ json .State.Health }}" nodeserver | jq . ``` **Port 8080** ![image](https://hackmd.io/_uploads/HkYp00SA6.png) ![image](https://hackmd.io/_uploads/rkdCRRrRa.png) **Port 8081** ![image](https://hackmd.io/_uploads/SJnzkJU0p.png) ![image](https://hackmd.io/_uploads/H1sVekICa.png) 6. Cek Container yang sudah unhealthy ``` curl 127.0.0.1:8081 docker ps docker inspect --format "{{ json .State.Health }}" nodeserver | jq . ``` ![image](https://hackmd.io/_uploads/BkoP118Aa.png) ![image](https://hackmd.io/_uploads/SyQGx1LAT.png) # **Modul 10: Security** ## **1. Docker Security** **Kernel namespaces** membuat setiap container terisolasi dari container lain, termasuk network stack yang mencegah serangan cyber. **Control groups** membatasi sumber daya untuk mencegah DDOS. **Docker daemon attack surface** mencegah orang yang tidak berwenang mengendalikan Docker daemon. **Linux kernel capabilities** mencegah processes bertindak menjadi root. **Docker Content Trust Signature Verification** memberikan wawasan terhadap administrator ## **2. CIS Docker Benchmark** Center for Internet Security (CIS) menjamin bahwa Docker container dan runtime diatur seaman mungkin. ## **3. Secure Computing Mode** Secure computing mode (seccomp) adalah sebuah fitur linux kernel yang dipakai untuk membatasi tindakan yang tersedia di dalam container. ## **4. Secret** Secret adalah sekumpulan data yang tidak dikirim atau disimpan di tempat yang unencrypted, biasanya untuk password, SSH keys, dll. # **Modul 11: Storage Driver** Storage Drivers memungkinkan pengguna untuk melakukan write pada container layer writable. Berikut adalah storage driver yang didukung oleh docker: * **overlay2**, tidak membutuhkan konfigurasi tambahan * **aufs**, untuk docker versi lawas yang tidak memiliki dukungan untuk overlay2 * **fuse-overlayfs**, digunakan hanya untuk menjalankan Rootless Docker * **devicemapper**, direkomendasikan untuk CentOS and RHEL yang tidak bisa menggunakan overlay2 * **btrfs & zfs**, digunakan jika ada backing filesystem * **vfs**, untuk melakukan ujicoba ## **1. Lab 11.1: Configuring Storage Driver** 1. Edit file daemon.json ``` sudo vim /etc/docker/daemon.json ``` ![image](https://hackmd.io/_uploads/rJyHfyLCp.png) 2. Restart service docker dan cek docker info ``` sudo service docker restart docker info ``` ![image](https://hackmd.io/_uploads/S1UtL1IRT.png) 3. Cek dengan docker pull ``` docker pull registry.adinusa.id/btacademy/ubuntu ``` ![image](https://hackmd.io/_uploads/BJIcUJU06.png) 5. Cek docker directory ``` sudo ls -al /var/lib/docker/vfs/dir/ sudo du -sh /var/lib/docker/vfs/dir/ ``` ![image](https://hackmd.io/_uploads/Sk9iU1LC6.png) ![image](https://hackmd.io/_uploads/SJFh81UAa.png) # **Modul 12: Logging and Error Handling** ## 1. Log Check Untuk melakukan cek di filesystem dalam sebuah container dapat menggunakan: ``` docker diff nama-container ``` ![image](https://hackmd.io/_uploads/rkz5v18Cp.png) Untuk membuka log dapat menggunakan: ``` docker logs --details nama-container docker logs --timestamps nama-container docker logs nama-container ``` # **Modul 13: Lab Challenge** ## **1. Challenge 1 - Haproxy With Docker** 1. Buat Working Direktori ``` mkdir challenge1 cd challenge1 ``` 2. Buat 2 container menggunakan image ``` docker run -d --name web1 -p 8081:80 registry.adinusa.id/btacademy/nginx:latest docker run -d --name web2 -p 8082:80 registry.adinusa.id/btacademy/httpd:latest ``` ![image](https://hackmd.io/_uploads/ryX_9y80p.png) 3. Buat file konfigurasi haproxy.cfg ``` vim haproxy.cfg ``` ![image](https://hackmd.io/_uploads/B1e27lI0a.png) 4. Buat volume untuk menyimpan konfigurasi haproxy.cfg ``` docker volume create haproxy_config ``` ![image](https://hackmd.io/_uploads/ry7hAk8Ra.png) 5. Jalankan container alpine menggunakan haproxy dengan konfigurasi yang sudah dimount ke volume ``` docker run -d --name alvan-haproxy -p 80:80 -v haproxy-config:/usr/local/etc/haproxy registry.adinusa.id/btacademy/haproxy-alpine:2.4 ``` ![image](https://hackmd.io/_uploads/r1Q-wTU0p.png) ## **2. Challenge 2 - Deploy Laravel with Docker (Hard)** 1. Buat Working Direktori ``` mkdir challenge2 cd challenge2 ``` 2. Clone repository dan buat docker file ``` git clone https://github.com/academynusa/perpus-laravel.git perpus vim Dockerfile ``` ![image](https://hackmd.io/_uploads/SJS-gWP06.png) 3. Buat bash script ``` vim setup.sh ``` ![image](https://hackmd.io/_uploads/rkU7gZPCT.png) 4. Build dan jalankan dari dockerfile ``` docker build -t img-perpus-username . docker run -d -p 8000:8000 --name perpus-username img-perpus-username ```