Pesan Error dan Maknanya
Ketika kamu baru selesai menginstal Docker dan bersemangat menjalankan perintah pertama, tiba-tiba terminal membalas dengan pesan yang tak ramah:
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.43/containers/create": dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.
Atau versi yang lebih singkat namun sama frustasinya:
permission denied while trying to connect to the Docker daemon socket
Dalam bahasa Indonesia, pesan ini berarti: "Akses ditolak saat mencoba menyambung ke socket daemon Docker." Secara sederhana, kamu mencoba berkomunikasi dengan Docker daemon (proses latar belakang yang menjalankan container), tapi sistem operasi menolak karena user yang kamu pakai tidak punya hak akses ke file socket yang dimaksud.
Kenapa error ini muncul? Docker daemon berjalan sebagai proses milik root (root), dan ia mengekspos API-nya melalui sebuah file socket Unix di /var/run/docker.sock. File ini secara default dimiliki oleh user root dan group docker. Ketika kamu menjalankan docker ps atau docker run sebagai user biasa (non-root), proses Docker CLI mencoba membaca dan menulis ke socket tersebut, tapi karena user kamu bukan anggota group docker dan bukan root, kernel Linux menolak operasi tersebut. Inilah mekanisme standar permission pada sistem berbasis Unix: setiap akses ke file dicek terhadap ownership dan group membership, dan kalau tidak cocok, akses ditolak dengan error EACCES.
Penyebab yang Paling Sering
Ada beberapa root cause yang paling sering memicu error ini, diurutkan dari yang paling frequently encountered:
User belum menjadi anggota group
docker. Ini adalah penyebab nomor satu. Setelah instalasi Docker, paket instalasi memang membuat groupdocker, tapi ia tidak otomatis menambahkan user kamu ke group tersebut. Banyak pengguna mengira instalasi saja cukup, padahal membership ke group harus dikonfigurasi secara eksplisit.Sesi shell belum di-refresh setelah penambahan group. Kamu mungkin sudah menjalankan
usermod -aG docker $USER, tapi perubahan group membership tidak langsung berlaku pada shell yang sedang berjalan. Kernel Linux membaca group membership saat proses baru dimulai (saat login atau spawn shell baru), bukan saat file/etc/groupdiubah. Shell yang sama tetap memakai snapshot group lama.Socket file
/var/run/docker.sockmemiliki permission atau ownership yang salah. Dalam kondisi normal, file ini harus dimiliki olehroot:dockerdengan mode660. Namun, jika ada skrip atau proses lain yang mengubah ownership-nya (misalnya chown yang terlalu agresif, atau Docker daemon yang di-restart dengan konfigurasi kustom), permission bisa berubah sehingga groupdockertidak lagi memiliki akses.Docker daemon tidak berjalan. Meskipun pesan error-nya bisa sedikit berbeda, kadang pesan "permission denied" muncul ketika socket file tidak ada sama sekali dan Docker CLI mencoba membuatnya. Ini lebih jarang, tapi perlu diperiksa jika solusi permission tidak membuahkan hasil.
Konflik dengan Docker Desktop (Linux). Docker Desktop versi baru menggunakan mekanisme berbeda untuk socket—ia membuat symlink dan mengelola socket melalui VM internal. Jika kamu menginstal Docker Engine (daemon murni) dan Docker Desktop bersamaan, bisa terjadi konflik ownership pada socket.
Cara memastikan penyebab mana yang kamu alami: Jalankan perintah berikut secara berurutan untuk mendiagnosis:
# Cek apakah user kamu ada di group docker
groups $USER
# Cek ownership dan permission socket
ls -l /var/run/docker.sock
# Cek apakah daemon berjalan
sudo systemctl status docker
# Cek versi dan varian Docker yang terinstal
docker version 2>/dev/null || echo "Docker CLI tidak bisa mengakses daemon"
Jika output groups tidak menampilkan docker, penyebabnya adalah poin nomor 1. Jika docker sudah muncul di groups tapi error tetap ada, kemungkinan besar poin nomor 2 (shell belum refresh). Jika ownership socket bukan root:docker, penyebabnya poin nomor 3.
Memperbaikinya Langkah demi Langkah
Berikut langkah-langkah yang bisa kamu ikuti langsung dari terminal untuk mengatasi error ini.
Langkah 1: Tambahkan user ke group docker
Jalankan perintah ini untuk menambahkan user aktif ke group docker:
sudo usermod -aG docker $USER
Perintah ini tidak menghasilkan output jika berhasil—itu normal. Flag -aG berarti "append to group", yang menambahkan user ke group tanpa menghapus keanggotaan group yang sudah ada. Tanpa flag -a, usermod -G akan mengganti seluruh daftar group, yang bisa berbahaya karena kamu kehilangan akses ke group lain seperti sudo atau wheel.
Langkah 2: Refresh sesi shell
Agar perubahan group membership berlaku, kamu harus memulai sesi shell baru. Ada dua cara:
# Cara 1: Menggunakan newgrp (hanya mengganti group konteks, tidak spawn shell baru penuh)
newgrp docker
# Cara 2: Logout dan login kembali (lebih thorough, direkomendasikan)
# Atau cukup tutup terminal dan buka kembali
Perintah newgrp docker adalah cara cepat yang memulai sub-shell dengan group docker sebagai group utama. Namun, cara ini hanya berlaku di shell itu saja—shell lain yang sudah terbuka tidak terpengaruh. Logout/login adalah cara yang lebih bersih karena seluruh sesi pengguna akan membaca ulang konfigurasi group dari /etc/group.
Langkah 3: Verifikasi keanggotaan group
Setelah refresh, pastikan user kamu sudah terdaftar:
groups $USER
Output yang diharapkan:
namauser adm cdrom sudo dip plugdev lpadmin lxd sambashare docker
Pastikan docker muncul dalam daftar tersebut.
Langkah 4: Uji menjalankan Docker tanpa sudo
docker run hello-world
Output yang diharapkan:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
...
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
Jika kamu melihat pesan "Hello from Docker!" tanpa menggunakan sudo, berarti solusi berhasil. Docker CLI berhasil terhubung ke daemon melalui socket, dan container berjalan dengan normal.
Solusi langsung (one-liner)
Jika kamu ingin satu baris perintah yang bisa dijalankan (misalnya untuk skrip provisioning):
sudo usermod -aG docker $USER && newgrp docker
Ini menggabungkan penambahan group dan refresh konteks group dalam satu eksekusi berantai. Perlu diingat bahwa newgrp hanya berlaku di sub-shell, jadi setelah skrip selesai, shell asli mungkin belum ter-refresh. Untuk lingkungan CI/CD atau provisioning, biasanya lebih aman melakukan su - $USER atau restart mesin.
Mencegahnya Kembali
Solusi di atas bersifat permanen untuk user yang sudah ditambahkan ke group. Namun, ada beberapa aspek konfigurasi tambahan yang memastikan error ini tidak kembali muncul di masa depan, baik setelah reboot maupun setelah update.
Konfigurasi systemd untuk menjaga ownership socket
Pada sistem yang menggunakan systemd (Ubuntu 16.04+, Debian Jessie+, CentOS 7+, RHEL 7+), Docker daemon dikelola oleh systemd dan ownership socket dikontrol oleh file socket unit. Pastikan override tidak mengubah group:
# Cek konfigurasi socket unit saat ini
systemctl cat docker.socket
Output default yang diharapkan berisi baris:
[Socket]
ListenStream=/var/run/docker.sock
SocketMode=0660
SocketGroup=docker
Jika SocketGroup di-override ke group lain, kamu bisa mengembalikannya:
sudo mkdir -p /etc/systemd/system/docker.socket.d
sudo tee /etc/systemd/system/docker.socket.d/override.conf <<EOF
[Socket]
SocketGroup=docker
SocketMode=0660
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker.socket
Konfigurasi ini memastikan bahwa setiap kali Docker daemon di-restart atau mesin di-reboot, socket file akan selalu dimiliki oleh group docker dengan permission 0660 (read/write untuk owner dan group, tidak ada akses untuk others).
Best practice keamanan
Penting untuk dipahami: menambahkan user ke group docker setara dengan memberikan akses root tanpa password pada mesin tersebut. Kenapa? Karena user yang bisa mengakses Docker daemon bisa menjalankan container dengan mounting filesystem root host:
# Ini membuktikan bahwa akses docker = akses root
docker run -v /:/host -it alpine chroot /host
Perintah di atas memberikan shell root penuh pada host mesin. Oleh karena itu, best practice-nya adalah:
- Jangan tambahkan user yang tidak terpercaya ke group
docker. - Gunakan Docker Rootless mode jika kamu ingin membatasi risiko. Rootless Docker menjalankan daemon sebagai user biasa tanpa akses root, dan socket-nya berada di
~/.docker/run/docker.sock:
# Instal Docker Rootless mode
dockerd-rootless-setuptool.sh install
# Set environment variable agar CLI menggunakan socket rootless
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
Dengan Rootless mode, bahkan jika container dikompromikan, penyerang tidak mendapatkan akses root pada host.
Perbedaan antar OS
Ubuntu/Debian: Paket docker-ce dari repository resmi Docker secara otomatis membuat group docker saat instalasi, tetapi tidak menambahkan user. Setelah usermod, logout/login sudah cukup.
CentOS/RHEL/Fedora: Perilaku serupa, namun SELinux bisa menambahkan layer penolakan tambahan. Jika setelah menambahkan user ke group error tetap muncul, cek audit SELinux:
sudo ausearch -m avc -ts recent | grep docker
Jika ada denial, kamu mungkin perlu menyesuaikan policy SELinux atau sementara set ke permissive untuk testing:
sudo setenforce 0 # Permissive (hanya log, tidak block)
# Test docker
docker run hello-world
sudo setenforce 1 # Kembali ke Enforcing setelah selesai diagnose
macOS: Error permission denied di macOS biasanya berkaitan dengan Docker Desktop, bukan socket Unix. Docker Desktop di macOS berjalan di dalam VM Linux (melalui Hypervisor.framework), dan CLI berkomunikasi via TCP, bukan socket. Jika mengalami permission denied, biasanya solusinya adalah mereset Docker Desktop dari menu atau menghapus dan menginstal ulang. Tidak ada konsep group docker di macOS untuk penggunaan Docker Desktop.
Windows (WSL2): Docker Desktop dengan WSL2 backend mengintegrasikan Docker ke distribusi WSL. Jika mengalami permission denied di dalam WSL2, solusi usermod sama dengan Linux biasa. Pastikan distribusi WSL yang kamu pakai sudah di-enable di Docker Desktop → Settings → Resources → WSL Integration.
Kalau Cara di Atas Gagal
Jika semua solusi di atas sudah diterapkan dan error tetap muncul, saatnya menggali lebih dalam.
Periksa socket file secara detail
# Stat lengkap socket file
stat /var/run/docker.sock
# Cek apakah ini symlink (Docker Desktop bisa membuat symlink)
file /var/run/docker.sock
Jika file menunjukkan bahwa /var/run/docker.sock adalah symbolic link, ikuti symlink-nya dan cek ownership file tujuan:
readlink -f /var/run/docker.sock
ls -l $(readlink -f /var/run/docker.sock)
Periksa log Docker daemon
D