Error yang menyatakan bahwa aplikasi membutuhkan koneksi aman HTTPS merupakan salah satu masalah yang cukup sering dijumpai oleh pengguna Docker, terutama saat pertama kali men-deploy aplikasi web di dalam container. Pesan error ini bisa muncul di berbagai skenario mulai dari akses ke Docker Registry, Portainer, GitLab, hingga aplikasi custom yang berjalan di dalam container. Artikel ini akan membahas secara mendalam bagaimana mengidentifikasi, memperbaiki, dan mencegah error ini agar tidak terulang kembali.


Anatomi pesan error

Pesan error yang muncul biasanya terlihat seperti berikut:

This application requires secure connection (HTTPS). Please check URL.

Dalam beberapa variasi, tergantung aplikasi yang berjalan di dalam container, pesan error bisa juga muncul dalam format yang sedikit berbeda:

Error: this application requires secure connection https please check url

Atau pada konteks Docker Registry:

Error response from daemon: Get "http://registry.example.com/v2/": 
this application requires secure connection (HTTPS). Please check URL.

Secara sederhana, pesan error ini berarti bahwa aplikasi atau layanan yang sedang kamu akses secara eksplisit mengharuskan koneksi melalui protokol HTTPS, namun permintaan yang dikirimkan menggunakan protokol HTTP yang tidak terenkripsi. Aplikasi di dalam container Docker menolak koneksi tersebut dan mengembalikan pesan error sebagai bentuk proteksi keamanan.

Error ini muncul karena beberapa alasan fundamental. Pertama, banyak aplikasi modern yang dikonfigurasi secara default untuk hanya menerima koneksi HTTPS sebagai bagian dari standar keamanan. Kedua, ketika kamu mengakses layanan Docker melalui browser atau CLI menggunakan http:// alih-alih https://, aplikasi akan menolak request tersebut. Ketiga, pada konteks Docker Registry, daemon Docker secara default memerlukan TLS (Transport Layer Security) untuk berkomunikasi dengan remote registry, dan jika registry tersebut tidak dikonfigurasi dengan sertifikat SSL yang valid, error ini akan muncul.

Contoh skenario konkret di mana error ini muncul adalah saat kamu mencoba melakukan push image ke private registry yang tidak menggunakan HTTPS:

docker push registry.example.com:5000/my-image:latest

Jika registry tersebut hanya mendengarkan pada HTTP tanpa TLS, Docker daemon akan menolak koneksi dan menampilkan error di atas. Hal yang sama juga terjadi ketika kamu mengakses Portainer atau aplikasi web lain di dalam container melalui browser dengan URL http:// padahal aplikasi tersebut dikonfigurasi untuk memaksa redirect ke HTTPS tetapi sertifikat belum tersedia atau konfigurasi belum sempurna.


Sumber masalah

Terdapat beberapa root cause yang menjadi sumber utama munculnya error ini, diurutkan dari yang paling sering ditemukan dalam praktik sehari-hari.

Pertama, mengakses layanan dengan protokol yang salah. Ini adalah penyebab paling umum dan paling mudah diperbaiki. Kamu mengetik http://localhost:8080 di browser padahal aplikasi di dalam container hanya mendengarkan pada HTTPS di port tertentu, misalnya https://localhost:8443. Atau sebaliknya, aplikasi dikonfigurasi untuk memaksa HTTPS tetapi kamu tetap mengaksesnya melalui HTTP. Cara memastikan penyebab ini adalah dengan memeriksa port mapping pada container dan mencoba mengakses URL dengan protokol HTTPS secara langsung.

Kedua, Docker Registry tanpa sertifikat TLS. Saat kamu men-setup private Docker Registry dan mengaksesnya tanpa mengkonfigurasi sertifikat SSL/TLS, Docker daemon akan menolak koneksi. Secara default, Docker mengharuskan semua komunikasi dengan registry dilakukan melalui HTTPS. Cara memastikan adalah dengan melihat konfigurasi registry dan memeriksa apakah ada sertifikat yang terpasang, atau dengan memeriksa file /etc/docker/daemon.json untuk melihat apakah registry sudah dimasukkan ke dalam daftar insecure registries.

