Ctrl K
ComunidadGuías…

Caddyfile

Rama 3.1.x · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
{
	{$CADDY_GLOBAL_OPTIONS}

	admin off

	auto_https {$AUTO_HTTPS:disable_redirects}

	servers {
		trusted_proxies static {$CADDY_TRUSTED_PROXIES:private_ranges}
		client_ip_headers Cf-Connecting-Ip X-Forwarded-For
	}

	# Logging
	log {
		output stdout
		format {$SOLIDINVOICE_LOG_FORMAT:console}
		level {$LOG_LEVEL:INFO}
	}

	frankenphp {
		{$FRANKENPHP_CONFIG}
	}
}

{$CADDY_EXTRA_CONFIG} 

{$SERVER_NAME} {
	bind {$SERVER_IP:0.0.0.0}

	root {$APP_PATH}/public

	# Extra directives (for "tls internal" in dev mode)
	{$CADDY_SERVER_EXTRA_DIRECTIVES}

	# Health check endpoint
	@health path /health
	respond @health "OK" 200

	# When behind Cloudflare, the intermediate proxy (e.g. Traefik, cloudflared)
	# may set X-Forwarded-Proto to "http" because its connection to Caddy is plain HTTP.
	# Cloudflare's Cf-Visitor header carries the original scheme, so use it to fix the proto.
	@cloudflare header Cf-Visitor *https*
	request_header @cloudflare X-Forwarded-Proto "https"
	request_header @cloudflare X-Forwarded-Port "443"

	# Caddy resolves the real client IP from client_ip_headers + trusted_proxies.
	# PHP only sees headers, so write it back into X-Forwarded-For (which Symfony
	# trusts). Untrusted peers get their own IP here, so XFF cannot be forged.
	request_header X-Forwarded-For {client_ip}

	# Basic security headers (for self-hosted deployments)
	header {
		X-Content-Type-Options "nosniff"
		X-Frame-Options "SAMEORIGIN"
		-Permissions-Policy "browsing-topics=()"
		-Server
	}

	# Access logging (JSON format for log ingestion)
	# Note: For sensitive data filtering (headers, query params), configure your
	# log aggregation system (e.g., Loki, Elasticsearch) to redact sensitive fields
	log {
		{$CADDY_SERVER_LOG_OPTIONS}
		output stdout
		format {$SOLIDINVOICE_LOG_FORMAT:console} {
			time_format iso8601
			time_key ts
			level_key level
			message_key msg
		}
	}

	# Static asset caching: files with a content hash in the name never change, so cache them
	# for good; anything else keeps its name across releases and must be revalidated.
	@static_hashed {
		path /css/* /js/* /static/* /images/* /fonts/* /build/* *.ico *.png *.jpg *.svg *.woff *.woff2
		path_regexp \.[0-9a-f]{8,}\.[a-z0-9]+$
	}
	header @static_hashed Cache-Control "public, max-age=31536000, immutable" defer

	@static {
		path /css/* /js/* /static/* /images/* /fonts/* /build/* *.ico *.png *.jpg *.svg *.woff *.woff2
		not path_regexp \.[0-9a-f]{8,}\.[a-z0-9]+$
	}
	header @static Cache-Control "public, max-age=3600, must-revalidate" defer

	# Compression
	encode zstd br gzip

	#	mercure {
	#		# Transport to use (default to Bolt)
	#		transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db}
	#		# Publisher JWT key
	#		publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
	#		# Subscriber JWT key
	#		subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
	#		# Allow anonymous subscribers (double-check that it's what you want)
	#		anonymous
	#		# Enable the subscription API (double-check that it's what you want)
	#		subscriptions
	#		# Extra directives
	#		{$MERCURE_EXTRA_DIRECTIVES}
	#	}

	#	vulcain

	@phpRoute {
		not path /.well-known/mercure*
		not path /health
		not file {path}
	}
	rewrite @phpRoute index.php

	@frontController path index.php
	php @frontController

	file_server {
		hide .env* .git* .php* composer.* package.json *.lock
	}
}