
Mendalami teknologi Docker .NET bukan sekadar membungkus aplikasi ke dalam container, melainkan tentang menyelaraskan ekosistem di dalamnya. Di Filosofi Ruang Proses, kita percaya bahwa setiap error log adalah guru yang jujur. Hari ini, saya akan membagikan catatan perjalanan teknis saat memindahkan aplikasi Backend .NET 6 ke dalam Docker.
Banyak developer mengira proses ini hanya sebatas melakukan docker build, namun kenyataannya, tantangan sebenarnya sering muncul saat aplikasi mulai berjalan di lingkungan terisolasi. Berikut adalah langkah-langkah troubleshooting yang saya lalui.
Step 1: Inisiasi Dockerfile dan Masalah File Statis
Awalnya, saya menggunakan Dockerfile standar untuk proyek Docker .NET ini. Rencana saya sederhana: Build, Publish, dan Run. Namun, masalah pertama langsung muncul saat kontainer dijalankan.
Masalah: Aplikasi crash saat startup. Log menunjukkan: System.Exception: Cannot find file AppConfig.json.
Analisis: Saat perintah dotnet publish berjalan, sistem secara default hanya fokus pada file binary (.dll). Folder pendukung seperti /Json atau file konfigurasi statis seringkali tertinggal di folder build jika tidak didaftarkan secara eksplisit.
Solusi: Pastikan pengaturan di file .csproj sudah benar agar file tersebut ikut terbawa saat proses publish:
<ItemGroup>
<None Update="AppConfig.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>
Step 2: Menjinakkan Connection String di Lingkungan Docker
Setelah masalah file konfigurasi selesai, muncul tantangan baru terkait jaringan. Aplikasi saya tidak bisa menemukan database PostgreSQL yang berjalan di host Windows saya.
Error: Npgsql.NpgsqlException: Failed to connect to [::1]:5432
Analisis: Di dalam Docker .NET 6, kata kunci localhost bukan lagi merujuk pada laptop kita, melainkan merujuk pada internal kontainer itu sendiri. Agar kontainer bisa berkomunikasi dengan layanan di luar (host), kita perlu menggunakan DNS khusus yang disediakan oleh Docker Desktop.
Solusi: Gunakan alamat host.docker.internal sebagai pengganti localhost pada string koneksi Anda. Anda bisa mempelajarinya lebih lanjut di dokumentasi resmi Docker Networking. Namun, tantangan tidak berhenti di sini. Karena saya menggunakan password dengan karakter spesial seperti @, #, atau !, terminal PowerShell sering salah menerjemahkan string tersebut.
Step 3: Masalah Karakter Spesial
Saat mencoba memasukkan Connection String lewat Environment Variable di perintah docker run, saya menemui error yang cukup membingungkan.
Error: System.ArgumentException: Format of the initialization string does not conform to specification.
Analisis: Karakter # atau @ dianggap sebagai karakter instruksi oleh parser Npgsql atau sering kali dipotong oleh terminal PowerShell sebelum sampai ke dalam kontainer. Ini adalah masalah umum saat kita bekerja dengan Docker .NET 6 di lingkungan Windows.
Solusi: Solusi terbaik adalah membungkus nilai password dengan kutip ganda yang di-escape (\") di dalam string koneksi. Ini memastikan sistem membaca password sebagai satu kesatuan teks utuh.
PowerShell Example:
docker run -e ConnectionStrings__DefaultConnection="Host=host.docker.internal;Database=ProsesDb;Username=usernameDb;Password=\"P@ssw0rd#\"" my-dotnet-app
Pentingnya Observabilitas dalam Kontainerisasi
Mengelola aplikasi dalam kontainer menuntut kita untuk memiliki pemahaman mendalam tentang bagaimana environment variables bekerja. Sering kali, developer melewatkan detail kecil seperti case-sensitivity atau batasan karakter pada sistem operasi tertentu. Dalam pengembangan Docker .NET, sangat disarankan untuk selalu memeriksa variabel yang terpasang di dalam kontainer menggunakan perintah docker inspect [container_id] guna memastikan konfigurasi sudah masuk sesuai harapan.
Selain itu, pertimbangkan untuk menggunakan Secrets Management jika aplikasi Anda sudah masuk ke tahap produksi (production), daripada hanya mengandalkan environment variables mentah di terminal. Hal ini demi menjaga keamanan kredensial database Anda dari kebocoran log.
Lesson Learned: Memahami Setiap Proses
Dari proses troubleshooting ini, ada tiga poin penting yang bisa kita ambil sebagai pelajaran berharga:
- Explicit is better than implicit: Jangan pernah berasumsi file statis akan ikut ter-copy otomatis ke Docker image tanpa instruksi yang jelas di
.csproj. - Network Awareness: Pahami perbedaan localhost di dalam dan di luar kontainer agar komunikasi antar layanan berjalan lancar.
- Security & Syntax: Selalu waspada dengan karakter spesial pada environment variables, terutama jika Anda menggunakan sistem operasi yang berbeda antara tahap development dan deployment.
Mendeploy aplikasi dengan Docker .NET bukan sekadar tentang efisiensi infrastruktur, tapi tentang kedisiplinan kita dalam menyelaraskan seluruh ekosistem aplikasi. Semoga catatan teknis ini membantu Anda yang sedang berproses menghadapi error serupa. Sampai jumpa di catatan Logika berikutnya di Ruang Proses!