(registry_auth) { basicauth { {env.REGISTRY_USERNAME} {env.REGISTRY_PASSWORD_HASH} } } # Option A: Self-signed certificates (IP address) YOUR_ACTUAL_IP_ADDRESS { # Use our generated TLS certificate tls /opt/registry/certs/registry.crt /opt/registry/certs/registry.key # Security headers header { X-Content-Type-Options nosniff X-Frame-Options DENY X-XSS-Protection "1; mode=block" Referrer-Policy "strict-origin-when-cross-origin" Content-Security-Policy "default-src 'self'; frame-ancestors 'none'" } # Handle registry operations based on URL patterns @push_operations { path /v2/*/blobs/uploads/* path /v2/*/manifests/* method PUT POST PATCH DELETE } @pull_operations { path /v2/*/blobs/* path /v2/*/manifests/* path /v2/_catalog path /v2/*/tags/list method GET HEAD OPTIONS } # Require authentication for push operations handle @push_operations { import registry_auth reverse_proxy registry:5000 { header_up Authorization {http.request.header.Authorization} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} header_up X-Forwarded-Host {host} header_up Host {host} } } # Allow unauthenticated pull operations handle @pull_operations { reverse_proxy registry:5000 { header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} header_up X-Forwarded-Host {host} header_up Host {host} } } # Block all other requests handle { respond "Registry operation not allowed" 405 } # Logging log { output file /var/log/caddy/registry.log format json level INFO } # Compression encode zstd gzip } # Option B: Let's Encrypt certificates (Domain name) # Uncomment and customize for domain-based setup # YOUR_DOMAIN_NAME { # # Let's Encrypt handles TLS automatically # # # Security headers # header { # X-Content-Type-Options nosniff # X-Frame-Options DENY # X-XSS-Protection "1; mode=block" # Referrer-Policy "strict-origin-when-cross-origin" # Content-Security-Policy "default-src 'self'; frame-ancestors 'none'" # } # # # Handle registry operations based on URL patterns # @push_operations { # path /v2/*/blobs/uploads/* # path /v2/*/manifests/* # method PUT POST PATCH DELETE # } # # @pull_operations { # path /v2/*/blobs/* # path /v2/*/manifests/* # path /v2/_catalog # path /v2/*/tags/list # method GET HEAD OPTIONS # } # # # Require authentication for push operations # handle @push_operations { # import registry_auth # reverse_proxy registry:5000 { # header_up Authorization {http.request.header.Authorization} # header_up X-Forwarded-For {remote_host} # header_up X-Forwarded-Proto {scheme} # header_up X-Forwarded-Host {host} # header_up Host {host} # } # } # # # Allow unauthenticated pull operations # handle @pull_operations { # reverse_proxy registry:5000 { # header_up X-Forwarded-For {remote_host} # header_up X-Forwarded-Proto {scheme} # header_up X-Forwarded-Host {host} # header_up Host {host} # } # } # # # Block all other requests # handle { # respond "Registry operation not allowed" 405 # } # # # Logging # log { # output file /var/log/caddy/registry.log # format json # level INFO # } # # # Compression # encode zstd gzip # }