Skip to content
Konsultasi

Callback OAuth Refused di Container Host-Mode

Adityo Guni Waluyo

Dugaan pertama bilang tambah ports di compose. Ternyata host-mode justru sudah membagikan loopback host, dan ports malah bikin compose gagal validasi.

Buka browser di host, halaman consent Spotify udah muncul, saya klik setuju. Yang terjadi malah connection refused pas callback ke http://[::1]:43827/spotify/callback. Hermes emang baru saya migrasi ke container Docker pakai network_mode: host di direktori Projects di host. Saya kira masalahnya sederhana: container nggak expose port.

Jadi saya buka docker-compose.yml, tambahin blok ports:

services:
  hermes:
    network_mode: host
    ports:
      - "43827:43827"

Terus jalanin docker compose up. Langsung meledak dengan error: conflicting options: port publishing and the container type network mode.

Ternyata dugaan saya salah banget. Host-mode nggak bisa publish port, bukan karena lupa config, tapi emang nggak boleh. Kalau kamu pernah bingung kenapa port tiba-tiba bentrok antar container, akarnya sering sama: pola dua container host-mode yang berebut satu port di namespace host yang dipakai bareng.

Loopback itu per-host, dan host-mode justru membagikannya

Loopback itu per-host-namespace. Pas container jalan di host-mode, dia bagikan network namespace host secara utuh. Server callback yang jalan di dalam container otomatis bind ke stack host, termasuk interface loopback. Browser di host buka halaman yang sama, tinggal tembak [::1] porta ephemeral, koneksi tembus tanpa perlu ports: sama sekali. Justru ports: yang bikin compose gagal validasi.

Saya pribadi berpendapat: ports: di host-mode bukan cuma diabaikan, tapi error, dan itu fitur, bukan bug. Maksa kita ngerti gimana network namespace kerja, bukan cuma neken tombol expose. Docker sendiri dokumentasikan kalau container host-mode nggak dapet IP sendiri dan mapping port dibuang — lihat dokumen host network driver.

Setelah paham itu, semua CLI OAuth loopback langsung jalan. Polanya jelas kalau kita lihat standarnya. RFC 8252 section 7.3 bilang authorization server wajib terima port apa pun buat redirect URI loopback, karena port ephemeral dipilih pas runtime RFC 8252. Google juga catat alur loopback IP kayak [::1] sebagai pola resmi desktop app, lengkap sama peringatan MITM antar-app di loopback yang sama panduan migrasi loopback Google. Implementer nyata kayak Duende IdentityServer pakai AddAppAuthRedirectUriValidator yang terima port apa pun kalo client register http://[::1] dan PKCE required validator port-agnostic Duende.

Kalo kita bikin agent atau CLI yang pakai pola serupa, jangan gebukin compose pakai ports:. Cukup host-mode, bind ke loopback, beres. Satu hal yang tetap wajib: pakai PKCE, karena callback di loopback bisa dicegat app lain di mesin yang sama. Itu bukan masalah Docker — itu sifat loopback itu sendiri.

Artikel terkait