Skip to content
Blog Programming

Bagaimana Saya Mengubah Perintah Docker yang Paling Sering Diulang Jadi Perintah yang Bisa Diketik dari Mana Pun

By Romi Fadli, S.Kom. 18 min read Tooling & Automation
On this page
Tiga perintah docker yang panjang di kiri berubah jadi tiga kotak ungu pendek dcup, dls, dan dcn; ketiganya terhubung ke kotak bergaris putus-putus hijau bertuliskan /usr/local/bin yang terjangkau dari direktori mana pun, dan satu kartu di kanan memperlihatkan dfind memanggil dls lewat pipe grep.

Ada satu jenis pemborosan yang tak pernah muncul di pengukuran mana pun. Yaitu ketika untuk kedua belas kalinya dalam sehari saya mengetik docker compose up -d, atau menyusun ulang template --format dari ingatan cuma untuk tahu container mana yang sedang memegang sebuah port. Tiap kejadiannya berongkos beberapa detik dan sedikit perhatian, dan tak satu pun dari keduanya layak disebut bila berdiri sendiri.

Yang membuat saya menganggapnya serius adalah menyadari ke mana perhatian itu pergi. Mengingat kembali sebuah flag tidak gratis — ia memotong apa pun yang sedang saya pikirkan, dan potongannya hidup jauh lebih lama ketimbang waktu mengetiknya. Maka perintah yang paling sering saya ulang saya ubah jadi sepuluh kata pendek yang bisa diketik dari direktori mana pun, dan bagian menariknya ternyata bukan pemendekan itu. Melainkan segala yang wajib diputuskan lebih dulu sebelum sebuah shortcut layak dimiliki.

Pendahuluan

Tulisan ini tentang keputusan-keputusan tersebut, bukan panduan menulis shell script — kebanyakan script-nya cuma dua baris, dan yang dua baris itu dikutip utuh justru sebab memang tak ada yang tersembunyi di dalamnya. Yang layak dijelaskan adalah kenapa masing-masing berbentuk seperti itu.

A. Apa yang sebenarnya diongkoskan pengetikan berulang

Tiga hal, dan cuma yang pertama yang kentara.

Yang pertama waktu, dan justru itu yang paling tak penting. Perintah yang butuh empat detik diketik, bukan satu detik, berongkos beberapa menit dalam seminggu — nyata, tapi tak cukup untuk membenarkan pembangunan apa pun.

Yang kedua typo. Perintah panjang adalah kesempatan panjang untuk keliru, dan perintah Docker luar biasa tak pemaaf soal ini sebab flag yang salah ketik kerap masih berupa perintah sah yang mengerjakan hal lain. Kegagalan macam itu berongkos lebih mahal ketimbang mengetik ulang: yang mahal adalah waktu memahami kenapa keluarannya tak seperti yang diharapkan.

Yang ketiga justru yang sungguh-sungguh mendorong semua ini, dan sifatnya kognitif. Menahan bentuk belasan pola perintah di ingatan kerja punya ongkos yang dibayar terus-menerus, bukan per pemanggilan. Tiap kali saya meraih template format yang tak dipakai selama dua pekan, saya sedang membelanjakan perhatian untuk mengingat, bukan untuk yang sedang dikerjakan. Sepuluh kata pendek menghapusnya sama sekali, sebab tak ada lagi yang perlu diingat.

B. Kenapa perintah Docker khususnya memanjang

Antarmuka barisnya dibangun demi kelengkapan, bukan demi pemakaian harian — dan itu prioritas yang benar untuk tool seluas itu sekaligus canggung bagi orang yang mengetiknya berulang-ulang.

Mendaftar container contoh paling terang. Keluaran bawaannya cukup lebar sampai terlipat di kebanyakan terminal, jadi siapa pun yang memakainya dengan serius akan meraih --format — yang menerima template Go, sebuah bahasa kecil yang tertanam di dalam flag-nya. Hasilnya perintah yang perkasa, cermat, dan mustahil diingat dengan benar sebulan kemudian.

