A personal journal.

Pengalaman Setting Reverse Proxy Traefik oleh Pemula

Published on: 23/11/2023 • Updated on: 14/05/2025 • 5 min read

Saya sering melihat orang-orang berbagi cara membuat reverse proxy untuk menjalankan layanan online, tetapi saya menganggapnya terlalu rumit. Bukankah cukup menggunakan tunnel dari Cloudflare? Namun, setelah saya mencoba sendiri, saya menyadari bahwa itu tidak sesulit yang saya kira (setelah saya mengerti konsepnya).

Saya tidak punya alasan khusus untuk membuat reverse proxy, karena saya hanya meminjam internet dari orang lain dan tidak memiliki IP publik sendiri. Bagi mereka yang memiliki IP publik, reverse proxy bisa membantu mengakses layanan online dengan DDNS.

Software reverse proxy pun ada bermacam-macam, yang paling terkenal adalah nginx dan traefik. Kalau nginx saya kira gara-gara nginx juga sebagai webserver jadi sekalian, meskipun kalau saya tengok, hampir semua webserver bisa berfungsi sebagai reverse proxy.

Alasan saya mencoba reverse proxy

Saya ingin belajar tentang reverse proxy, jadi saya memilih Traefik sebagai alatnya. Saya tidak tertarik dengan Nginx atau yang lainnya. Saya tahu reverse proxy bisa digunakan untuk mengekspos layanan lokal, load balancing, dan keamanan, tetapi saya tidak membutuhkannya. Saya sudah menggunakan tunnel Cloudflare yang memberikan SSL/TLS, meskipun hanya dalam mode fleksibel. Saya rasa itu sudah cukup.

Cloudflare tunnel + Traefik?

Hampir semua layanan yang berjalan di RPi0W saya adalah docker, dan untuk mengeksposnya, saya cukup memetakan port saja, dan pada pengaturan tunnel tinggal memanggil localhost:port.

Muncul masalah lain, yaitu cloudflared lama saya yang menggunakan network_mode=host, yang memudahkan saya untuk mengatur tunnel. Sebenarnya, saya hanya perlu memasang port saja. Namun, ketika menggunakan Traefik, saya sekarang berpikir tentang bagaimana caranya agar saya tidak menggunakan host networking dan menggunakan network internal dari Docker. Tentu saja, saya akan kehilangan akses langsung dari host ke Docker ataupun sebaliknya.

Setup Traefik dan Providernya

Mari kita lanjutkan untuk setup (pengaturan) nya, berikut contekan dari docker-compose yang saya gunakan:

version: "3"
services:
  cloudflared:
    container_name: cloudflared-tunnel
    image: cloudflare/cloudflared
    restart: unless-stopped
    command: tunnel run
    environment:
      - TUNNEL_TOKEN=<YOUR TUNNEL TOKEN>
    networks:
      - cftunnel

  traefik:
    image: traefik/latest
    container_name: traefik
    restart: always
    networks:
      - cftunnel
      - traefiktun
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro # provider docker harus expose ini
      - ./traefik.yaml:/traefik.yaml:ro # static config
      - ./dynamic_conf.yaml:/dynamic_conf.yaml # dynamic config
      - ./cert:/cert:ro # untuk origin certificate

networks:
  cftunnel:
  traefiktun:
    external: true

Contoh isi docker-compose.yml

Karena di sini kita membutuhkan external network, maka kita perlu terlebih dahulu membuat network-nya pada Docker dengan perintah docker network create traefiktun. Untuk konfigurasi statisnya, saya isi tentang logging, provider (Docker dan file), dan entrypoints.

log:
  level: DEBUG # untuk keperluan testing & monitoring, bisa diganti jika tidak diperlukan.

entryPoints:
  websecure:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    filename: dynamic_conf.yaml

Isi dari traefik.yaml

Secara default, alasan menggunakan file provider adalah dynamic load, di mana Traefik secara berkala akan melakukan cek terhadap file tersebut, apakah diubah atau tidak, dan akan memperbarui konfigurasi Traefik tanpa harus melakukan restart.

Isi dari dynamic_conf.yaml saya masukkan pengaturan Certificate Origin Server dari Cloudflare. Untuk pembuatan Origin Server cukup mudah, jadi saya tidak menuliskannya. Silakan cek dokumentasi Cloudflared.

tls:
  stores:
    default:
      defaultCertificate:
        certFile: /cert/mydomain.tld.pem
        keyFile: /cert/mydomain.tld.key

  certificates:
    - certFile: /cert/mydomain.tld.pem
      keyFile: /cert/mydomain.tld.key

isi daru dynamic_conf.yaml

Kemudian, untuk mengatur per-service pada Docker, kita hanya perlu menambahkan label dan network saja. Kita tidak perlu memetakan port pada Docker karena Traefik secara otomatis akan menggunakan port yang di-expose (sesuai Dockerfile-nya) untuk komunikasi secara privat. Misalnya, saya ingin menjalankan ntfy:

version: "3"
services:
  ntfy:
    image: binwiederhier/ntfy
    container_name: ntfy
    command:
      - serve
    volumes:
      - /var/cache/ntfy:/var/cache/ntfy
      - ./ntfy-data:/etc/ntfy
    restart: always

Setup minimal ntfy

