{"id":179,"date":"2024-10-13T02:40:41","date_gmt":"2024-10-12T19:40:41","guid":{"rendered":"https:\/\/notes.its.ac.id\/ruhendrawan\/?p=179"},"modified":"2024-10-13T18:39:02","modified_gmt":"2024-10-13T11:39:02","slug":"docker-sehari-hari","status":"publish","type":"post","link":"https:\/\/notes.its.ac.id\/ruhendrawan\/docker-sehari-hari","title":{"rendered":"Menjalankan Aplikasi Tanpa Instalasi dengan Docker"},"content":{"rendered":"<p>Ingin mencoba <code>nginx<\/code>, <code>ruby<\/code>, atau <code>golang<\/code> tapi males repot menginstal dan menghapusnya nanti? Dengan Docker, kita bisa langsung menjalankan aplikasi tanpa harus pusing dengan proses instalasi atau bersih-bersih setelahnya.<\/p>\n<h2>Mengunduh image bikinan orang lain<\/h2>\n<p><code>image<\/code> adalah semacam &quot;installer&quot;. Dari <code>image<\/code> ini, kita bisa menginstallnya sebagai <code>container<\/code>, yaitu aplikasi yang siap dijalankan.  Kita bisa membuat <code>image<\/code> sendiri, tapi konfigurasi dan proses  <code>build<\/code> membutuhkan waktu lama. Dengan kepakaran yang terbatas, lebih praktis memanfaatkan <code>image<\/code> bikinan orang lain.<\/p>\n<p><code>image<\/code> yang telah dibangun oleh orang lain dapat diperoleh dari <a href=\"https:\/\/hub.docker.com\/\">Docker Hub<\/a>. Semacam  toko aplikasi atau &quot;App Store&quot; yang di dalamnya telah diorganisasi dengan rapi. Misalnya, kategori <a href=\"https:\/\/hub.docker.com\/search?categories=Languages+%26+Frameworks\">&quot;Language &amp; Frameworks&quot;<\/a> berisikan <code>image<\/code> dari bahasa <code>php<\/code> atau <code>ruby<\/code> yang lumayan ribet jika menginstall secara manual.<\/p>\n<p>Namun, berkat docker kita bisa dengan mudah gunakan <code>image<\/code> tersebut dengan <code>docker pull NAMA_IMAGE<\/code>. Contohnya:<\/p>\n<pre><code class=\"language-bash\">docker pull ruby\n<\/code><\/pre>\n<p>Kemudian mengecek daftar <code>image<\/code> dengan perintah<\/p>\n<pre><code>docker image ls\n<\/code><\/pre>\n<pre><code>REPOSITORY      TAG               IMAGE ID       CREATED       SIZE\nruby            latest            dc4e58bf5fd5   5 weeks ago   1.46GB\n<\/code><\/pre>\n<h2>Menghapus image<\/h2>\n<p><code>Image<\/code> yang tidak dipakai lebih baik dihapus daripada menghabiskan ruang.<\/p>\n<p>Misalnya terdapat <code>image<\/code> dengan nama <code>nginx<\/code>. Dua cara menghapusnya, yaitu:<\/p>\n<ul>\n<li>Cara intuitif<\/li>\n<\/ul>\n<pre><code class=\"language-bash\">docker image rm nginx\n<\/code><\/pre>\n<ul>\n<li>Cara cepat (rmi = remove image)<\/li>\n<\/ul>\n<pre><code class=\"language-bash\">docker rmi nginx\n<\/code><\/pre>\n<h2>Menjalankan container<\/h2>\n<p><code>Image<\/code> adalah sekumpulan aplikasi yang tersedia namun belum siap digunakan, semacam &quot;installer&quot;.<\/p>\n<p>Sebelum dijalankan, <code>image<\/code> perlu dipasang\/ diinstall ke sistem sebagai <code>container<\/code>.<\/p>\n<p>Sebuah <code>image<\/code> dapat dipasang sebagai beberapa <code>container<\/code>.<\/p>\n<p>Terdapat dua jenis kontainer:<\/p>\n<ol>\n<li>Kontainer layanan siaga: kontainer dengan layanan latar (background service)<\/li>\n<li>Kontainer buruh: kontainer aplikasi<\/li>\n<\/ol>\n<h3>Kontainer Layanan Siaga<\/h3>\n<p>Aplikasi semacam server web, menjalankan proses latar. Di balik layar (tanpa antar muka), proses tersebut berjalan <strong>standby menunggu permintaan dari pengguna<\/strong>.<\/p>\n<p>Biasanya aplikasi semacam ini menerima permintaan melalui protokol TCP\/IP (aplikasi jaringan) dan HTTP (aplikasi web).<\/p>\n<p>Contohnya, aplikasi <code>nginx<\/code> memonitor port 80 (bisa diganti di konfigurasi). Selama hidupnya, <code>nginx<\/code> akan menguasai port 80 sehingga aplikasi lain tidak dapat menggunakannya (port binding).<\/p>\n<p>Perintah berikut akan melakukan tiga hal:<\/p>\n<ul>\n<li>Mengunduh image <code>nginx<\/code> dari &quot;Docker Hub&quot; jika belum tersedia di komputer lokal.<\/li>\n<li>Membuat container baru dengan nama otomatis<\/li>\n<li>Menjalankan container tersebut.<\/li>\n<\/ul>\n<pre><code class=\"language-bash\">docker run -d -p 80:80 nginx\n<\/code><\/pre>\n<p><code>-d<\/code> atau <code>--detach<\/code>menandakan bahwa proses dijalankan dilatar (&quot;detach&quot; berarti pengguna tidak perlu menunggu dan menanti sampai kisah ini berakhir).<\/p>\n<blockquote>\n<p>[!important] Dalam dunia sistem komputer, kita juga mengenal istilah <code>daemon<\/code>, yaitu <strong>proses yang bergentayangan di balik layar<\/strong>.<\/p>\n<\/blockquote>\n<p><code>nginx<\/code> mangkal di port 80 di dalam kontainer dan siap siaga. Namun, untuk meminta data dari <code>nginx<\/code>, kita perlu masuk ke dalam kontainer tersebut. Ini akan kita bahas lain waktu. Kita pelajari dulu cara mengakses layanan ini tanpa masuk-masuk.<\/p>\n<p><code>-p<\/code> atau <code>--publish<\/code> berarti layanan yang ada di dalam kontainer akan dipublikasikan oleh <code>host<\/code> (komputer yang menjalankan kontainer), sehingga bisa diakses tanpa harus masuk ke dalam kontainer.<\/p>\n<p>Kita bisa menggunakan browser dan mengambil file yang tersedia melalui broser dengan alamat URL <code>http:\/\/127.0.0.1:80<\/code> atau <code>http:\/\/127.0.0.1<\/code> (:80 adalah port default untuk protokol HTTP).<\/p>\n<pre><code class=\"language-bash\"># Welcome to nginx!\n\nIf you see this page, the nginx web server is successfully installed and working. Further configuration is required.\n\nFor online documentation and support please refer to\u00a0[nginx.org](http:\/\/nginx.org\/).  \nCommercial support is available at\u00a0[nginx.com](http:\/\/nginx.com\/).\n\n_Thank you for using nginx._\n<\/code><\/pre>\n<p>Orang siaga ada batasnya, ada masa-masa dimana aplikasi membutuhkan &quot;me time&quot;.<\/p>\n<p>Apakah aplikasi sedang siaga? Pertanyaan bisa dijawab dengan mudah menggunakan perintah berikut:<\/p>\n<pre><code class=\"language-bash\">docker ps\n<\/code><\/pre>\n<p><code>ps<\/code> adalah perintah umum di linux yang merupakan singkatan dari <code>proses status<\/code>.<\/p>\n<pre><code class=\"language-bash\">CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS          PORTS                NAMES\n24b57acffb5b   nginx                           &quot;\/docker-entrypoint.\u2026&quot;   16 minutes ago   Up 16 minutes   0.0.0.0:80-&gt;80\/tcp   pedantic_sinoussi\n<\/code><\/pre>\n<p>Dari luaran di atas, proses dari kontainer <code>nginx<\/code> sedang berjalan dengan port yang dipublikasikan di <code>0.0.0.0:80<\/code>.<\/p>\n<blockquote>\n<p>[!note] Dalam jaringan dengan TCP-IP, setiap komputer diberi nama menggunakan alamat IP.<\/p>\n<p>Alamat khusus &quot;127.0.0.1&quot; (loopback interface) digunakan untuk menyebut &quot;komputer ini&quot; secara spesific.<\/p>\n<p>Sedangkan &quot;0.0.0.0&quot; (unspecified address) menunjukkan bahwa aplikasi akan melayani &quot;siapapun&quot;.<\/p>\n<\/blockquote>\n<p>Layanan web sudah berjalan, tapi bagaimana jika file HTML nya ada di laptop (<code>host<\/code>).<\/p>\n<p>Bayangkan kontainer seperti sebuah komputer yang ada didalam komputer yang sedang kita gunakan. Terdapat dua sistem penyimpanan file, satu di <code>container<\/code>, dan satu lagi di <code>host<\/code>.<\/p>\n<p>Supaya layanan <code>nginx<\/code> dapat membaca file yang ada di <code>host<\/code>, docker membutuhkan pemetaan dari sistem file <code>host<\/code> dengan <code>container<\/code>.<\/p>\n<p>Docker menyediakan parameter <code>-v<\/code> atau <code>--volume<\/code> untuk memetakan <code>volume<\/code> yang ada di <code>host<\/code> ke <code>container<\/code>. Pada linux, <code>volume<\/code> adalah lokasi logis sebuah media penyimpanan. Misalnya kita memiliki sebuah media penyimpanan fisik yaitu sebuah harddisk. Harddisk dapat dipartisi menjadi dua <code>volume<\/code>. Pada Microsoft Windows, volume adalah drive, misalnya drive C dan D. Alamat dari sebuah <code>volume<\/code> biasa disebut <code>path<\/code>, misalnya <code>c:\\<\/code> dan <code>d:\\<\/code>.<\/p>\n<p>Sehingga, <code>path<\/code> dibutuhkan untuk menyampaikan memberitahu pemetaan lokasi penyimpanan dari <code>host<\/code> ke <code>container<\/code>.<\/p>\n<p>Sintaksnya adalah <code>-v host_path:container_path<\/code><\/p>\n<p>Pertama, siapkan dulu dokumen html di komputer yang sedang dipakai. <code>~\/<\/code> adalah lokasi data dari user yang sedang login.<\/p>\n<p>Misalnya, ketika login sebagai user <code>aku<\/code> di Linux,<\/p>\n<ul>\n<li>maka <code>~\/<\/code> sama dengan <code>\/home\/aku<\/code><\/li>\n<li>atau pada MacOS lokasinya adalah <code>\/Users\/aku<\/code><\/li>\n<\/ul>\n<pre><code>mkdir -p ~\/Projects\/html\nvim ~\/Projects\/html\/index.html\n<\/code><\/pre>\n<p>Lalu jalankan layanan <code>nginx<\/code> dengan memetakan:<\/p>\n<ul>\n<li>Dari lokasi <code>~\/Projects\/html<\/code> pada <code>host<\/code><\/li>\n<li>Ke <code>\/usr\/share\/nginx\/html<\/code> dalam <code>container<\/code><\/li>\n<\/ul>\n<p>Secara default, <code>nginx<\/code> akan menyajikan semua file yang ada di <code>\/usr\/share\/nginx\/html<\/code>. Lebih detail dijelaskan pada dokumentasi <code>image<\/code> <code>nginx<\/code> di <a href=\"https:\/\/hub.docker.com\/_\/nginx\">hub.docker.com\/_\/nginx<\/a><\/p>\n<pre><code class=\"language-bash\">docker run -d -p 80:80 --name nginxdocker -v ~\/Projects\/html:\/usr\/share\/nginx\/html nginx\n<\/code><\/pre>\n<p>Cek di browser <code>http:\/\/127.0.0.1<\/code> dan pastikan tampilannya sama dengan isi dari <code>~\/Projects\/html\/index.html<\/code>.<\/p>\n<h3>Kontainer Buruh<\/h3>\n<p>Berbeda dengan <code>nginx<\/code> yang menyediakan layanan siaga, aplikasi semacam <code>php<\/code> dan <code>ruby<\/code> <strong>hanya bekerja ketika diperintah<\/strong>.<\/p>\n<blockquote>\n<p>[!tip] Hal ini sangat jarang dilakukan karena biasanya kita menggunakan docker untuk menyediakan layanan.<\/p>\n<p>Ssaat development, semua aplikasi (<code>php<\/code>, <code>ruby<\/code>) biasanya sudah terinstall.<\/p>\n<\/blockquote>\n<p>Contohnya, menjalankan aplikasi <code>ruby<\/code> dalam mode interactive dan tty <code>-it<\/code>, <strong>langsung dari dalam kontainer<\/strong>. Dalam mode interactive <code>-i<\/code>, klien docker akan menunggu masukan (input). Ditambah mode tty <code>-t<\/code>, docker juga akan menampilkan luaran (output) dari aplikasi yang dijalankan.<\/p>\n<pre><code class=\"language-bash\">docker run -it ruby\n<\/code><\/pre>\n<pre><code class=\"language-ruby\">irb(main):003&gt; x=&quot;hello&quot;\n=&gt; &quot;hello&quot;\nirb(main):004&gt; puts x\nhello\n=&gt; nil\nirb(main):005&gt; exit\n<\/code><\/pre>\n<p>Cocok buat coba-coba tanpa merusak sistem di komputer lokal.<\/p>\n<h3>Menjalankan aplikasi di dalam kontainer<\/h3>\n<p>Bayangkan <code>container<\/code> sebagai komputer di dalam komputer yang sedang kita gunakan. Komputer yang menjalankan <code>container<\/code>, disebut sebagai <code>host<\/code>.<\/p>\n<p>Jika dalam <code>host<\/code> kita menjalankan aplikasi <code>ruby<\/code> dengan perintah berikut (<code>-e<\/code> menandakan eksekusi <code>argumen<\/code> berikutnya, yaitu <code>&quot;puts 'hello'&quot;<\/code>):<\/p>\n<pre><code class=\"language-bash\">ruby -e &quot;puts 'hello'&quot; \n<\/code><\/pre>\n<p>Aplikasi di dalam kontainer dapat dijalankan secara langsung, dengan perintah yang mirip, dengan menjalankan <code>docker run nama_image<\/code>.<\/p>\n<blockquote>\n<p>[!note] Ingat: <code>docker run<\/code> Membuat dan menjalankan kontainer baru dari image<\/p>\n<\/blockquote>\n<pre><code class=\"language-bash\">docker run ruby ruby -e &quot;puts 'hello'&quot; \n<\/code><\/pre>\n<p>Setelah aplikasi di dalam kontainer selesai dieksekusi, <strong>proses kontainer<\/strong> akan distop namun  <strong>kontainer TIDAK dihapus<\/strong>.<\/p>\n<p>Cek sendiri kalau tidak percaya.<\/p>\n<pre><code class=\"language-bash\">docker ps\ndocker container ls -a\n<\/code><\/pre>\n<p>Dalam contoh berikut, terdapat tiga container yang telah berhenti <code>Exited (0)<\/code> dengan nama <code>flamboyant_hellman<\/code>, <code>admiring_panini<\/code>, <code>xenodochial_driscoll<\/code>.<\/p>\n<blockquote>\n<p>Docker selalu membuat kontainer baru dengan nama otomatis karena kita tidak memberikan nama.<\/p>\n<\/blockquote>\n<pre><code>CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES\nf1678868ff5d   ruby      &quot;ruby -e 'puts 'hell\u2026&quot;   37 seconds ago   Exited (0) 36 seconds ago             flamboyant_hellman\nc4c40fd1dbeb   ruby      &quot;ruby -e 'puts 'hell\u2026&quot;   39 seconds ago   Exited (0) 39 seconds ago             admiring_panini\n6029346e8df7   ruby      &quot;ruby -e 'puts 'hell\u2026&quot;   43 seconds ago   Exited (0) 42 seconds ago             xenodochial_driscoll\n<\/code><\/pre>\n<p>Kalau mau bersih-bersih, <code>docker rm<\/code> bisa dipakai untuk menghapusnya:<\/p>\n<pre><code class=\"language-bash\">docker rm NAMA_CONTAINER\n<\/code><\/pre>\n<p>Atu jalur gampang nan berbahaya, hapus semua docker yang sudah tidak berjalan dengan <code>prune<\/code> (pangkas).<\/p>\n<pre><code class=\"language-bash\">docker container prune\n<\/code><\/pre>\n<p>Sekarang, bagaimana caranya agar setiap menjalankan <code>docker run<\/code>, tidak menghasilkan kontainer baru.<\/p>\n<p>Cara pertama adalah dengan otomatis menghapus container setelah dijalankan, dengan memberi tanda <code>--rm<\/code><\/p>\n<pre><code class=\"language-bash\">docker run --rm ruby ruby -e &quot;puts 'hello'&quot; \n<\/code><\/pre>\n<p>Cara kedua adalah dengan memberikan nama kontainer dengan argumen <code>--name<\/code>.<br \/>\nBerikut sintaksnya:<\/p>\n<pre><code>docker run --name NAMA_CONTAINER NAMA_IMAGE PERINTAH\n<\/code><\/pre>\n<p>Sebagai contoh:<\/p>\n<pre><code class=\"language-bash\">docker run --name rubydocker ruby ruby -e &quot;puts 'hello'&quot; \n<\/code><\/pre>\n<p>Setiap perintah di atas dijalankan, maka docker akan mencoba memanfaatkan container yang sudah ada dengan nama yang diberikan.<\/p>\n<pre><code class=\"language-bash\">docker container ls -a\n<\/code><\/pre>\n<pre><code class=\"language-bash\">CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES\n7d9ffbc6aab7   ruby      &quot;ruby -e 'puts 'hell\u2026&quot;   27 seconds ago   Exited (0) 26 seconds ago             rubydocker\n<\/code><\/pre>\n<p>Disini hanya terdapat satu kontainer bernama <code>rubydocker<\/code>.<\/p>\n<p>Perintah <code>docker run<\/code> yang sama, tidak dapat dijalankan lagi karena kontainer ini sudah ada.<\/p>\n<pre><code class=\"language-bash\">\u276f docker run --name rubydocker ruby ruby -e &quot;puts 'hello'&quot;\ndocker: Error response from daemon: Conflict. The container name &quot;\/rubydocker&quot; is already in use by container &quot;7d9ffbc6aab70355725fb8e57c1c63475d8fb0834f6ce83c5658b13c6fd9edc0&quot;. You have to remove (or rename) that container to be able to reuse that name.\nSee 'docker run --help'.\n<\/code><\/pre>\n<p>Sehingga, untuk memanfaatkan kembali kontainer ini digunakan perintah <code>docker start NAMA_CONTAINER<\/code>.<\/p>\n<p>Namun, pada &quot;kontainer buruh&quot;, proses ini hanya berjalan sesaat kemudian keluar lagi, karena tidak ada perintah yang diberikan.<\/p>\n<p>Perintah dapat diberikan dengan menggunakan operasi pipe <code>|<\/code>. Sintaksnya <code>perintah_pertama | perintah_kedua<\/code>. Proses dari perintah pertama akan menjadi masukan bagi perintah kedua.<\/p>\n<pre><code class=\"language-bash\">docker start rubydocker | ruby -e &quot;puts 'hello'&quot;\n<\/code><\/pre>\n<p>Mulai ribet kan?<br \/>\nDemi kenyamanan bersama, perintah panjang ini bisa dijadikan pendek dengan alias.<\/p>\n<pre><code class=\"language-ssh\">alias druby=&quot;docker start rubydocker | ruby $1&quot;\n<\/code><\/pre>\n<p>Sehingga bisa perintahnya menjadi<\/p>\n<pre><code class=\"language-bash\">druby -e &quot;puts 'hello'&quot;\n<\/code><\/pre>\n<p>Sekarang kita bisa menjalankan perintah <code>ruby<\/code> tanpa harus menginstallnya.<\/p>\n<p>Misal terdapat skrip <code>hello.rb<\/code> pada komputer. Skrip ini bisa dijalankan dengan perintah:<\/p>\n<pre><code>druby hello.rb\n<\/code><\/pre>\n<p>Tapi ingat, setiap eksekusi perintah ini akan ada biaya tambahan (overhead cost) untuk menjalankan container.<\/p>\n<pre><code>\u276f time druby test.rb\nhello\ndocker start rubydocker  0.01s user 0.01s system 9% cpu 0.233 total\nruby test.rb  0.04s user 0.01s system 96% cpu 0.055 total\n\n\u276f time ruby test.rb\nhello\nruby test.rb  0.04s user 0.01s system 95% cpu 0.055 total\n<\/code><\/pre>\n<h2>Ringkasan<\/h2>\n<h3><strong>Kontainer Layanan<\/strong><\/h3>\n<p>Contoh: Menjalankan server web <code>nginx<\/code><\/p>\n<ol>\n<li>Siapkan dokumen html<\/li>\n<\/ol>\n<pre><code>mkdir -p ~\/Projects\/html\nvim ~\/Projects\/html\/index.html\n<\/code><\/pre>\n<ol start=\"2\">\n<li>Lalu jalankan layanan<\/li>\n<\/ol>\n<pre><code class=\"language-bash\">docker run -d -p 80:80 --name nginxdocker -v ~\/Projects\/html:\/usr\/share\/nginx\/html nginx\n<\/code><\/pre>\n<ol start=\"3\">\n<li>Cek di browser <code>http:\/\/127.0.0.1<\/code><\/li>\n<\/ol>\n<h3><strong>Kontainer Buruh<\/strong><\/h3>\n<p>Menjalankan aplikasi: berikut contoh untuk <code>ruby<\/code>. Bisa diterapkan untuk aplikasi lain, tinggal mengganti <code>ruby<\/code> dengan <code>php<\/code>, <code>python<\/code>, dll.<\/p>\n<pre><code class=\"language-bash\">docker run --name rubydocker ruby ruby -e &quot;puts 'hello'&quot; \n\nalias druby=&quot;docker start rubydocker | ruby $1&quot;\n\ndruby -e &quot;puts 'hello'&quot;\ndruby hello.rb\n<\/code><\/pre>\n<h2>Bonus<\/h2>\n<p>Aplikasi biasanya dikemas sebagai <code>image<\/code> dalam sistem operasi <code>Debian<\/code>, yang dilengkapi dengan paket lengkap sehingga ukurannya cukup besar. Namun, kebutuhan dasar aplikasi umumnya dapat dipenuhi dengan paket yang lebih ringan dari distribusi seperti <code>Debian Bookworm<\/code> atau <code>Linux Alpine<\/code>.<\/p>\n<p>Contohnya, aplikasi <code>ruby<\/code> yang dikemas dalam <code>Debian Bookworm<\/code> dapat dijalankan dengan menambahkan tag <code>slim<\/code>, sehingga nama imagenya menjadi <code>ruby:slim<\/code>. Tag selengkapnya dapat di cek di <a href=\"https:\/\/hub.docker.com\/_\/ruby\">hub.docker.com\/_\/ruby<\/a><\/p>\n<pre><code>docker run --name rubydockerslim ruby:slim ruby -e &quot;puts 'hello'&quot;\n<\/code><\/pre>\n<p>Berikut adalah perbandingan ukuran aplikasi yang didistribusikan dengan tag <code>latest<\/code>, <code>alpine<\/code> atau <code>slim<\/code>:<\/p>\n<pre><code>REPOSITORY   TAG      IMAGE ID       CREATED        SIZE\n\nnginx        latest   048e09038596   10 days ago    197MB\nnginx        alpine   577a23b5858b   10 days ago    50.8MB\n\nphp          latest   910138e230ec   2 weeks ago    530MB\nphp          alpine   b6ec2c8a30cb   2 weeks ago    96.7MB\n\nruby         latest   febc5e18cba3   5 weeks ago    1GB\nruby         slim     137ca6ff3afb   5 weeks ago    212MB\nruby         alpine   e78475f17fab   5 weeks ago    92.5MB\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Ingin mencoba nginx, ruby, atau golang tapi males repot menginstal dan menghapusnya nanti? Dengan Docker, kita bisa langsung menjalankan aplikasi tanpa harus pusing dengan proses&hellip;<\/p>\n","protected":false},"author":1286,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-179","post","type-post","status-publish","format-standard","hentry","category-web-deployment"],"_links":{"self":[{"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/posts\/179","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/users\/1286"}],"replies":[{"embeddable":true,"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/comments?post=179"}],"version-history":[{"count":12,"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/posts\/179\/revisions"}],"predecessor-version":[{"id":213,"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/posts\/179\/revisions\/213"}],"wp:attachment":[{"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/media?parent=179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/categories?post=179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/notes.its.ac.id\/ruhendrawan\/wp-json\/wp\/v2\/tags?post=179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}