Compose menambahkan satu kata lagi ke segalanya. Network menambahkan tingkat ketiga, tempat keterangan yang layak dimiliki justru terpecah antara network ls dan network inspect lalu wajib digabungkan sendiri oleh yang membacanya. Tak satu pun dari ini cacat pada tool-nya. Beginilah yang terjadi ketika antarmuka umum bertemu kebiasaan yang khusus.

C. Shortcut bukan alias, dan bedanya itulah seluruh rancangannya

Cara paling kentara memendekkan perintah adalah shell alias, dan ia bekerja baik untuk persis satu keadaan: manusia yang mengetik di shell interaktif yang sudah membaca file tempat alias-nya ditulis.

Di luar keadaan itu ia tak ada. Script tak bisa memanggilnya, sebab script tak membaca konfigurasi shell interaktif. sudo tak melihatnya. Job terjadwal tak melihatnya. Dan karena ia tinggal di dalam konfigurasi sebuah shell, bukan di disk sebagai program, tak ada apa pun yang bisa dirangkai dengannya.

File yang bisa dieksekusi di PATH tak punya satu pun batasan itu. Ia program, jadi apa pun yang sanggup menjalankan program sanggup menjalankannya — termasuk salah satu shortcut lain dalam himpunan ini, dan itu ternyata lebih menentukan dari dugaan saya di awal.

D. Sepuluh perintah itu apa saja

Semuanya jatuh ke empat kelompok, dan pengelompokan itulah yang membuatnya gampang diingat.

Daur hidup Compose: dcup dan dcdown menyalakan dan mematikan satu stack; dcb mem-build; dcx membuka shell di dalam satu service. Membaca keadaan: dls mendaftar container yang berjalan sebagai tabel bernomor, dcls mengerjakan hal serupa untuk project Compose yang sedang aktif, dan dfind mencari di dalam daftar itu. Image: bdi menyimpan image ke file terkompresi dan rdi memuatnya kembali. Network: dcn membuat, menghapus, dan mendaftarnya.

Sembilan dari sepuluhnya berkisar antara dua sampai empat puluh baris. Yang kesepuluh dua ratus enam puluh baris, dan selisih kedua angka itu sendiri salah satu temuan di bawah.

E. Enam hambatan yang menghalangi

Dinyatakan sebagai tujuan: mengubah perintah Docker yang paling sering saya ulang jadi kata tunggal yang bisa diketik dari direktori mana pun, tanpa kehilangan keluwesan perintah yang digantikannya, dan dalam bentuk yang bisa dipanggil otomasi lain, bukan ditulis ulang di sana.

Gampang dirumuskan, canggung dibangun. Ada enam hambatan yang menghalangi, dan dua yang pertama menentukan bentuk semua sisanya.

Hambatan pertama: perintah pendek wajib bekerja dari mana pun, kalau tidak ia cuma memindahkan persoalannya. Script yang wajib dijalankan dari direktori tempat ia tinggal sudah menukar mengingat flag jadi mengingat path, dan itu bukan kemajuan. Alternatif yang ditolak adalah shell alias, dan ia ditolak karena alasan yang spesifik, bukan karena prinsip: alias tak terlihat oleh script, oleh sudo, maupun oleh job terjadwal — dan itu meniadakan perangkaian yang dijelaskan di bawah. Penggantinya: tiap file dijadikan executable lalu symbolic link-nya ditaruh di PATH, sehingga shortcut-nya jadi program, bukan kenyamanan shell.

Hambatan kedua: sepuluh nama sembarang cuma akan memindahkan hafalannya. Kalau tiap shortcut dinamai menurut apa pun yang terasa masuk akal hari itu, hasilnya sepuluh hal tambahan untuk diingat — persis hasil yang hendak dihindari latihan ini. Alternatif yang ditolak adalah menamai tiap script sendiri-sendiri. Penggantinya sebuah pola yang diterapkan konsisten: d di depan untuk Docker, c sesudahnya bila perintahnya milik Compose, lalu kata kerjanya. Mengetahui polanya sudah cukup untuk menebak sebuah nama tanpa mencarinya, dan itu sifat yang lebih kuat ketimbang tiap nama yang cerdas sendiri-sendiri.

