Tutorial Podman Praktis: Untuk Programmer & DevOps
Tutorial Podman praktis untuk pekerjaan sehari-hari programmer dan DevOps: container, database, volume, network, debugging, build image, registry, rootless, Compose, Pod, systemd, Quadlet, dan tips troubleshooting.
Podman bukan cuma “Docker tanpa daemon”. Dalam pekerjaan sehari-hari programmer dan DevOps, Podman bisa dipakai untuk menjalankan database lokal, menguji service, membangun image, mengelola environment development, menjalankan job sekali jalan, melihat log, debugging container, membuat stack multi-container, sampai menjalankan service Linux dengan systemd.
Tutorial ini fokus pada praktik yang benar-benar sering terjadi setiap hari, bukan sekadar daftar command. Contoh menggunakan Linux/macOS dengan Podman yang sudah terpasang. Sebagian fitur networking dan systemd paling relevan di Linux.
Prasyarat
Pastikan Podman tersedia:
podman --version
podman info
Coba container pertama:
podman run --rm hello-world
Tip: Biasakan memakai
--rmuntuk container percobaan atau command sekali jalan. Container tidak menumpuk setelah proses selesai.
1. Memahami Pola Dasar Podman
Hampir semua pekerjaan Podman sehari-hari dapat dipahami sebagai siklus:
image → container → logs / exec / inspect → stop → remove
Lihat image yang tersedia:
podman images
Lihat container:
podman ps
podman ps -a
Jalankan container:
podman run -d --name web nginx:alpine
Hentikan:
podman stop web
Hapus:
podman rm web
Tip: Gunakan nama container yang konsisten.
api-dev,postgres-dev, danredis-devjauh lebih mudah diingat daripada nama acak.
2. Menjalankan Database Lokal Tanpa Menginstal Database di Laptop
Ini salah satu penggunaan Podman yang paling berguna bagi programmer.
Daripada memasang PostgreSQL langsung ke laptop, jalankan sebagai container:
podman run -d \
--name postgres-dev \
-e POSTGRES_PASSWORD=devpass \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
postgres:18
Periksa:
podman ps
podman logs postgres-dev
Masuk ke PostgreSQL:
podman exec -it postgres-dev psql -U postgres -d myapp
Sekarang aplikasi lokal dapat menggunakan:
host = localhost
port = 5432
database = myapp
user = postgres
password = devpass
Hentikan dan hidupkan lagi
podman stop postgres-dev
podman start postgres-dev
Data tetap ada selama container belum dihapus.
Tetapi untuk workflow development yang lebih aman, gunakan volume.
3. Gunakan Volume untuk Data yang Harus Bertahan
Buat volume:
podman volume create postgres-data
Jalankan PostgreSQL:
podman run -d \
--name postgres-dev \
-e POSTGRES_PASSWORD=devpass \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
-v postgres-data:/var/lib/postgresql/data \
postgres:18
Lihat volume:
podman volume ls
Inspect:
podman volume inspect postgres-data
Penting: Container dan data adalah dua hal berbeda. Menghapus container seharusnya tidak otomatis berarti kehilangan data aplikasi.
4. Jalankan Redis, MySQL, atau Service Pendukung Lain
Pola yang sama dapat digunakan untuk dependency development.
Redis:
podman run -d \
--name redis-dev \
-p 6379:6379 \
redis:alpine
Cek:
podman exec -it redis-dev redis-cli
Nginx:
podman run -d \
--name nginx-dev \
-p 8080:80 \
nginx:alpine
Sekarang buka:
http://localhost:8080
Trik: Gunakan suffix
-dev,-test, atau nama project pada container. Ini sangat membantu ketika laptop sudah memiliki banyak project.
5. Masuk ke Container untuk Debugging
Ketika aplikasi bermasalah, exec adalah salah satu command yang paling sering digunakan.
podman exec -it nginx-dev sh
Kemudian:
ls
env
ps
Keluar:
exit
Jika image memiliki Bash:
podman exec -it myapp bash
Tetapi jangan berasumsi semua image memiliki Bash.
Tip: Image minimal seperti Alpine sering hanya memiliki
sh. Untuk debugging, cobashlebih dulu.
6. Membaca Log dengan Benar
Daripada langsung masuk ke container, lihat log terlebih dahulu:
podman logs myapp
Follow log:
podman logs -f myapp
Batasi output:
podman logs --tail 100 myapp
Gabungkan:
podman logs --since 30m myapp
Trik: Saat incident, jangan langsung restart container. Ambil log terlebih dahulu. Restart yang terlalu cepat bisa menghilangkan konteks error yang justru sedang Anda cari.
7. Container Jalan, tetapi Aplikasi Tidak Bisa Diakses
Gunakan tiga pemeriksaan sederhana.
Cek status
podman ps
Cek port
podman port myapp
Cek detail container
podman inspect myapp
Jika aplikasi mendengarkan port 3000 di dalam container:
podman run -d \
--name myapp \
-p 3000:3000 \
myapp:latest
Ingat:
-p HOST_PORT:CONTAINER_PORT
Jadi:
-p 8080:3000
berarti browser mengakses port 8080 pada host, sedangkan aplikasi tetap mendengarkan port 3000 di container.
8. Menggunakan Environment Variable
Untuk aplikasi:
podman run -d \
--name api-dev \
-e NODE_ENV=development \
-e PORT=3000 \
-e DATABASE_URL='postgresql://postgres:devpass@postgres-dev:5432/myapp' \
myapp:latest
Untuk banyak variable, gunakan file:
podman run -d \
--name api-dev \
--env-file .env \
myapp:latest
Security tip: Jangan commit
.envyang berisi password production ke Git. Untuk secret production, gunakan mekanisme secret management yang sesuai, bukan sekadar environment variable biasa.
9. Membuat Network untuk Beberapa Container
Misalnya kita memiliki:
api → postgres
api → redis
Buat network:
podman network create myapp-net
Jalankan PostgreSQL:
podman run -d \
--name postgres-dev \
--network myapp-net \
-e POSTGRES_PASSWORD=devpass \
-e POSTGRES_DB=myapp \
postgres:18
Redis:
podman run -d \
--name redis-dev \
--network myapp-net \
redis:alpine
API:
podman run -d \
--name api-dev \
--network myapp-net \
-p 3000:3000 \
myapp:latest
Dalam konfigurasi aplikasi, gunakan nama service/container sesuai network:
postgres-dev:5432
redis-dev:6379
Tip: Jangan menggunakan
localhostuntuk komunikasi antar-container. Di dalam container,localhostberarti container itu sendiri.
10. Build Image dari Dockerfile
Podman dapat membangun image dari Dockerfile.
Contoh:
FROM node:24-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Build:
podman build -t myapp:dev .
Lihat image:
podman images
Jalankan:
podman run --rm -p 3000:3000 myapp:dev
Tip: Beri tag yang jelas seperti
myapp:dev,myapp:test, ataumyapp:1.4.2. Jangan mengandalkanlatestuntuk deployment yang membutuhkan reproducibility.
11. Debug Image Build
Jika build gagal:
podman build --no-cache -t myapp:debug .
Jika ingin melihat layer image:
podman history myapp:dev
Inspect metadata:
podman inspect myapp:dev
Trik: Jangan selalu menggunakan
--no-cache. Itu berguna untuk troubleshooting, tetapi menghilangkan manfaat build cache dan dapat membuat build jauh lebih lambat.
12. Bind Mount Source Code untuk Development
Untuk aplikasi yang sedang dikembangkan, Anda mungkin tidak ingin rebuild image setiap kali mengubah satu file.
Contoh:
podman run --rm -it \
-p 3000:3000 \
-v "$PWD":/app:Z \
myapp:dev
Pada host Linux dengan SELinux, opsi :Z atau :z dapat diperlukan untuk relabeling volume sesuai kebutuhan.
Perhatikan perbedaan:
:Z— volume private untuk satu container.:z— volume shared untuk beberapa container.
Warning: Opsi SELinux dan behavior mount dapat berbeda menurut host dan filesystem. Jangan menambahkan
:Zsecara membabi buta pada semua environment.
13. Shortcut Alias untuk Pengguna Docker
Jika tim Anda terbiasa dengan Docker, beberapa command Podman terasa sangat familiar:
alias docker=podman
Tetapi ini sebaiknya dianggap sebagai transition aid, bukan bukti bahwa seluruh ecosystem Docker identik dengan Podman.
Untuk script CI/CD, jangan buru-buru melakukan search-and-replace docker menjadi podman.
Uji dahulu:
- Docker socket
- Compose
- build engine
- networking
- volume
- privileged container
- registry authentication
- CI runner
14. Menggunakan Podman Compose untuk Development Stack
Untuk project sederhana dengan beberapa service, Compose-style workflow sangat nyaman.
Contoh compose.yaml:
services:
app:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://postgres:devpass@db:5432/myapp
depends_on:
- db
db:
image: postgres:18
environment:
POSTGRES_PASSWORD: devpass
POSTGRES_DB: myapp
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
Jika tool Compose yang Anda gunakan tersedia:
podman compose up -d
Lihat status:
podman compose ps
Turunkan stack:
podman compose down
Catatan: Compatibility Compose perlu diuji untuk fitur yang digunakan project. Jangan menganggap semua behavior Docker Compose otomatis identik.
15. Gunakan Pod untuk Workload yang Memang Cocok
Podman mempunyai Pod sebagai first-class object.
Buat Pod:
podman pod create --name webstack -p 8080:80
Tambahkan container:
podman run -d --pod webstack --name web nginx:alpine
Lihat:
podman pod ps
podman ps --pod
Hentikan:
podman pod stop webstack
Tip: Pod cocok ketika beberapa container memang harus diperlakukan sebagai satu unit dan berbagi network namespace. Jangan membuat Pod hanya karena “bisa”; untuk stack sederhana, network biasa sering lebih mudah dipahami.
16. Menjalankan Container Sekali Jalan
Podman sangat praktis untuk pekerjaan disposable.
Contoh menjalankan shell Ubuntu:
podman run --rm -it ubuntu:24.04 bash
Tes curl tanpa memasang curl di host:
podman run --rm curlimages/curl https://example.com
Tes DNS atau networking:
podman run --rm busybox nslookup example.com
Trik: Ini salah satu kegunaan Podman yang sering diremehkan. Daripada “mengotori” laptop dengan berbagai utility, jalankan utility tersebut sebagai container sementara.
17. Membersihkan Container dan Image yang Tidak Terpakai
Setelah beberapa minggu bekerja, laptop bisa penuh oleh image lama.
Lihat disk usage:
podman system df
Bersihkan resource yang tidak digunakan:
podman system prune
Jika memang ingin lebih agresif, baca opsi command tersebut terlebih dahulu sebelum menjalankannya.
Warning: Jangan menjalankan cleanup agresif pada host production tanpa memahami resource apa yang akan dihapus. “Prune” bukan sinonim dari “aman-aman saja”.
18. Copy File dari dan ke Container
Dari host ke container:
podman cp ./config.json api-dev:/app/config.json
Dari container ke host:
podman cp api-dev:/app/logs/error.log ./error.log
Ini sangat berguna ketika troubleshooting tanpa harus memasang editor di dalam container.
19. Melihat Resource CPU dan Memory
Saat aplikasi terasa lambat:
podman stats
Untuk satu container:
podman stats api-dev
Perhatikan:
- CPU
- memory
- network I/O
- block I/O
- process count
Tip:
podman statsbagus untuk diagnosis cepat. Untuk production jangka panjang, gunakan observability stack yang memang menyimpan metrics dan membuat baseline.
20. Membatasi Resource Container
Untuk menghindari satu service menghabiskan semua resource:
podman run -d \
--name api-dev \
--memory=512m \
--cpus=1.0 \
myapp:dev
Resource limit sangat penting pada server yang menjalankan banyak workload.
Tetapi jangan memilih angka secara asal. Gunakan hasil observability dan load test untuk menentukan limit yang masuk akal.
21. Health Check
Container yang “running” belum tentu aplikasinya sehat.
Contoh:
podman run -d \
--name api-dev \
--health-cmd='curl -f http://localhost:3000/health || exit 1' \
--health-interval=30s \
--health-timeout=5s \
--health-retries=3 \
myapp:dev
Kemudian inspect status health:
podman inspect api-dev
Trik: Bedakan process health dengan application health. HTTP endpoint
/healthyang benar-benar memeriksa dependency sering jauh lebih berguna daripada sekadar memastikan PID masih hidup.
22. Restart Policy untuk Service
Untuk workload service:
podman run -d \
--name api-dev \
--restart=unless-stopped \
myapp:dev
Tetapi untuk Linux production, terutama jika Anda memang menggunakan systemd, pertimbangkan lifecycle management melalui systemd/Quadlet daripada membuat semua logika restart berada di command podman run.
23. Podman + systemd: Praktik Production Linux
Untuk service Linux, Podman dapat diintegrasikan dengan systemd menggunakan Quadlet.
Contoh file:
[Unit]
Description=My API Container
After=network-online.target
[Container]
Image=registry.example.com/myapp:1.2.3
PublishPort=3000:3000
[Service]
Restart=always
[Install]
WantedBy=default.target
Setelah konfigurasi dibuat sesuai lokasi dan user yang digunakan, systemd dapat mengelola lifecycle service tersebut.
Keuntungannya:
- lifecycle terintegrasi dengan OS
- status bisa dilihat dengan
systemctl - log dapat diperiksa dengan
journalctl - dependency dapat diatur melalui systemd
- service dapat dijalankan sebagai user sesuai desain deployment
Tip: Untuk server Linux single-node atau small-scale, kombinasi Podman + systemd + Quadlet sangat layak dipelajari sebelum langsung menambahkan orchestration platform yang jauh lebih kompleks.
24. Troubleshooting Cepat: Checklist 60 Detik
Ketika container bermasalah, jalankan urutan berikut:
podman ps -a
podman logs --tail 200 <container>
podman inspect <container>
podman port <container>
podman stats <container>
Jika masih belum jelas:
podman exec -it <container> sh
Lalu periksa:
env
ps
ls
cat /etc/resolv.conf
Untuk masalah network:
podman network ls
podman network inspect <network>
Untuk masalah storage:
podman volume ls
podman volume inspect <volume>
Urutan ini membantu mencegah debugging dengan metode “restart lalu berdoa”.
25. Registry: Login, Tag, dan Push Image
Login:
podman login registry.example.com
Tag:
podman tag myapp:dev registry.example.com/team/myapp:1.0.0
Push:
podman push registry.example.com/team/myapp:1.0.0
Pull di server:
podman pull registry.example.com/team/myapp:1.0.0
Best practice: Untuk production, gunakan immutable version tag seperti
1.0.0atau commit SHA. Hindari deployment production berdasarkanlatestkarena tag tersebut dapat berubah.
26. Gunakan Image Digest untuk Reproducibility
Tag masih dapat dipindahkan ke image lain.
Digest lebih kuat sebagai identifier image tertentu.
Setelah image tersedia, Anda dapat memeriksa informasi image:
podman image inspect registry.example.com/team/myapp:1.0.0
Dalam pipeline production, pertimbangkan deployment menggunakan immutable digest ketika reproducibility sangat penting.
27. Rootless: Biasakan dari Awal
Periksa identity:
id
podman info
Coba menjalankan container tanpa root:
podman run --rm alpine id
Rootless container membantu mengurangi privilege yang dibutuhkan oleh workload.
Tetapi rootless bukan magic shield.
Tetap perhatikan:
- filesystem permissions
- UID/GID mapping
- networking
- privileged operations
- device access
- SELinux/AppArmor
- host kernel
- image supply chain
28. Secrets: Jangan Taruh Password di Shell History
Cara sederhana seperti:
podman run -e DB_PASSWORD=supersecret ...
bisa meninggalkan secret pada shell history atau tooling lain tergantung workflow.
Gunakan mekanisme secret yang sesuai dengan environment Anda.
Podman memiliki dukungan untuk secret management. Untuk production yang lebih kompleks, pertimbangkan Vault, cloud secret manager, Kubernetes Secrets dengan kontrol yang tepat, atau platform secret management lain.
Rule of thumb: Jika password database production bisa ditemukan dengan mudah melalui
history, desain secret management Anda perlu diperbaiki.
29. Shortcut yang Sangat Berguna
Buat alias untuk pekerjaan yang sering dilakukan:
alias pps='podman ps'
alias ppa='podman ps -a'
alias pimg='podman images'
alias plog='podman logs'
alias pexec='podman exec -it'
Untuk project tertentu, gunakan Makefile atau task runner:
up:
podman compose up -d
down:
podman compose down
logs:
podman compose logs -f
ps:
podman compose ps
Kemudian:
make up
make logs
make down
Tip: Setelah command mulai diulang lebih dari tiga kali, pertimbangkan untuk mengotomatisasikannya. Programmer yang baik mengurangi jumlah hal yang harus diingat otaknya.
30. Pola Workflow Harian Programmer
Workflow yang realistis bisa seperti ini:
Pagi
podman ps
podman compose up -d
Mulai coding
Source code di-bind mount ke container.
Database
PostgreSQL dan Redis tetap hidup sebagai dependency lokal.
Debug
podman logs -f api-dev
Masuk container
podman exec -it api-dev sh
Tes
podman run --rm myapp:test
Build
podman build -t myapp:$GIT_SHA .
Push
podman push registry.example.com/team/myapp:$GIT_SHA
Deploy
Server melakukan pull image berdasarkan tag immutable atau digest.
Ini jauh lebih reproducible daripada “di laptop saya jalan”.
31. Pola Workflow Harian DevOps
Untuk DevOps, fokusnya bergeser dari menjalankan container menjadi mengelola lifecycle.
Checklist harian:
podman ps
podman stats
podman logs --since 1h <service>
podman images
podman system df
Kemudian periksa:
- image yang digunakan
- versi deployment
- resource consumption
- error log
- health status
- disk usage
- network connectivity
- restart count
- backup status
Untuk server production, tambahkan:
- vulnerability scanning
- image provenance
- registry policy
- resource limits
- monitoring
- alerting
- backup/restore test
- disaster recovery test
32. Tips dan Trik yang Sering Menyelamatkan Waktu
Tip 1 — Gunakan --rm untuk eksperimen
podman run --rm -it alpine sh
Tidak ada sampah container setelah selesai.
Tip 2 — Jangan gunakan latest untuk production
Gunakan:
myapp:1.4.2
atau commit SHA.
Tip 3 — Pisahkan data dari container
Gunakan volume untuk database dan persistent data.
Tip 4 — Gunakan network berdasarkan aplikasi
podman network create project-net
Jangan membuat semua container berbicara melalui network default tanpa alasan.
Tip 5 — Log sebelum restart
podman logs --tail 200 service
Tip 6 — Gunakan inspect saat realitas berbeda dari asumsi
podman inspect service
Tip 7 — Jangan menjalankan container sebagai root jika tidak perlu
Gunakan rootless workflow ketika cocok.
Tip 8 — Gunakan health check
“Container running” bukan berarti “application healthy”.
Tip 9 — Build image secara reproducible
Pin base image dan dependency sesuai kebutuhan keamanan/reproducibility.
Tip 10 — Dokumentasikan command operasional
Jika hanya Anda yang tahu command restart service, itu bukan automation. Itu tribal knowledge.
33. Kesalahan yang Sebaiknya Dihindari
Menjalankan database tanpa volume
Container hilang, data ikut hilang.
Menggunakan password production di command line
Secret dapat masuk ke history atau observability tooling.
Memberikan privilege terlalu tinggi
Hindari --privileged kecuali benar-benar diperlukan dan telah dipahami risikonya.
Mengandalkan latest
Deployment menjadi sulit direproduksi.
Menghapus container sebelum membaca log
Anda mungkin menghapus bukti paling berguna.
Menganggap Docker socket selalu aman
Akses ke Docker daemon dapat menjadi privilege yang sangat kuat.
Menganggap Podman = Docker 100%
CLI dan image compatibility membantu migrasi, tetapi API, networking, Compose, storage, CI, dan security model tetap harus diuji.
34. Cheat Sheet Podman
| Kebutuhan | Command |
|---|---|
| Cek versi | podman --version |
| Info host | podman info |
| Jalankan container | podman run |
| Background | podman run -d |
| Hapus otomatis | podman run --rm |
| Daftar container | podman ps |
| Semua container | podman ps -a |
| Stop | podman stop |
| Start | podman start |
| Restart | podman restart |
| Hapus | podman rm |
| Log | podman logs |
| Follow log | podman logs -f |
| Masuk container | podman exec -it |
| Inspect | podman inspect |
| Copy file | podman cp |
| Image list | podman images |
| Build | podman build |
| Pull | podman pull |
| Push | podman push |
| Login registry | podman login |
| Volume list | podman volume ls |
| Network list | podman network ls |
| Resource monitor | podman stats |
| Disk usage | podman system df |
| Cleanup | podman system prune |
| Pod list | podman pod ps |
Kesimpulan
Podman akan terasa jauh lebih berguna ketika diperlakukan bukan sebagai “pengganti command Docker”, tetapi sebagai toolbox container untuk pekerjaan sehari-hari.
Untuk programmer, gunakan Podman untuk:
- database lokal
- Redis dan dependency development
- disposable environment
- build image
- debugging
- integration testing
- local multi-container stack
Untuk DevOps, gunakan Podman untuk:
- rootless service
- image build dan distribution
- resource management
- logging
- networking
- persistent storage
- health check
- systemd/Quadlet
- operational automation
Mulailah dari command sederhana:
podman run
podman ps
podman logs
podman exec
podman inspect
podman build
podman push
Kemudian naik ke:
Network
→ Volume
→ Compose
→ Pod
→ Rootless
→ Registry
→ Health Check
→ systemd / Quadlet
→ CI/CD
Itulah jalur belajar yang paling praktis: gunakan Podman untuk menyelesaikan masalah yang benar-benar muncul hari ini, lalu naikkan kompleksitas ketika kebutuhan memang muncul.
Referensi Resmi
Post Terkait
Pengalaman Publish Aplikasi ke Google Play: Personal vs Organization, D-U-N-S, Tester dan Biaya
Membedah proses publikasi aplikasi ke Google Play: akun personal vs organization, D-U-N-S, 12 tester selama 14 hari, bia...
Memilih Container Image: Alpine, Debian, Ubuntu atau Distroless?
Panduan memilih container image untuk Docker dan Podman. Bandingkan Alpine, Debian Slim, Ubuntu, Fedora, Rocky, UBI, Dis...
AWS ALB Tidak Selalu Diperlukan: Solusi Ingress Single-AZ yang Scalable
Jika workload sengaja berada di satu Availability Zone, apakah ALB masih diperlukan? Pelajari alternatif ingress single-...