Tech With Ngurah Bagus
Tech With Ngurah Bagus
Published on 2025-09-07 / 202 Visits
2
2

Migrasi dari Nginx-Proxy-Manager ke Traefik

Nginx-Proxy-Manager (NPM) adalah tool yang sangat bagus, terutama bagi mereka yang baru memulai di dunia self-hosting. Tampilannya yang berbasis web (GUI) membuatnya sangat mudah untuk mengatur reverse proxy dan mendapatkan sertifikat SSL. Namun, seiring berjalannya waktu dan semakin banyaknya layanan yang kita hosting, ada kalanya pendekatan GUI justru terasa sedikit merepotkan.

Kadang saya merasa kesusahan, jika hanya menambah satu servis, saya harus membuka dashboard, login, klik sana-sini hanya untuk menambahkan satu host. Proses ini terasa kurang efisien, terutama jika kita ingin semua konfigurasi terdokumentasi sebagai kode (Infrastructure as Code).

Di sinilah Traefik menjadi solusi. Traefik adalah reverse proxy modern yang dirancang untuk dunia cloud-native, terintegrasi sempurna dengan Docker. Konsep utamanya adalah kita mendefinisikan semua konfigurasi routing dan SSL langsung pada label di file compose.yaml milik servis itu sendiri. Tidak perlu lagi buka dashboard terpisah.

Jadi yang saya perlukan agar servis Docker saya dapat diakses yaitu:

- Reverse Proxy yang disini saya gunakan yaitu traefik

- SSL Otomatis dengan Let's Encrypt, khususnya disini saya menggunakan DNS-01 Challenge dari Cloudflare untuk wildcard certificate maupun sertifikat biasa tanpa harus membuka port 80 ke dunia luar.

Step Instalasi

1. Buat Secret untuk Credentials Dashboard Traefik

Pertama, kita perlu mengamankan dashboard Traefik dengan basic authentication. Kita akan membuat hash password menggunakan htpasswd.

# Buat direktori kerja untuk Traefik

mkdir traefik
cd traefik

# Hasilkan username dan hash password

# Ganti <yourPassword> dengan password yang kuat
htpasswd -nb admin "<yourPassword>" | sed -e 's/\$/\$\$/g'

# Hasilnya akan seperti ini: admin:$$apr1$$...

# Copy hasil lengkapnya untuk langkah selanjutnya

Keterangan: Perintah sed -e 's/\$/\$\$/g' sangat penting. Ini berfungsi untuk melakukan escape pada karakter $ di dalam hash password. Tanpa ini, Docker Compose akan salah menginterpretasikannya sebagai variabel dan menyebabkan otentikasi gagal.

2. Buat Credentials untuk Cloudflare

Selanjutnya, buat file .env untuk menyimpan kredensial Cloudflare. Traefik akan menggunakan ini untuk memvalidasi kepemilikan domain melalui DNS Challenge (DNS-01).

# Buat file .env dan isi dengan kredensial Anda
cat << EOF | tee .env
CF_API_EMAIL="<email_cloudflare_anda>"
CF_DNS_API_TOKEN="<token_api_cloudflare_anda>"
EOF

Keterangan: Sangat disarankan untuk membuat API Token di Cloudflare dengan permission sebatas Zone:DNS:Edituntuk domain yang bersangkutan, daripada menggunakan Global API Key. Ini adalah praktik keamanan yang lebih baik (_least privilege_).

3. Buat compose.yaml

Ini adalah inti dari instalasi Traefik kita. File ini mendefinisikan servis Traefik itu sendiri, beserta konfigurasi dasarnya melalui label Docker.

services:
  traefik:
    image: traefik:v3.0 # Selalu baik untuk menggunakan versi spesifik
    container_name: traefik
    restart: unless-stopped
    environment:
      - CF_API_EMAIL=${CF_API_EMAIL}
      - CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
    security_opt:
      - no-new-privileges:true

    networks:
      - proxy

    ports:
      - "80:80"
      - "443:443"
      # - "8080:8080" # Opsional: jika ingin expose dashboard tanpa proxy

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./certs:/certs
      - ./traefik.yaml:/etc/traefik/traefik.yaml:ro

    # Traefik Dynamic configuration via Docker labels
    labels:
      # Enable self‑routing
      - "traefik.enable=true"

      # Dashboard router
      - "traefik.http.routers.dashboard.rule=Host(`dashboard.domain-anda.com`)"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.tls=true"
      - "traefik.http.routers.dashboard.tls.certresolver=letencrypt"

      # Basic‑auth middleware
      - "traefik.http.middlewares.dashboard-auth.basicauth.users=<Paste Credentials dari Langkah 1 Disini>"
      - "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker"

networks:
  proxy:
    name: proxy

Keterangan:

- environment: Mengambil nilai variabel dari file .env yang kita buat tadi dan memberikannya ke kontainer Traefik.

- networks: - proxy: Ini krusial. Kita membuat sebuah network khusus bernama proxy. Semua servis yang ingin di-ekspos melalui Traefik harus terhubung ke network ini.

- volumes:

- /var/run/docker.sock:/var/run/docker.sock:ro: Ini adalah "sihir"-nya. Dengan me-mounting Docker socket (dalam mode read-only untuk keamanan), Traefik bisa "mendengarkan" setiap kejadian di Docker (misal: kontainer start/stop) dan secara otomatis memperbarui konfigurasinya tanpa perlu di-restart.