Mari kita tambahkan label dan network seperti berikut:

    labels:
      - traefik.enable=true
      - traefik.http.routers.ntfy.rule=Host(`sub.mydomain.tld`) # sesuaikan dengan nama domain
      - traefik.http.routers.ntfy.tls=true # wajib karena entrypoint hanya menggunakan websecure / https
    networks:
      - traefiktun

Baris tambahan agar terhubung dengan traefik

Perlu diketahui bahwa ntfy dalam traefik.http.routers.**ntfy**.tls merupakan label dinamis, jadi bisa saja saya menamai traefik.http.routers.**notif**.tls, yang penting konsisten pada setiap layanan. Setelah kita jalankan, maka traefik akan secara otomatis menambahkan route untuk ntfy.

Setup Cloudflared

Setelah semua berjalan, kita bisa lanjut ke pengaturan tunnel di Cloudflare. Silakan tambahkan Public Hostname pada Cloudflare Zero Trust, sebagai contoh seperti ini:

Pengaturan tunnel di Cloudflare Zero Trust

Untuk layanan kita, sebaiknya langsung memanggil https://traefik karena traefik dan cloudflared berada dalam satu network di docker-compose.yml.

Kemudian, di pengaturan TLS, kita perlu mengatur Origin Server Name dengan hostname yang sudah kita atur. Di sini, saya berikan contoh.testeraphy.cf. Pada bagian HTTP2 connection, kita bisa mengaktifkannya karena kita sudah menggunakan https dan mengaktifkan TLS menjadi Full(Strict). Kalau tidak diaktifkan juga tidak apa-apa.

Selesai! Kamu sudah bisa menggunakan Traefik untuk keperluan reverse proxy aplikasi Docker!

Temuan - temuan

Mudah? Tidak juga. Di atas adalah contoh yang mudah, karena gambar ntfy secara default sudah mengekspos port 80, dan saya juga tidak menjelaskan bagaimana jika saya ingin mengekspos service yang berjalan lokal di luar Docker.

Pada bagian ini saya akan mencoba temuan saya ketika mengatur Traefik+cloudflared yang mungkin berguna.

App tidak mengekspos port, perlukah mapping port?

Tidak, daripada harus melakukan mapping port (dan tidak akan diakses juga di local server) kamu bisa mengekspos port secara manual dengan menambahkan berita seperti berikut pada docker compose.

expose:
  - 8080

mengekspos port jika tidak diberikan ketika build

Kenapa tidak mapping port? karena traefik secara pintar akan menggunakan port yang sudah diekspos untuk keperluan reverse proxy. Langkah lain adalah dengan menambahkan label traefik.http.services.ntfy.loadbalancer.server.port=80 (Misalnya, jika aplikasi tersebut berjalan pada port 80.).

Kecuali jika layanan Docker kamu ingin bisa diakses dari localhost, ya harus di-expose.

Akses localhost dari dalam docker

Seperti yang sudah ditulis sebelumnya, kita dengan mudah bisa ‘mengakali’ ini dengan menggunakan host networking. Namun karena di sini kita ingin mengisolasi jaringan di dalam docker, maka untuk service traefik kita tambahkan:

  extra_hosts:
      - "host.docker.internal:host-gateway"

baris tambahan untuk akses localhost dari dalam docker

Alhasil, kita bisa membuat layanan reverse proxy di luar Docker dengan menggunakan alamat host.docker.internal.

Reverse proxy untuk service diluar docker

Bagian ini masuk ke dalam bagian konfigurasi dinamis Traefik, yang mana kita akan menggunakan file dynamic_conf.yaml. Sebagai contoh, saya akan membuat reverse proxy dari Prometheus yang tidak berjalan di dalam Docker, maka di dalam dynamic_conf.yaml tambahkan baris berikut:

http:
  routers:
    prometheus:
      rule: 'Host(`prometheus.mydomain.tld`)'
      service: prometheus
      tls: true
  services:
    prometheus:
      loadBalancer:
        servers:
          - url: "http://host.docker.internal:9090"

membuat reverse porxy untuk prometheus

Pada setiap service yang ingin kita buatkan reverse proxynya kita memerlukan 2 baris yaitu routers dan services. Untuk url pada services karena servicenya berada di localhost dan diluar docker, maka kita akses dari http://host.docker.internal.

Jika diperhatikan, sebenarnya formatnya sama seperti ketika kita memberikan label pada Docker, yang berarti kita juga bisa ‘nebeng’ label di Docker.

Bingung formatnya berasal dari mana? Perhatikan format host pada ntfy yang tertulis traefik.http.routers.ntfy.rule=Host(`sub.mydomain.tld`). Jika kita ubah menjadi format yaml, menjadi:

http:
  routers:
    ntfy:
      rule: 'Host(`sub.mydomain.tld`)'

konversi dari baris ke file yaml

Untuk yang lain, saya rasa sudah cukup jelas, dan tentu saja dokumentasi dari Traefik lebih lengkap.

Now the question? did you really need reverse proxy while using cloudflared tunnel?

Hehe, sok inggris. Tapi jawabnya adalah tidak. Cukup gunakan saja tunnel, karena pada dasarnya sama saja, untuk akses.

Hal lain yang saya dapatkan ketika mencoba ini adalah… mending pakai nginx, cuma butuh 7 MiB daripada traefik yang makan 50 MiB.