Ketiga, environment variable yang memaksa HTTPS tetapi sertifikat tidak tersedia. Banyak aplikasi seperti GitLab, Portainer, dan Nextcloud menggunakan environment variable seperti SSL=true, HTTPS_ONLY=true, atau FORCE_HTTPS=true yang memaksa aplikasi hanya menerima koneksi aman. Jika variable ini diaktifkan tanpa menyediakan sertifikat yang sesuai, error akan muncul. Kamu bisa memastikan dengan memeriksa konfigurasi environment variable pada container menggunakan perintah docker inspect.

Keempat, konfigurasi reverse proxy yang tidak tepat. Ketika kamu menggunakan Nginx atau Apache sebagai reverse proxy di depan container Docker, konfigurasi SSL termination yang salah bisa menyebabkan error ini. Proxy menerima koneksi HTTPS dari klien tetapi meneruskannya ke container melalui HTTP, sementara aplikasi di dalam container tetap memeriksa header dan menolak koneksi karena menganggapnya tidak aman. Cara memastikan adalah dengan memeriksa konfigurasi reverse proxy dan melihat header yang diteruskan ke container.

Kelima, sertifikat self-signed yang tidak dipercaya oleh sistem. Bahkan ketika HTTPS sudah dikonfigurasi, jika sertifikat yang digunakan adalah self-signed dan tidak ditambahkan ke trust store sistem, Docker daemon atau browser bisa menolak koneksi. Cara memastikan penyebab ini adalah dengan melihat pesan error tambahan yang menyebutkan "certificate signed by unknown authority" atau "x509 certificate signed by unknown authority".

Untuk memastikan penyebab mana yang sedang kamu alami, ikuti langkah diagnostik berikut secara berurutan:

  • Periksa URL yang kamu gunakan: apakah sudah menggunakan https://?
  • Jalankan docker inspect <container_name> dan periksa bagian Env dan PortBindings
  • Periksa log container dengan docker logs <container_name> untuk pesan error spesifik
  • Cek file /etc/docker/daemon.json untuk konfigurasi insecure registry
  • Periksa konfigurasi reverse proxy jika digunakan

Memperbaiki error ini

Bagian ini akan membahas solusi langkah demi langkah untuk setiap root cause yang telah diidentifikasi, lengkap dengan perintah yang dapat langsung dijalankan dan Hasil yang muncul.

Solusi 1: Perbaiki protokol akses

Jika penyebabnya adalah salah protokol, solusinya langsung: gunakan HTTPS saat mengakses layanan.

# Salah - menggunakan HTTP
curl http://localhost:8080/api/health

# Benar - menggunakan HTTPS
curl -k https://localhost:8443/api/health

Flag -k pada curl digunakan untuk melewati verifikasi sertifikat, berguna untuk lingkungan development. Hasil yang muncul adalah respons berhasil dari aplikasi, misalnya:

{"status": "ok"}

Untuk verifikasi bahwa solusi berhasil, akses URL HTTPS melalui browser dan pastikan halaman aplikasi termuat tanpa pesan error. Jika menggunakan CLI, jalankan curl dengan flag verbose untuk melihat detail koneksi TLS:

curl -v -k https://localhost:8443/api/health

Keluaran yang tampak menunjukkan handshake TLS yang berhasil:

* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384

Solusi 2: Konfigurasi insecure registry (development only)

Untuk Docker Registry yang tidak memiliki sertifikat TLS, tambahkan registry ke daftar insecure registries. Ini adalah solusi sementara untuk lingkungan development, bukan untuk production.

Edit file /etc/docker/daemon.json:

sudo nano /etc/docker/daemon.json

Tambahkan konfigurasi berikut:

{
  "insecure-registries": ["registry.example.com:5000"]
}

Kemudian restart Docker daemon:

sudo systemctl restart docker

Contoh output tidak ada pesan error, dan Docker akan memulai ulang dengan konfigurasi baru. Verifikasi dengan:

docker info | grep -A 5 "Insecure Registries"

Keluaran yang tampak:

Insecure Registries:
  registry.example.com:5000
  127.0.0.0/8

Setelah itu, kamu bisa melakukan push image ke registry tersebut:

docker push registry.example.com:5000/my-image:latest

Namun perlu diingat, solusi ini hanya mengatasi gejala, bukan root cause. Fix permanennya adalah mengkonfigurasi TLS pada registry.

Solusi 3: Fix environment variable HTTPS

Jika penyebabnya adalah environment variable yang memaksa HTTPS tanpa sertifikat, ada dua pendekatan. Pertama, nonaktifkan pemaksaan HTTPS untuk development:

docker run -d \
  --name my-app \
  -e SSL=false \
  -e HTTPS_ONLY=false \
  -p 8080:8080 \
  my-app-image:latest

Kedua, sebagai fix permanen, sediakan sertifikat yang valid:

docker run -d \
  --name my-app \
  -e SSL=true \
  -e SSL_CERT_FILE=/certs/cert.pem \
  -e SSL_KEY_FILE=/certs/key.pem \
  -v /path/to/certs:/certs:ro \
  -p 8443:8443 \
  my-app-image:latest

Verifikasi dengan memeriksa log container:

docker logs my-app

Keluaran yang tampak menunjukkan aplikasi berhasil dimulai dengan HTTPS:

Server started on https://0.0.0.0:8443
SSL certificate loaded successfully

Solusi 4: Perbaiki konfigurasi reverse proxy

Untuk Nginx sebagai reverse proxy, pastikan header HTTPS diteruskan dengan benar ke container backend:

