Adfaft

How to Series - Caddy sebagai server alternative yang simple dan menyediakan HTTPS secara otomatis

Table of Content

Reference

Summary

Caddy adalah alternatif server seperti Apache, Nginx, atau Trafik yang simple dan mudah untuk disetting diawal.

Caddy sudah include HTTPS secara default, untuk local hostname akan menggunaka self-signed certificates dan untuk public site akan menggunakan Lets Encrypt / ZeroSSL

Caddy dapat digunakan sebagai alternatif dari server seperti Apache, Nginx, atau Traefik

Disini akan membahas:

Personal Opinion

Pilihan saya untuk Caddy:

Prerequisites

How to

Installation

# filename: Caddyfile

localhost:80 {
	respond "hello world"
}
# filename: docker-compose.yml
services:
  caddy:
    image: [](caddy:latest)
    container_name: caddy
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - $PWD/[](conf:/etc/caddy)
      - $PWD/[](site:/srv)
      - [](caddy_data:/data)
      - [](caddy_config:/config)
      - $PWD/index.[](html:/usr/share/caddy/index.html)
    networks:
      - default

volumes:
  caddy_data:
  caddy_config:

networks:
  caddy:

Alternatively, create a script for easy HOT Reloading with file name hot-reload.sh

#!/bin/sh
docker exec caddy caddy reload --adapter caddyfile --config /etc/caddy/Caddyfile

make it executable chmod +x hot-reload.sh and run with command ./hot-reload.sh

Examples

Static respond

[domain] {
	respond "[string]"
}

contoh:

test.com {
	respond "hello world"
}

Static Site

[domain] {
	root * [path]
	file_server
}

contoh :

[domain] {
	root * /var/www/mysite
	file_server
}

Jika digunakan sebagai file listing

[domain] {
	root * /var/www/mydir
	file_server browse
}

Reverse Proxy

[domain] {
	reverse_proxy [domain]
}

contoh, untuk docker container mycontainer di port 8080 (kalau docker, gunakan container name, bukan localhost)

subdomain.test.com {
	redir /path /real_path   # optional, for redirect
	reverse_proxy [](http://mycontainer:8080)
}

PHP Laravel App

ref: https://github.com/Kamleshpaul/laravel-caddy?tab=readme-ov-file

buat snippet untuk security.conf

# filename: snippets/security.conf

header {
    # keep referrer data off of HTTP connections
    Referrer-Policy no-referrer-when-downgrade
    # Referrer-Policy "strict-origin-when-cross-origin"

    # enable HSTS
    Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

    # Enable cross-site filter (XSS) and tell browser to block detected attacks
    X-Xss-Protection "1; mode=block"

    # disable clients from sniffing the media type
    X-Content-Type-Options "nosniff"

    # clickjacking protection
    X-Frame-Options "SAMEORIGIN"

    Content-Security-Policy "upgrade-insecure-requests"

    # hide server name
    -Server Caddy
}

buat snippet untuk laravel app laravel-snippet.conf

# filename: snippets/laravel-snippet.conf

# snippets/laravel-app
# {args[0]} represents the root url of the app. Example: "exmaple.com".
# {args[1]} represents the root path to the app. Example: "/var/www/html/laravel-app"

(laravel-app) {
    {args[0]} {
        # apply security header
        import security.conf

        # Resolve the root directory for the app
        root * {args[1]}/public

        # Provide Zstd and Gzip compression
        encode zstd gzip

        # Enable PHP-FPM 
        # Change this based on installed php version
        php_fastcgi unix//run/php/php8.3-fpm.sock 

        # Allow caddy to serve static files
        file_server
    }
}

Kemudian, isi dari Caddyfile menjadi

# filename: Caddyfile

import snippets/*
import laravel-app example.com /var/www/html/example.com

Caddyfile

Struktur dari Caddyfile antara lain ![[./assets/how-to-series---caddy/caddyfile-visual.png]]

contoh lain untuk matchers https://caddyserver.com/docs/caddyfile/matchers

Metrics via Prometheus

ref: https://github.com/Kamleshpaul/laravel-caddy/tree/main Hidupkan metrics sebagai global options block di Caddyfile

{
	metrics {
		per_host
	}
}

Maka metrics sudah di expose di /metrics . URL ini dapat di konfigurasi lagi via Caddyfile, contoh

example.com {
	# disable
	metrics /metrics {
		disable_openmetrics
	}

	# redirect ke path lain
	metrics /foo/bar/path

}

Contoh config prometheus

# prometheus.yaml
global:
  scrape_interval: 15s # default is 1 minute

scrape_configs:
  - job_name: caddy
    static_configs:
      - targets: ['[](localhost:2019)']

dan jalankan config tersebut di prometheus via

$ prometheus --config.file=prometheus.yaml

Other Reading

Footnote