Pendahuluan
Docker di macOS sering gagal bind ke port karena layanan lain menggunakan port yang sama (misalnya, sisa container, sistem, atau app lain). Pesan error seperti “EADDRINUSE” atau “Cannot start service: address already in use” menunjukkan konflik. Artikel ini menjelaskan langkah-langkah untuk menemukan dan melepaskan port yang digunakan, lalu mengonfigurasi Docker untuk menghindari konflik berulang.
Deteksi port yang sibuk
Gunakan lsof atau netstat untuk menemukan PID yang memegang port:
# Contoh: port 8080lsof -i :8080# Output (contoh):# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME# docker 1234 user 9u IPv4 0x... 0t0 TCP *:8080 (LISTEN)Jika lsof tidak tersedia, gunakan netstat:
netstat -tulpn | grep :8080Hasil tipikal:
TCP 0.0.0.0:8080 0.0.0.0:0 LISTEN 1234Kedua perintah menampilkan PID dan nama program. Di macOS, lsof adalah pilihan utama.
Hentikan proses yang menggunakan port
Setelah mendapatkan PID, hentikan proses tersebut. Contoh untuk container Docker yang tersisa:
# Hentikan container yang sedang berjalan dengan nama "conflicting_container"docker stop conflicting_container# Hapus container yang tidak diperlukandocker rm conflicting_containerJika itu adalah daemon sistem (misalnya, nginx), edit konfigurasi atau gunakan Homebrew untuk uninstall:
# Contoh untuk nginx yang diinstal via Homebrewbrew services stop nginxbrew uninstall nginxSetelah layanan berhenti, verifikasi port bebas:
lsof -i :8080# Tidak ada output → port bebasAtur Docker untuk menggunakan port unik
Docker Desktop untuk macOS menggunakan VM internal. Secara default, Docker mengizinkan penggunaan kembali port setelah container berhenti, tetapi sisa container atau proses binding ke port host akan menyebabkan konflik berulang.
Gunakan label publish yang eksplisit atau ports di docker-compose.yml:
version: "3.9"services: web: image: nginx:alpine ports: - "8080:80" # bind host 8080 → container 80 labels: - "com.docker.compose.staging=false"Jika Anda memerlukan port acak untuk menghindari konflik di masa depan, gunakan placeholder ${{ random }} di CI atau buat rentang port dinamis melalui skrip:
# Pilih port bebas secara acak antara 49152–65535FREE_PORT=$(shuf -i 49152-65535 -n 1)docker run -p ${FREE_PORT}:80 nginxecho "Container menggunakan port ${FREE_PORT}"Trade-off dan batasan
| Pendekatan | Kelebihan | Kekurangan |
|---|---|---|
| Hentikan layanan yang menggunakan port | Segera menyelesaikan konflik | Mungkin mengganggu aplikasi lain |
Gunakan docker-compose dengan pemetaan port eksplisit | Menjamin binding yang dapat diulang | Memerlukan file compose tambahan |
| Port acak | Menghilangkan kebutuhan untuk mengelola konflik | Sulit untuk dokumentasi dan debugging |
Docker di macOS juga mendukung macOS IP 127.0.0.1:. Jika Anda memerlukan binding ke antarmuka host, gunakan 0.0.0.0 di container, tetapi ingat bahwa Docker VM tidak mengekspos antarmuka host secara langsung.
Pemecahan Masalah
Error: EADDRINUSE
docker run -p 8080:80 nginx# Output (diringkas):# Error response from daemon: "Driver networking endpoint "bridge" does not have a free port to allocate"Penyebab: Port 8080 sudah digunakan oleh proses di host (misalnya, sisa container, mongod, atau vscode).
Solusi: Jalankan lsof -i :8080, hentikan proses yang teridentifikasi, lalu jalankan container lagi.
Error: Cannot start service: address already in use
docker compose up -d# Output (diringkas):# Service "db" failed to start: address already in usePenyebab: Container lain (mungkin dari docker compose sebelumnya) masih memegang port 3306.
Solusi: Jalankan docker ps -a, temukan container yang berhenti, lalu docker rm <container>.
Error: socket: address already in use
lsof -i :3000# Output (contoh):# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME# python 4567 user 9u IPv4 0x... 0t0 TCP *:3000 (LISTEN)Penyebab: Skrip Python yang berjalan di host menggunakan port 3000.
Solusi: Hentikan skrip (kill -9 4567) atau ubah skrip untuk menggunakan port bebas.
Port tetap konflik setelah restart
Jika port masih sibuk setelah container dihapus, periksa LaunchDaemons atau system.ini yang mungkin memulai layanan secara otomatis. Gunakan brew services list untuk menemukan daemon yang dikelola Homebrew.
Jika tidak ada, jalankan sudo kill -9 $(lsof -t -i :<PORT>) untuk menghapus paksa, lalu verifikasi:
lsof -i :<PORT># Tidak ada output → port bebasRingkasan
- Gunakan
lsof -i :<PORT>untuk menemukan proses yang menggunakan port. - Hentikan atau hapus proses tersebut (
docker stop/rm,brew services stop). - Verifikasi port bebas sebelum menjalankan container lagi.
- Gunakan pemetaan port eksplisit di
docker-compose.ymlatau pilih port acak untuk menghindari konflik berulang.
Port conflict di Docker macOS dapat diperbaiki dengan cepat menggunakan langkah-langkah di atas, dan konfigurasi yang tepat mencegah masalah ini muncul kembali.