server {
    listen 443 ssl;
    server_name app.example.com;

    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;

    location / {
        proxy_pass http://app-container:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Header X-Forwarded-Proto $scheme sangat penting karena memberitahu aplikasi di dalam container bahwa koneksi asli dari klien menggunakan HTTPS, meskipun proxy meneruskan ke container melalui HTTP. Tanpa header ini, aplikasi bisa menolak koneksi karena menganggap request datang melalui HTTP.

Reload konfigurasi Nginx setelah melakukan perubahan:

sudo nginx -t && sudo nginx -s reload

Keluaran yang tampak:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Solusi 5: Tambahkan sertifikat self-signed ke trust store

Untuk sertifikat self-signed yang tidak dipercaya, tambahkan ke trust store sistem. Pada Ubuntu/Debian:

# Salin sertifikat ke direktori yang tepat
sudo cp my-registry-cert.crt /usr/local/share/ca-certificates/

# Update trust store
sudo update-ca-certificates

Yang akan kamu lihat:

Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

Kemudian restart Docker daemon agar perubahan efektif:

sudo systemctl restart docker

Verifikasi dengan melakukan login ke registry:

docker login registry.example.com:5000

Keluaran yang tampak jika berhasil:

Login Succeeded

Supaya tidak terulang

Mencegah error ini muncul kembali membutuhkan pendekatan sistematis dalam konfigurasi dan deployment. Berikut adalah konfigurasi, Praktik terbaik, dan perbedaan yang perlu diperhatikan di berbagai sistem operasi.

Pencegahan di level konfigurasi

Pertama dan terpenting, selalu gunakan HTTPS di lingkungan production. Siapkan sertifikat TLS sejak awal deployment menggunakan Let's Encrypt untuk sertifikat gratis yang terotomatisasi, atau sertifikat dari CA komersial untuk kebutuhan enterprise. Dengan docker-compose, konfigurasi bisa dibuat persisten dan konsisten:

# docker-compose.yml
version: '3.8'

services:
  app:
    image: my-app:latest
    environment:
      - SSL=true
      - SSL_CERT_FILE=/certs/fullchain.pem
      - SSL_KEY_FILE=/certs/privkey.pem
    volumes:
      - ./certs:/certs:ro
    ports:
      - "8443:8443"
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./certs:/etc/nginx/ssl:ro
    depends_on:
      - app
    restart: unless-stopped

Dengan konfigurasi di atas, setiap kali container di-restart atau di-deploy ulang, sertifikat akan selalu termuat dan aplikasi akan selalu dilayani melalui HTTPS.

Cara yang disarankan

Gunakan reverse proxy sebagai single entry point untuk semua layanan Docker. Reverse proxy seperti Nginx, Traefik, atau Caddy menangani SSL termination, sehingga aplikasi di dalam container tidak perlu mengelola sertifikat sendiri. Caddy bahkan memiliki fitur automatic HTTPS yang secara otomatis mendapatkan dan memperbarui sertifikat Let's Encrypt:

# docker-compose.yml dengan Caddy
version: '3.8'

services:
  caddy:
    image: caddy:2
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    restart: unless-stopped

  app:
    image: my-app:latest
    # tidak perlu expose port ke host
    restart: unless-stopped

volumes:
  caddy_data:
  caddy_config:

File Caddyfile:

app.example.com {
    reverse_proxy app:8080
}

Caddy akan otomatis mendapatkan sertifikat untuk app.example.com dan memperbaruinya sebelum kedaluwarsa. Ini mengeliminasi seluruh kelas masalah terkait HTTPS.

Selain itu, selalu terapkan HTTP-to-HTTPS redirect di level reverse proxy sehingga tidak ada request HTTP yang lolos ke aplikasi. Hindari penggunaan insecure registries di production. Jika harus menggunakan private registry, pasang sertifikat TLS yang valid dan daftarkan CA-nya ke semua mesin yang mengaksesnya.

Perbedaan OS

Konfigurasi trust store dan cara restart Docker berbeda di setiap sistem operasi, dan ini sering menjadi sumber kebingungan.

Linux (Ubuntu/Debian):

# Tambahkan sertifikat
sudo cp cert.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

# Restart Docker
sudo systemctl restart docker

Linux (RHEL/CentOS/Fedora):

# Tambahkan sertifikat
sudo cp cert.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# Restart Docker
sudo systemctl restart docker

macOS (Docker Desktop):

Pada macOS, Docker berjalan di dalam VM terpisah sehingga menambahkan sertifikat ke macOS Keychain tidak otomatis dipercaya oleh Docker. Kamu perlu menambahkan sertifikat melalui UI Docker Desktop:

  1. Buka Docker Desktop → Settings → Resources → Proxies atau gunakan ${HOME}/.docker/certs.d/
  2. Salin sertifikat ke direktori registry tertentu:
mkdir -p ~/.docker/certs.d/registry.example.com:5000
cp cert.crt ~/.docker/certs.d/registry.example.com:5000/ca.crt
  1. Restart Docker Desktop

Windows (Docker Desktop):

Serupa dengan macOS, sertifikat perlu diletakkan di direktori khusus:

mkdir "$env:USERPROFILE\.docker\certs.d\registry.example.com:5000"
copy cert.crt "$env:USERPROFILE\.docker\certs.d\registry.example.com:5000\ca.crt"

Kemudian restart Docker Desktop. Jika menggunakan Windows Certificate Store, sertifikat juga perlu diimpor ke Local Machine → Trusted Root Certification Authorities melalui certlm.msc.


Langkah lanjutan

Kalau semuanya sudah dicoba tapi masih error tetapi error masih muncul, ada beberapa langkah lanjutan yang bisa dilakukan untuk mengetahui akar masalah yang sebenarnya.

Membaca log secara mendalam

Log container sering kali memberikan petunjuk yang lebih spesifik daripada pesan error yang ditampilkan ke pengguna. Mulailah dengan memeriksa log container yang bermasalah:

docker logs --tail 100 --timestamps my-container

Flag --timestamps membantu menghubungkan pesan log dengan kejadian waktu tertentu. Jika container sudah berjalan lama, gunakan --since untuk memfilter log terbaru:

docker logs --since 30m my-container

Selain log container, periksa juga log Docker daemon itu sendiri untuk mendapatkan informasi level lebih rendah:

# Linux
sudo journalctl -u docker.service --since "30 minutes ago"

# macOS dan Windows
# Buka Docker Desktop → Troubleshoot → Get diagnostic info

Untuk masalah terkait jaringan dan TLS, aktifkan debug mode pada Docker daemon dengan menambahkan konfigurasi berikut ke /etc/docker/daemon.json:

{
  "debug": true,
  "log-level": "debug"
}

Setelah restart Docker, log akan jauh lebih verbose dan menampilkan detail handshake TLS, verifikasi sertifikat, dan koneksi jaringan. Ini sangat membantu untuk mengidentifikasi di mana tepatnya koneksi gagal. Namun ingat untuk menonaktifkan debug mode setelah masalah teratasi karena log akan bertumbuh sangat cepat.

Cara debugging jaringan di dalam container

Kadang masalah bukan pada konfigurasi Docker itu sendiri, melainkan pada konektivitas jaringan antar container atau antara container dan host. Gunakan tools jaringan untuk mendiagnosis:

# Masuk ke dalam container
docker exec -it my-container sh

# Periksa konektivitas ke registry atau layanan lain
wget --no-check-certificate -O- https://registry.example.com:5000/v2/

# Atau jika curl tersedia
curl -v -k https://registry.example.com:5000/v2/

Jika container tidak memiliki wget atau curl, kamu bisa menjalankan container sementara untuk testing:

docker run --rm -it --network my-network curlimages/curl -v -k https://registry.example.com:5000/v2/

Tool diagnostik tambahan

OpenSSL sangat berguna untuk memeriksa sertifikat dan koneksi TLS secara independen dari Docker:

# Periksa sertifikat yang disajikan oleh server
openssl s_client -connect registry.example.com:5000 -showcerts

# Verifikasi sertifikat tertentu
openssl verify -CAfile /path/to/ca.crt /path/to/cert.pem

Output dari openssl s_client akan menunjukkan apakah sertifikat valid, chain of trust lengkap, dan protokol TLS yang dinegosiasikan. Jika ada masalah dengan sertifikat, output akan menampilkan kode error spesifik seperti verify error:num=19:self signed certificate in certificate chain atau verify error:num=20:unable to get local issuer certificate.

Bacaan resmi terkait

Untuk pemahaman yang lebih mendalam, berikut adalah sumber resmi yang direkomendasikan:

  1. Docker Documentation - Use TLS (HTTPS): Dokumentasi resmi Docker yang membahas konfigurasi HTTPS untuk Docker daemon, termasuk cara membuat sertifikat dan mengkonfigurasi daemon untuk only menerima koneksi terenkripsi. URL: https://docs.docker.com/engine/security/protect-access/

  2. Docker Registry - Certificate Authority: Panduan resmi untuk mengkonfigurasi sertifikat TLS pada Docker Registry, termasuk penggunaan sertifikat dari CA komersial dan self-signed. URL: https://distribution.github.io/distribution/about/configuration/

  3. RFC 8446 - TLS 1.3: Untuk memahami secara fundamental bagaimana TLS bekerja, RFC ini adalah sumber definitif. Memahami TLS handshake dan proses verifikasi sertifikat akan sangat membantu saat meng-debug masalah koneksi HTTPS yang kompleks.

  4. Traefik Documentation - HTTPS & TLS: Jika menggunakan Traefik sebagai reverse proxy, dokumentasinya sangat lengkap dalam membahas automatic TLS certificate management. URL: https://doc.traefik.io/traefik/https/tls/

  5. Caddy Documentation - Automatic HTTPS: Caddy menawarkan pendekatan zero-configuration untuk HTTPS, dan dokumentasinya menjelaskan bagaimana fitur ini bekerja serta bagaimana meng-customisasinya. URL: https://caddyserver.com/docs/automatic-https

Dengan mengikuti langkah-langkah diagnostik dan solusi yang telah dibahas, error "this application requires secure connection https please check url" seharusnya dapat diatasi secara tuntas. Kunci utamanya adalah memahami bahwa error ini bukan sekadar masalah protokol, melainkan indikator bahwa aspek keamanan dalam deployment Docker belum dikonfigurasi dengan benar. Dengan mengadopsi Praktik terbaik menggunakan HTTPS sejak awal, menerapkan reverse proxy dengan SSL termination, dan memastikan sertifikat terpercaya di seluruh infrastruktur, error ini tidak akan pernah muncul kembali di lingkungan production maupun development kamu.