Hambatan ketiga: shortcut yang menelan argumennya cuma berguna untuk satu kasus yang paling lazim. Menanam perintahnya secara kaku membuatnya lebih pendek sekaligus membuatnya tak berguna begitu nama service atau flag tambahan dibutuhkan — dan pada titik itu perintah utuhnya kembali dan shortcut-nya ditinggalkan. Menanam secara kaku itulah alternatif yang ditolak; penggantinya meneruskan segalanya, sehingga shortcut-nya jadi ejaan yang lebih pendek dari perintahnya, bukan versi yang lebih sempit.

Hambatan keempat: keluaran daftar bawaannya sulit dibaca sekilas. Kolomnya tak sejajar begitu panjang namanya beragam, tak ada penomoran untuk menyebut satu baris, dan tak ada totalnya. Ketiganya kekurangan kecil yang menjumlah jadi keharusan membaca dengan cermat padahal melirik semestinya cukup. Mengandalkan --format saja adalah alternatif yang ditolak — ia menentukan field mana yang tampil, bukan bagaimana semuanya ditata. Penggantinya merender tabelnya sendiri, dengan kolom yang sejajar, nomor baris, dan hitungan di bawahnya.

Hambatan kelima: tak ada satu perintah Docker pun yang menjawab pertanyaan yang sungguh-sungguh saya ajukan tentang network. Pertanyaannya "network mana saja yang ada, subnet berapa yang dipegang masing-masing, dan container mana saja yang ada di dalamnya" — dan menjawabnya berarti membaca satu daftar untuk namanya, lalu meng-inspect tiap network untuk subnet-nya, lalu meng-inspect lagi untuk anggotanya, dan menggabungkan tiga keluaran dengan mata. Mengerjakan itu manual adalah alternatif yang ditolak. Penggantinya satu perintah yang mengerjakan penggabungannya lalu mencetak satu tabel, dengan lebar kolom dihitung dari datanya, bukan ditebak di muka.

Hambatan keenam: membuat network gagal terlambat dan tak menolong ketika subnet-nya sudah terpakai. Kegagalannya tiba dari daemon sesudah percobaannya, dan pesannya menyebut bentrokannya tanpa menyebut network yang menyebabkannya — jadi langkah berikutnya selalu pencarian manual untuk tahu siapa yang memegang rentang itu. Membiarkan daemon yang menolak adalah alternatif yang ditolak. Penggantinya memeriksa nama dan subnet lebih dulu, lalu ketika subnet-nya memang terpakai, menyebutkan nama network yang memegangnya di dalam pesan error.

Urutannya mencerminkan apa yang diatur tiap hambatan. Dua yang pertama soal bentuk — di mana sebuah shortcut tinggal dan apa namanya — dan keduanya berlaku sama untuk kesepuluhnya, dan karena itulah tak ada hal lain yang bisa diputuskan sebelum keduanya. Yang ketiga soal batas sebuah shortcut: seberapa banyak dari perintah aslinya yang boleh ia sembunyikan. Tiga yang terakhir berbeda jenis, dan merekalah yang melahirkan kode sungguhan, bukan sekadar kesepakatan: dua soal membaca keadaan yang dilaporkan Docker dengan canggung, dan satu soal mencegah kegagalan, bukan menjelaskannya sesudahnya.

Metode

A. Executable di PATH, bukan alias

Inilah jawaban atas hambatan pertama, dan dialah yang memungkinkan semua yang datang sesudahnya.

Tiap script dijadikan executable sekali lalu di-link ke direktori yang memang sudah ada di PATH. Link-nya membuat file-nya tetap tinggal di tempat ia disunting dan dilacak version control, sementara perintahnya tersedia di mana-mana.