- ./certs:/certs: Volume untuk menyimpan sertifikat SSL yang dihasilkan oleh Let's Encrypt secara persisten.

- ./traefik.yaml:/etc/traefik/traefik.yaml:ro: File konfigurasi statis Traefik yang akan kita buat selanjutnya.

- labels: Di sini kita mengkonfigurasi Traefik untuk dirinya sendiri. Kita memberitahu Traefik untuk membuat sebuah router untuk dashboard-nya, mengamankannya dengan HTTPS websecure), menggunakan resolveletencrypt, dan menerapkan middleware otentikasi dasar yang telah kita siapkan.

4. Buat Konfigurasi Statis Traefik

File ini berisi konfigurasi yang jarang berubah, seperti mendefinisikan entrypoints (port masuk), provider Docker, dan konfigurasi Let's Encrypt.

cat << EOF > traefik.yaml
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true

  websecure:
    address: ":443"
    http:
      tls: {}

providers:
  docker:
    exposedByDefault: false
    network: proxy

api:
  dashboard: true
  insecure: false

log:
  level: INFO

accessLog: {}

certificatesResolvers:
  letencrypt:
    acme:
      email: email-anda@email.com
      storage: /certs/acme.json
      caServer: [https://acme-v02.api.letsencrypt.org/directory](https://acme-v02.api.letsencrypt.org/directory) # production (default)
      # caServer: [https://acme-staging-v02.api.letsencrypt.org/directory](https://acme-staging-v02.api.letsencrypt.org/directory) # staging (gunakan ini saat development)
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: 10 # Opsional, menunggu 10 detik sebelum verifikasi DNS
EOF

Keterangan:

- entryPoints: Mendefinisikan "pintu masuk" traffic. web (port 80) diatur untuk secara otomatis me-redirect semua permintaan ke websecure (port 443/HTTPS).

- providers.docker: Mengaktifkan Docker sebagai provider konfigurasi. exposedByDefault: false adalah setelan keamanan yang penting, artinya kita harus secara eksplisit menambahkan label traefik.enable=true pada setiap servis yang ingin di-ekspos.

- certificatesResolvers.letencrypt: Di sinilah kita mendefinisikan resolver sertifikat kita, memberitahu Traefik untuk menggunakan email dan penyimpanan yang ditentukan, serta memakai dnsChallenge dengan provider cloudflarePenting: Gunakan caServer staging selama masa percobaan untuk menghindari rate limit dari Let's Encrypt. Ganti ke production jika semua sudah berjalan lancar.

5. Compose UP!

Sekarang, saatnya menjalankan Traefik.

sudo docker compose up -d

Jika semua berjalan lancar, Anda seharusnya sudah bisa mengakses https://dashboard.domain-anda.com dan akan diminta memasukkan username dan password yang telah dibuat di langkah pertama.

traefik dashboard

Expose Service Lain

Inilah bagian terbaiknya. Untuk mengekspos servis baru, kita hanya perlu menambahkan beberapa baris labels di file compose.yaml servis tersebut.

Disini saya mencontohkan untuk expose WordPress. Anggap kita punya compose.yaml untuk WordPress, kita hanya perlu memodifikasinya seperti ini:

services:
  # ... (definisi servis database, jika ada)

  wordpress:
    image: wordpress:latest
    restart: unless-stopped
    environment:
      WORDPRESS_DB_HOST: db
      # ... env lain
    networks:
      - proxy # <--- PENTING: Hubungkan ke network proxy
      - internal # network untuk komunikasi dengan db
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wordpress-https.rule=Host(`wp.domain-anda.com`)" # sesuaikan dengan dns nya
      - "traefik.http.routers.wordpress-https.entrypoints=websecure"
      - "traefik.http.routers.wordpress-https.tls=true"
      - "traefik.http.routers.wordpress-https.tls.certresolver=letencrypt"
      # Memberitahu Traefik port internal mana yang harus dihubungi
      - "traefik.http.services.wordpress-svc.loadbalancer.server.port=80"

# ... (definisi network lain)

networks:
  proxy:
    external: true
  internal:
    external: false

Keterangan:

- *networks**: Pertama dan terpenting, pastikan kontainer WordPress terhubung ke jaringan proxy yang sama dengan Traefik.

- *traefik.enable: "true"**: "Saklar" untuk memberitahu Traefik agar mengelola proxy untuk servis ini.

- *traefik.http.routers...rule**: Menentukan aturan routing. Dalam hal ini, semua traffic untuk wp.domain-anda.com akan diarahkan ke kontainer ini.

- *traefik.http.routers...entrypoints**: Menentukan bahwa router ini hanya mendengarkan di pintu masuk websecure (HTTPS).

- *traefik.http.routers...tls.certresolver**: Menyuruh Traefik untuk secara otomatis mendapatkan sertifikat SSL untuk domain ini menggunakan resolver letencrypt yang telah kita buat.

- *traefik.http.services...port**: Menentukan port internal dari servis yang dituju (WordPress berjalan di port 80 di dalam kontainernya).

Setelah menambahkan label ini, cukup jalankan docker compose up -d di direktori WordPress, dan Traefik akan secara otomatis mendeteksinya, meminta sertifikat SSL, dan mulai mengarahkan traffic. Semuanya tanpa menyentuh konfigurasi Traefik sama sekali.


Comment