bash
chmod +x ~/programs/docker/*
sudo ln -s ~/programs/docker/dls /usr/local/bin/dls
# …one link per script. The file stays where it is edited;
# the command exists everywhere, including inside other scripts.

Akibat yang paling menentukan bukan kenyamanannya. Melainkan semuanya jadi bisa dirangkai, dan script terpendek dalam himpunan inilah buktinya.

bash
#!/bin/bash

dls | grep "$1"

Itulah dfind selengkapnya. Ia mencari di daftar container dengan memanggil dls — bukan dengan menggandakan apa yang dikerjakan dls. Ia sanggup begitu semata-mata karena dls adalah program di PATH, bukan shell alias, dan inilah persis perangkaian yang ditutup oleh pendekatan alias. Sifat yang sama pula yang membuat otomasi yang lebih besar di tempat lain bisa memanggil ini ketimbang menuliskan ulang sebuah template format.

B. Satu pola penamaan, bukan sepuluh nama

Inilah jawaban atas hambatan kedua. Nama-namanya tidak cerdas sendiri-sendiri, dan itu disengaja.

d di depan berarti Docker. c sesudahnya berarti perintahnya milik Compose. Yang mengikuti adalah kata kerjanya, disingkat sampai batas ia masih tak bermakna ganda.

bash
dcup  dcdown  dcb  dcx  dcls     # d + c + verb  → docker compose …
dls   dfind                      # d + verb      → docker (no compose)
bdi   rdi                        # backup/restore docker image
dcn                              # docker compose network

Ujian sebuah skema penamaan adalah apakah ia memungkinkan kita menebak. Dengan mengetahui polanya, dcb bisa diturunkan tanpa dihafal, begitu pula kenyataan bahwa dls dan dcls pasti berbeda cakupan, bukan berbeda perilaku. Orang yang tahu tiga di antaranya bisa menyimpulkan sisanya.

C. Meneruskan argumen, bukan menyembunyikannya

Inilah jawaban atas hambatan ketiga, sekaligus beda antara shortcut yang bertahan dan yang akhirnya ditinggalkan.

bash
if [ $# -eq 0 ]; then
  docker compose up -d
else
  # Everything is forwarded: a service name, extra flags, whatever.
  docker compose up -d "$@"
fi

Tanda kutipnya bagian yang menanggung beban. "$@" mempertahankan tiap argumen sebagai kata terpisah bahkan ketika isinya memuat spasi, dan itulah yang membuat dcup jadi ejaan yang lebih pendek dari perintahnya, bukan bagian kecil yang dibatasi darinya. Tanpa itu shortcut-nya bekerja sampai argumen pertama yang butuh tanda kutip, lalu gugur dengan cara yang sulit ditimpakan ke sebabnya.

Asasnya berlaku umum: shortcut semestinya mengurangi pengetikan, bukan mengurangi kemampuan. Begitu ia tak sanggup mengerjakan apa yang sanggup dikerjakan aslinya, ia berhenti dipakai untuk segala keperluan dan hafalannya kembali lagi.

D. Merender tabelnya, bukan sekadar memformat field-nya

Inilah jawaban atas hambatan keempat. Docker bersedia memformat field; ia tak menata tabel.

bash
containers=$(docker ps --format '{{.Names}}\t{{.Ports}}\t{{.Image}}')

i=1
while IFS=$'\t' read -r name ports image; do
  [ -z "$ports" ] && ports="-"          # empty reads as missing, not blank
  printf "%-3s | %-20s | %-15s | %s\n" "$i" "$name" "$ports" "$image"
  ((i++))
done <<< "$containers"

echo "Total container berjalan: $((i - 1))"

Tiga keputusan kecil yang mengerjakan pekerjaannya. Keluaran berpemisah tab diurai, bukan dicetak langsung, sehingga penyejajarannya diputuskan di sini, bukan oleh nilai terpanjang. Daftar port yang kosong jadi tanda hubung, sebab sel kosong terbaca seperti kesalahan render sementara tanda hubung terbaca sebagai jawaban. Dan pencacah yang menomori barisnya sekaligus melahirkan totalnya di akhir — tak berongkos apa pun, dan menjawab "berapa yang sedang jalan" tanpa menghitung baris dengan mata.

E. Menggabungkan yang dilaporkan Docker terpisah-pisah

Inilah jawaban atas hambatan kelima, sekaligus penjelasan kenapa satu script berpanjang dua ratus enam puluh baris sementara sisanya di bawah empat puluh.

Pertanyaan "network mana saja yang ada, dengan subnet apa, memuat container mana" tak punya satu perintah pun di belakangnya. Namanya datang dari sebuah daftar; subnet-nya datang dari meng-inspect tiap network; anggotanya datang dari meng-inspect-nya lagi dengan template berbeda. Merakit jawabannya itulah pekerjaannya.

bash
while IFS=$'\t' read -r net_id net_name; do
  subnet=$(docker network inspect "$net_id" \
    --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}')

  raw_containers=$(docker network inspect "$net_id" \
    -f '{{range $k, $v := .Containers}}{{$v.Name}}|{{$v.IPv4Address}}{{"\n"}}{{end}}')
  # …collected per network, then printed as one table
done <<< "$all_networks"

Karena sebuah network bisa memuat container sebanyak apa pun, barisnya jadi tak seragam: satu network menempati satu baris, yang lain menempati lima. Lebar kolom yang dipatok akan memenggal nama atau memboroskan sebagian besar terminal, jadi lebarnya diukur dari datanya sebelum apa pun dicetak.

bash
for ((j=0; j<total; j++)); do
  [ ${#NET_NAMES[$j]} -gt $col_name ] && col_name=${#NET_NAMES[$j]}
  [ ${#NET_SUBNETS[$j]} -gt $col_subnet ] && col_subnet=${#NET_SUBNETS[$j]}
done
col_name=$((col_name + 2))        # measured, then padded — never guessed

Dari sinilah jumlah barisnya datang, dan pertukarannya layak disebut terus terang. Dua ratus enam puluh baris shell itu banyak untuk sebuah perintah pendaftar. Ia dibenarkan di sini semata-mata karena pertanyaannya sering saya ajukan dan alternatif manualnya tiga perintah plus penggabungan di kepala — tapi di situlah kata "shortcut" berhenti jadi gambaran yang tepat atas apa yang dibangun.

F. Gagal sebelum percobaannya, bukan sesudahnya

Inilah jawaban atas hambatan keenam, sekaligus satu-satunya yang mencegah kegagalan, bukan menyajikan keterangan dengan lebih terang.

Membuat network dengan subnet yang sudah dipegang pihak lain gugur di daemon. Pesannya melaporkan tumpang tindihnya tanpa menyebut network yang bertanggung jawab, jadi gerakan berikutnya selalu sebuah pencarian. Pemeriksaannya memindahkan pencarian itu ke sebelum percobaannya, lalu melaporkan jawabannya sebagai bagian dari penolakannya.

bash
for net_id in $all_networks; do
  existing_subnet=$(docker network inspect "$net_id" \
    --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}')
  if [ "$existing_subnet" = "$SUBNET" ]; then
    existing_net_name=$(docker network inspect "$net_id" --format '{{.Name}}')
    # The name is the whole point: without it, this is just a slower daemon error.
    echo "Error: subnet '$SUBNET' is already used by network '$existing_net_name'."
    exit 1
  fi
done

Nama di dalam pesan itulah seluruh nilai pemeriksaannya. Mendeteksi bentrokannya lebih awal tak menghemat apa pun bila berdiri sendiri — daemon-nya pun akan mendeteksinya. Yang tak dikerjakan daemon adalah memberi tahu network mana yang harus didatangi, dan satu keping keterangan itulah beda antara pesan yang bisa ditindaklanjuti dan pesan yang memulai penyelidikan.

Hasil dan Pembahasan

A. Apa yang sesungguhnya membaik

Pengetikan yang terhemat bagian terkecilnya, dan saya takkan membangun ini cuma demi itu. Yang berubah adalah banyaknya yang saya tahan di kepala selagi bekerja: template format-nya hilang, kombinasi flag-nya hilang, dan yang tersisa satu pola penamaan yang cukup kecil untuk disusun ulang dari tiga contoh.

Golongan typo-nya ikut lenyap bersamanya. Flag yang salah ketik kerap masih perintah sah yang mengerjakan yang tak dimaksudkan; shortcut yang salah ketik adalah perintah yang tak ada, dan shell langsung mengatakannya. Memindahkan error dari senyap jadi lantang lebih berharga ketimbang memindahkannya dari sering jadi jarang.

Perangkaiannya jadi kejutan. Semua ini saya bangun untuk pemakaian interaktif, lalu saya temukan otomasi lain memanggilnya — script deployment yang mendaftar container dengan memanggil dls, bukan dengan menuliskan ulang template-nya. Itu cuma mungkin karena semuanya program di PATH, dan keputusan itu diambil demi alasan yang sama sekali berbeda.

B. Dari mana selisih jumlah barisnya datang

Sembilan di antaranya pendek sebab Docker sudah mengerjakan pekerjaannya dan cuma ejaannya yang perlu dipendekkan. Satu berpanjang dua ratus enam puluh baris sebab Docker sama sekali tak mengerjakan pekerjaannya, dan script-nya justru penerapan yang hilang, bukan cara yang lebih pendek untuk memanggil yang sudah ada.

Pembedaan itu layak disadari ketika memutuskan apakah sesuatu perlu dibangun. Pembungkus atas perintah yang sudah ada semestinya kecil; kalau ternyata tidak, sebabnya biasanya perintah yang dibungkus itu memang tak menjawab pertanyaan yang sedang diajukan. Ukurannya adalah isyarat tentang keadaan mana dari keduanya yang sedang kita hadapi, dan itulah tolok ukur yang jujur atas apa yang sesungguhnya dikerjakan sebuah shortcut.

C. Di mana ini berhenti jadi gagasan yang baik

Semua ini memang sengaja dibuat sebagai tool pribadi. Ia ikut ke mana pun saya bekerja, dan apa pun yang dipakai bersama atau diserahterimakan memakai perintah utuh yang dibungkusnya — perintah yang tetap utuh dan terbaca di balik tiap jalan pintas ini.

Semuanya juga lapisan yang bisa menyimpang. Shortcut yang menanam sebuah flag yang nanti diubah rilis Docker akan tetap bekerja sampai ia tak lagi bekerja, dan kebingungannya akan sebanding dengan seberapa lama shortcut itu sudah dipercaya.

Dan pemendekannya punya dasar. Di bawah panjang tertentu, namanya berhenti bisa diturunkan dari polanya lalu kembali jadi hafalan — dan di situlah seluruh latihan ini berawal.

Simpulan

Pelajaran yang saya bawa dari sini bukan soal Docker. Melainkan bahwa ongkos yang layak dioptimalkan justru yang kognitif, dan itulah yang paling belakangan saya sadari. Waktu dan typo bisa diukur dan kecil; belanja terus-menerus untuk menahan belasan bentuk perintah di ingatan kerja tak bisa diukur sekaligus tak kecil, dan itulah yang sungguh-sungguh dihapus sebuah shortcut yang baik.

Pelajaran kedua soal di mana sebuah shortcut tinggal. Menjadikan semua ini program, bukan alias, adalah keputusan tentang kenyamanan yang ternyata jadi keputusan tentang kemampuan — sebab program bisa dipanggil program lain, sementara shell alias cuma bisa diketik manusia.

Istilah

Shell alias
Nama pendek untuk sebuah perintah yang ditulis di konfigurasi shell. Tersedia bagi orang yang mengetik interaktif; tak terlihat oleh script, sudo, maupun job terjadwal.
PATH
Daftar direktori tempat shell mencari executable. File yang ditaruh di sana jadi perintah yang tersedia dari direktori kerja mana pun.
Symbolic link
Entri filesystem yang menunjuk file lain. Dipakai di sini supaya script tetap tinggal di tempat ia disunting sementara perintahnya ada di PATH.
Template Go
Bahasa format kecil yang diterima flag --format milik Docker, cukup perkasa untuk mengambil field apa pun dan cukup canggung sampai layak dibungkus.
Compose
Komponen Docker yang menjalankan aplikasi multi-container dari sebuah file deklaratif, sekaligus alasan separuh shortcut ini membawa huruf c.
Subnet
Rentang alamat yang diberikan ke sebuah Docker network. Dua network tak bisa memegang rentang yang sama, dan bentrokan itulah yang diperiksa lebih dulu oleh salah satu script ini.
Composability
Sifat yang membuat satu tool bisa dipakai di dalam tool lain. Di sini ia akibat dari menjadi program di PATH, bukan sekadar kenyamanan shell.

Technologies covered

  • Bash
  • Linux
  • Docker
  • Docker Compose

About the author

Photo of Romi Fadli

Romi Fadli, S.Kom.

Solution Architect · Backend Engineer · Embedded Systems

In my day job I work as a solution architect. I design the system, lead the team that builds it — quality assurance, backend developers, a UI developer, DevOps and DevSecOps — and write the most critical modules myself, such as a certificate authority, a long-term PDF signer, and the core API of a personnel system.

I work across the whole stack that a running system actually needs. On the hardware side that means PCB design, microcontrollers, and embedded firmware — including RISC-V boards running FreeRTOS and Embassy, speaking MQTT over mutually authenticated TLS on a microcontroller with 64 KB of SRAM.

Most of my day-to-day work is software: Rust backends and API modules built on Clean Architecture, an OAuth2/OpenID Connect authorization server written from scratch, PAdES document signing, and certificate authorities — root CAs, timestamping authorities, and OCSP responders. I also build the frontends that sit on top of them.

Running all of that means infrastructure: Docker Compose stacks, networking, Mikrotik and RADIUS, observability with OpenTelemetry, and a steady habit of writing command-line tools and utilities for Linux when the existing ones do not fit.

Share

Enjoyed this?

Get an email when a new article is published.

Referenced by

Three image layer stacks, each with a version tag of its own colour, blue, orange, and green, each leading to an archive file banded in the same colour

Perintah yang memberi versi tersendiri pada tiap modul stack, mem-build image-nya di bawah tag yang berarti tepat satu build, menolak memakai ulang versi atau menelan compile yang gagal, dan mengarsipkan image menurut nama dan tag supaya versi tak saling menimpa.

7 min read Read more →
A browser window sends one orange path into a single web server, which routes it on to the orange staging environment; dashed paths to the blue development and green production environments stay inactive

Dua perintah yang menjaga tiga environment tetap terpisah di satu mesin dan satu web server: satu menetapkan alamat environment dan menyelaraskan setiap file yang menyimpannya, merender nginx dari template dan menolak bila bentrok; satu lagi mengarahkan browser ke satu environment.

11 min read Read more →

Related Articles

A stack of Markdown documents and an orange arrow leading to a browser page with a side menu, a heading, paragraphs, a dark code panel, and a table of contents with its active entry highlighted

Satu script yang mengubah dokumentasi Markdown satu project menjadi situs statis yang terbuka dari folder tanpa server maupun internet: menu, daftar isi yang mengikuti pembaca, tabel yang tak pernah terpotong, kode dengan tombol salin, dan tautan yang tetap berfungsi.

7 min read Read more →
An old layout with a grey banner and a new structure with a green banner, each holding a blue database, a purple document store, and an orange telemetry store; three coloured paths pass through one export package marked with a green check

Empat perintah yang memindahkan stack dari layout lama ke struktur baru melintasi versi mayor: export tanpa mengubah data sumber, import tiap store sesuai cara yang diizinkan versinya, verifikasi apa yang benar-benar tiba, dan rename modul sambil memindahkan datanya.

11 min read Read more →
Three image layer stacks, each with a version tag of its own colour, blue, orange, and green, each leading to an archive file banded in the same colour

Perintah yang memberi versi tersendiri pada tiap modul stack, mem-build image-nya di bawah tag yang berarti tepat satu build, menolak memakai ulang versi atau menelan compile yang gagal, dan mengarsipkan image menurut nama dan tag supaya versi tak saling menimpa.

7 min read Read more →