From cdf0820bb8f9cc86896eaa7a649b38011e54c4fc Mon Sep 17 00:00:00 2001 From: "Arthur K." Date: Thu, 29 May 2025 16:29:59 +0300 Subject: [PATCH] --- .gitignore | 6 +- Dockerfile | 4 +- cmd/traefik/traefik.go | 6 + compose.yml | 20 + .../reference/static-configuration/cli-ref.md | 3 + .../reference/static-configuration/env-ref.md | 3 + .../reference/static-configuration/file.toml | 1 + .../reference/static-configuration/file.yaml | 3 + pkg/config/static/static_config.go | 1 + pkg/updater/provider.go | 49 + schema.json | 1829 +++++++++++++++++ traefik.sample.toml | 152 -- traefik.sample.yml | 151 -- traefik.yml | 54 + 14 files changed, 1974 insertions(+), 308 deletions(-) create mode 100644 compose.yml create mode 100644 pkg/updater/provider.go create mode 100644 schema.json delete mode 100644 traefik.sample.toml delete mode 100644 traefik.sample.yml create mode 100644 traefik.yml diff --git a/.gitignore b/.gitignore index 1754b1c70..b1ce4c383 100644 --- a/.gitignore +++ b/.gitignore @@ -8,9 +8,9 @@ /site/ /docs/site/ /autogen/ -/traefik -/traefik.toml -/traefik.yml +# /traefik +# /traefik.toml +# /traefik.yml *.log *.exe cover.out diff --git a/Dockerfile b/Dockerfile index fcf9c49b9..ec1012635 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,8 @@ FROM alpine:3.21 RUN apk add --no-cache --no-progress ca-certificates tzdata -ARG TARGETPLATFORM -COPY ./dist/$TARGETPLATFORM/traefik / +COPY ./dist/linux/amd64/traefik / +COPY ./traefik.yml /etc/traefik/traefik.yml EXPOSE 80 VOLUME ["/tmp"] diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index 61f8e8217..1aeccf08e 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -49,6 +49,7 @@ import ( "github.com/traefik/traefik/v3/pkg/tracing" "github.com/traefik/traefik/v3/pkg/types" "github.com/traefik/traefik/v3/pkg/version" + "github.com/traefik/traefik/v3/pkg/updater" ) func main() { @@ -197,6 +198,8 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err tsProviders := initTailscaleProviders(staticConfiguration, providerAggregator) + updaterProvider := updater.New(staticConfiguration); + // Observability metricRegistries := registerMetricClients(staticConfiguration.Metrics) @@ -383,6 +386,9 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err } }) + // Updater + watcher.AddListener(updaterProvider.HandleConfigUpdate) + return server.NewServer(routinesPool, serverEntryPointsTCP, serverEntryPointsUDP, watcher, observabilityMgr), nil } diff --git a/compose.yml b/compose.yml new file mode 100644 index 000000000..603819644 --- /dev/null +++ b/compose.yml @@ -0,0 +1,20 @@ +services: + traefik: + build: . + network_mode: host + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - certs:/etc/certs/ + - /tmp:/tmp + environment: + - CF_API_EMAIL=${CF_API_EMAIL} + - CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN} + labels: + traefik.host: _ + traefik.http.services.dashboard.loadbalancer.server.port: 0 + traefik.http.routers.api.rule: Host(`traefik-cpu.wzray.com`) + traefik.http.routers.api.service: api@internal + restart: unless-stopped + +volumes: + certs: diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index b35cbc982..2eaa9861b 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -369,6 +369,9 @@ Periodically check if a new version has been released. (Default: ```true```) `--global.sendanonymoususage`: Periodically send anonymous usage statistics. If the option is not specified, it will be disabled by default. (Default: ```false```) +`--global.updatercallbacks`: +Callback urls for updater script (example: https://localhost:8080/callback) + `--hostresolver`: Enable CNAME Flattening. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index 8f6e25c05..474fdc9ef 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -369,6 +369,9 @@ Periodically check if a new version has been released. (Default: ```true```) `TRAEFIK_GLOBAL_SENDANONYMOUSUSAGE`: Periodically send anonymous usage statistics. If the option is not specified, it will be disabled by default. (Default: ```false```) +`TRAEFIK_GLOBAL_UPDATERCALLBACKS`: +Callback urls for updater script (example: https://localhost:8080/callback) + `TRAEFIK_HOSTRESOLVER`: Enable CNAME Flattening. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index e548ee76d..8e96fd52e 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -3,6 +3,7 @@ [global] checkNewVersion = true sendAnonymousUsage = true + updaterCallbacks = ["foobar", "foobar"] [serversTransport] insecureSkipVerify = true diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml index 760802591..3c79d9089 100644 --- a/docs/content/reference/static-configuration/file.yaml +++ b/docs/content/reference/static-configuration/file.yaml @@ -3,6 +3,9 @@ global: checkNewVersion: true sendAnonymousUsage: true + updaterCallbacks: + - foobar + - foobar serversTransport: insecureSkipVerify: true rootCAs: diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index af60efbb8..73f740472 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -108,6 +108,7 @@ type CertificateResolver struct { type Global struct { CheckNewVersion bool `description:"Periodically check if a new version has been released." json:"checkNewVersion,omitempty" toml:"checkNewVersion,omitempty" yaml:"checkNewVersion,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` SendAnonymousUsage bool `description:"Periodically send anonymous usage statistics. If the option is not specified, it will be disabled by default." json:"sendAnonymousUsage,omitempty" toml:"sendAnonymousUsage,omitempty" yaml:"sendAnonymousUsage,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + UpdaterCallbacks []string `description:"Callback urls for updater script (example: https://localhost:8080/callback)" json:"updaterCallbacks,omitempty" toml:"updaterCallbacks,omitempty" yaml:"updaterCallbacks,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` } // ServersTransport options to configure communication between Traefik and the servers. diff --git a/pkg/updater/provider.go b/pkg/updater/provider.go new file mode 100644 index 000000000..26d1fc469 --- /dev/null +++ b/pkg/updater/provider.go @@ -0,0 +1,49 @@ +package updater + +import ( + "bytes" + "encoding/json" + "net/http" + + "github.com/rs/zerolog/log" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/safe" +) + +type Updater struct { + callbackUrls []string +} + +func New(config *static.Configuration) *Updater { + updater := &Updater{ + callbackUrls: config.Global.UpdaterCallbacks, + } + + return updater +} + +func (u *Updater) HandleConfigUpdate(cfg dynamic.Configuration) { + body, err := json.Marshal(cfg) + + if err != nil { + // should never happen? + log.Error().Err(err).Msg("Error while marshalling dynamic configuration data to json") + return + } + + requestBody := bytes.NewBuffer(body) + + for _, url := range u.callbackUrls { + safe.Go(func() { + resp, err := http.Post(url, "application/json", requestBody) + + if err != nil { + log.Error().Err(err).Str("url", url).Msg("Error while sending configuration data to callback") + } else { + log.Debug().Str("url", url).Msg("Configuration data sent") + resp.Body.Close() + } + }) + } +} diff --git a/schema.json b/schema.json new file mode 100644 index 000000000..2abcd8b90 --- /dev/null +++ b/schema.json @@ -0,0 +1,1829 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://json.schemastore.org/traefik-v3.json", + "$defs": { + "CertificateResolverTailscaleStruct": { + "additionalProperties": false, + "type": "object" + }, + "acmeConfiguration": { + "additionalProperties": false, + "properties": { + "caCertificates": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "caServer": { + "type": "string" + }, + "caServerName": { + "type": "string" + }, + "caSystemCertPool": { + "type": "boolean" + }, + "certificatesDuration": { + "type": "integer" + }, + "dnsChallenge": { + "$ref": "#/$defs/acmeDNSChallenge" + }, + "eab": { + "$ref": "#/$defs/acmeEAB" + }, + "email": { + "type": "string" + }, + "httpChallenge": { + "$ref": "#/$defs/acmeHTTPChallenge" + }, + "keyType": { + "type": "string" + }, + "preferredChain": { + "type": "string" + }, + "storage": { + "type": "string" + }, + "tlsChallenge": { + "$ref": "#/$defs/acmeTLSChallenge" + } + }, + "type": "object" + }, + "acmeDNSChallenge": { + "additionalProperties": false, + "properties": { + "delayBeforeCheck": { + "type": "string" + }, + "disablePropagationCheck": { + "type": "boolean" + }, + "propagation": { + "$ref": "#/$defs/acmePropagation" + }, + "provider": { + "type": "string" + }, + "resolvers": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + } + }, + "type": "object" + }, + "acmeEAB": { + "additionalProperties": false, + "properties": { + "hmacEncoded": { + "type": "string" + }, + "kid": { + "type": "string" + } + }, + "type": "object" + }, + "acmeHTTPChallenge": { + "additionalProperties": false, + "properties": { + "entryPoint": { + "type": "string" + } + }, + "type": "object" + }, + "acmePropagation": { + "additionalProperties": false, + "properties": { + "delayBeforeChecks": { + "type": "string" + }, + "disableANSChecks": { + "type": "boolean" + }, + "disableChecks": { + "type": "boolean" + }, + "requireAllRNS": { + "type": "boolean" + } + }, + "type": "object" + }, + "acmeTLSChallenge": { + "additionalProperties": false, + "type": "object" + }, + "consulProviderBuilder": { + "additionalProperties": false, + "properties": { + "endpoints": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "rootKey": { + "type": "string" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + }, + "token": { + "type": "string" + } + }, + "type": "object" + }, + "consulcatalogEndpointConfig": { + "additionalProperties": false, + "properties": { + "address": { + "type": "string" + }, + "datacenter": { + "type": "string" + }, + "endpointWaitTime": { + "type": "string" + }, + "httpAuth": { + "$ref": "#/$defs/consulcatalogEndpointHTTPAuthConfig" + }, + "scheme": { + "type": "string" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + }, + "token": { + "type": "string" + } + }, + "type": "object" + }, + "consulcatalogEndpointHTTPAuthConfig": { + "additionalProperties": false, + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "consulcatalogProviderBuilder": { + "additionalProperties": false, + "properties": { + "cache": { + "type": "boolean" + }, + "connectAware": { + "type": "boolean" + }, + "connectByDefault": { + "type": "boolean" + }, + "constraints": { + "type": "string" + }, + "defaultRule": { + "type": "string" + }, + "endpoint": { + "$ref": "#/$defs/consulcatalogEndpointConfig" + }, + "exposedByDefault": { + "type": "boolean" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "prefix": { + "type": "string" + }, + "refreshInterval": { + "type": "string" + }, + "requireConsistent": { + "type": "boolean" + }, + "serviceName": { + "type": "string" + }, + "stale": { + "type": "boolean" + }, + "strictChecks": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "watch": { + "type": "boolean" + } + }, + "type": "object" + }, + "crdProvider": { + "additionalProperties": false, + "properties": { + "allowCrossNamespace": { + "type": "boolean" + }, + "allowEmptyServices": { + "type": "boolean" + }, + "allowExternalNameServices": { + "type": "boolean" + }, + "certAuthFilePath": { + "type": "string" + }, + "disableClusterScopeResources": { + "type": "boolean" + }, + "endpoint": { + "type": "string" + }, + "ingressClass": { + "type": "string" + }, + "labelSelector": { + "type": "string" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "nativeLBByDefault": { + "type": "boolean" + }, + "throttleDuration": { + "type": "string" + }, + "token": { + "type": "string" + } + }, + "type": "object" + }, + "dockerProvider": { + "additionalProperties": false, + "properties": { + "allowEmptyServices": { + "type": "boolean" + }, + "constraints": { + "type": "string" + }, + "defaultRule": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "exposedByDefault": { + "type": "boolean" + }, + "httpClientTimeout": { + "type": "string" + }, + "network": { + "type": "string" + }, + "password": { + "type": "string" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + }, + "useBindPortIP": { + "type": "boolean" + }, + "username": { + "type": "string" + }, + "watch": { + "type": "boolean" + } + }, + "type": "object" + }, + "dockerSwarmProvider": { + "additionalProperties": false, + "properties": { + "allowEmptyServices": { + "type": "boolean" + }, + "constraints": { + "type": "string" + }, + "defaultRule": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "exposedByDefault": { + "type": "boolean" + }, + "httpClientTimeout": { + "type": "string" + }, + "network": { + "type": "string" + }, + "password": { + "type": "string" + }, + "refreshSeconds": { + "type": "string" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + }, + "useBindPortIP": { + "type": "boolean" + }, + "username": { + "type": "string" + }, + "watch": { + "type": "boolean" + } + }, + "type": "object" + }, + "ecsProvider": { + "additionalProperties": false, + "properties": { + "accessKeyID": { + "type": "string" + }, + "autoDiscoverClusters": { + "type": "boolean" + }, + "clusters": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "constraints": { + "type": "string" + }, + "defaultRule": { + "type": "string" + }, + "ecsAnywhere": { + "type": "boolean" + }, + "exposedByDefault": { + "type": "boolean" + }, + "healthyTasksOnly": { + "type": "boolean" + }, + "refreshSeconds": { + "type": "integer" + }, + "region": { + "type": "string" + }, + "secretAccessKey": { + "type": "string" + } + }, + "type": "object" + }, + "etcdProvider": { + "additionalProperties": false, + "properties": { + "endpoints": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "password": { + "type": "string" + }, + "rootKey": { + "type": "string" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "fileProvider": { + "additionalProperties": false, + "properties": { + "debugLogGeneratedTemplate": { + "type": "boolean" + }, + "directory": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "watch": { + "type": "boolean" + } + }, + "type": "object" + }, + "gatewayProvider": { + "additionalProperties": false, + "properties": { + "certAuthFilePath": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "experimentalChannel": { + "type": "boolean" + }, + "labelSelector": { + "type": "string" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "nativeLBByDefault": { + "type": "boolean" + }, + "statusAddress": { + "$ref": "#/$defs/gatewayStatusAddress" + }, + "throttleDuration": { + "type": "string" + }, + "token": { + "type": "string" + } + }, + "type": "object" + }, + "gatewayServiceRef": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + }, + "type": "object" + }, + "gatewayStatusAddress": { + "additionalProperties": false, + "properties": { + "hostname": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "service": { + "$ref": "#/$defs/gatewayServiceRef" + } + }, + "type": "object" + }, + "httpProvider": { + "additionalProperties": false, + "properties": { + "endpoint": { + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "pollInterval": { + "type": "string" + }, + "pollTimeout": { + "type": "string" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + } + }, + "required": ["endpoint"], + "type": "object" + }, + "ingressEndpointIngress": { + "additionalProperties": false, + "properties": { + "hostname": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "publishedService": { + "type": "string" + } + }, + "type": "object" + }, + "ingressProvider": { + "additionalProperties": false, + "properties": { + "allowEmptyServices": { + "type": "boolean" + }, + "allowExternalNameServices": { + "type": "boolean" + }, + "certAuthFilePath": { + "type": "string" + }, + "disableClusterScopeResources": { + "type": "boolean" + }, + "disableIngressClassLookup": { + "type": "boolean" + }, + "endpoint": { + "type": "string" + }, + "ingressClass": { + "type": "string" + }, + "ingressEndpoint": { + "$ref": "#/$defs/ingressEndpointIngress" + }, + "labelSelector": { + "type": "string" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "nativeLBByDefault": { + "type": "boolean" + }, + "throttleDuration": { + "type": "string" + }, + "token": { + "type": "string" + } + }, + "type": "object" + }, + "nomadEndpointConfig": { + "additionalProperties": false, + "properties": { + "address": { + "type": "string" + }, + "endpointWaitTime": { + "type": "string" + }, + "region": { + "type": "string" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + }, + "token": { + "type": "string" + } + }, + "type": "object" + }, + "nomadProviderBuilder": { + "additionalProperties": false, + "properties": { + "allowEmptyServices": { + "type": "boolean" + }, + "constraints": { + "type": "string" + }, + "defaultRule": { + "type": "string" + }, + "endpoint": { + "$ref": "#/$defs/nomadEndpointConfig" + }, + "exposedByDefault": { + "type": "boolean" + }, + "namespaces": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "prefix": { + "type": "string" + }, + "refreshInterval": { + "type": "string" + }, + "stale": { + "type": "boolean" + }, + "throttleDuration": { + "type": "string" + }, + "watch": { + "type": "boolean" + } + }, + "type": "object" + }, + "pingHandler": { + "additionalProperties": false, + "properties": { + "entryPoint": { + "type": "string" + }, + "manualRouting": { + "type": "boolean" + }, + "terminatingStatusCode": { + "type": "integer" + } + }, + "type": "object" + }, + "pluginsDescriptor": { + "additionalProperties": false, + "properties": { + "moduleName": { + "type": "string" + }, + "settings": { + "$ref": "#/$defs/pluginsSettings" + }, + "version": { + "type": "string" + } + }, + "type": "object" + }, + "pluginsLocalDescriptor": { + "additionalProperties": false, + "properties": { + "moduleName": { + "type": "string" + }, + "settings": { + "$ref": "#/$defs/pluginsSettings" + } + }, + "type": "object" + }, + "pluginsSettings": { + "additionalProperties": false, + "properties": { + "envs": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "mounts": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + } + }, + "type": "object" + }, + "redisProvider": { + "additionalProperties": false, + "properties": { + "db": { + "type": "integer" + }, + "endpoints": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "password": { + "type": "string" + }, + "rootKey": { + "type": "string" + }, + "sentinel": { + "$ref": "#/$defs/redisSentinel" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "redisSentinel": { + "additionalProperties": false, + "properties": { + "latencyStrategy": { + "type": "boolean" + }, + "masterName": { + "type": "string" + }, + "password": { + "type": "string" + }, + "randomStrategy": { + "type": "boolean" + }, + "replicaStrategy": { + "type": "boolean" + }, + "useDisconnectedReplicas": { + "type": "boolean" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "restProvider": { + "additionalProperties": false, + "properties": { + "insecure": { + "type": "boolean" + } + }, + "type": "object" + }, + "staticAPI": { + "additionalProperties": false, + "properties": { + "basePath": { + "type": "string" + }, + "dashboard": { + "type": "boolean" + }, + "debug": { + "type": "boolean" + }, + "disableDashboardAd": { + "type": "boolean" + }, + "insecure": { + "type": "boolean" + } + }, + "type": "object" + }, + "staticCertificateResolver": { + "additionalProperties": false, + "properties": { + "acme": { + "$ref": "#/$defs/acmeConfiguration" + }, + "tailscale": { + "$ref": "#/$defs/CertificateResolverTailscaleStruct" + } + }, + "type": "object" + }, + "staticCore": { + "additionalProperties": false, + "properties": { + "defaultRuleSyntax": { + "type": "string" + } + }, + "type": "object" + }, + "staticEntryPoint": { + "additionalProperties": false, + "properties": { + "address": { + "type": "string" + }, + "allowACMEByPass": { + "type": "boolean" + }, + "asDefault": { + "type": "boolean" + }, + "forwardedHeaders": { + "$ref": "#/$defs/staticForwardedHeaders" + }, + "http": { + "$ref": "#/$defs/staticHTTPConfig" + }, + "http2": { + "$ref": "#/$defs/staticHTTP2Config" + }, + "http3": { + "$ref": "#/$defs/staticHTTP3Config" + }, + "observability": { + "$ref": "#/$defs/staticObservabilityConfig" + }, + "proxyProtocol": { + "$ref": "#/$defs/staticProxyProtocol" + }, + "reusePort": { + "type": "boolean" + }, + "transport": { + "$ref": "#/$defs/staticEntryPointsTransport" + }, + "udp": { + "$ref": "#/$defs/staticUDPConfig" + } + }, + "type": "object" + }, + "staticEntryPointsTransport": { + "additionalProperties": false, + "properties": { + "keepAliveMaxRequests": { + "type": "integer" + }, + "keepAliveMaxTime": { + "type": "string" + }, + "lifeCycle": { + "$ref": "#/$defs/staticLifeCycle" + }, + "respondingTimeouts": { + "$ref": "#/$defs/staticRespondingTimeouts" + } + }, + "type": "object" + }, + "staticExperimental": { + "additionalProperties": false, + "properties": { + "abortOnPluginFailure": { + "type": "boolean" + }, + "fastProxy": { + "$ref": "#/$defs/staticFastProxyConfig" + }, + "kubernetesGateway": { + "type": "boolean" + }, + "localPlugins": { + "additionalProperties": { + "$ref": "#/$defs/pluginsLocalDescriptor" + }, + "type": "object" + }, + "otlplogs": { + "type": "boolean" + }, + "plugins": { + "additionalProperties": { + "$ref": "#/$defs/pluginsDescriptor" + }, + "type": "object" + } + }, + "type": "object" + }, + "staticFastProxyConfig": { + "additionalProperties": false, + "properties": { + "debug": { + "type": "boolean" + } + }, + "type": "object" + }, + "staticForwardedHeaders": { + "additionalProperties": false, + "properties": { + "connection": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "insecure": { + "type": "boolean" + }, + "trustedIPs": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + } + }, + "type": "object" + }, + "staticForwardingTimeouts": { + "additionalProperties": false, + "properties": { + "dialTimeout": { + "type": "string" + }, + "idleConnTimeout": { + "type": "string" + }, + "responseHeaderTimeout": { + "type": "string" + } + }, + "type": "object" + }, + "staticGlobal": { + "additionalProperties": false, + "properties": { + "checkNewVersion": { + "type": "boolean" + }, + "sendAnonymousUsage": { + "type": "boolean" + }, + "updaterCallbacks": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "type": "object" + }, + "staticHTTP2Config": { + "additionalProperties": false, + "properties": { + "maxConcurrentStreams": { + "type": "integer" + } + }, + "type": "object" + }, + "staticHTTP3Config": { + "additionalProperties": false, + "properties": { + "advertisedPort": { + "type": "integer" + } + }, + "type": "object" + }, + "staticHTTPConfig": { + "additionalProperties": false, + "properties": { + "encodeQuerySemicolons": { + "type": "boolean" + }, + "maxHeaderBytes": { + "type": "integer" + }, + "middlewares": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "redirections": { + "$ref": "#/$defs/staticRedirections" + }, + "tls": { + "$ref": "#/$defs/staticTLSConfig" + } + }, + "type": "object" + }, + "staticLifeCycle": { + "additionalProperties": false, + "properties": { + "graceTimeOut": { + "type": "string" + }, + "requestAcceptGraceTimeout": { + "type": "string" + } + }, + "type": "object" + }, + "staticObservabilityConfig": { + "additionalProperties": false, + "properties": { + "accessLogs": { + "type": "boolean" + }, + "metrics": { + "type": "boolean" + }, + "tracing": { + "type": "boolean" + } + }, + "type": "object" + }, + "staticProviders": { + "additionalProperties": false, + "properties": { + "consul": { + "$ref": "#/$defs/consulProviderBuilder" + }, + "consulCatalog": { + "$ref": "#/$defs/consulcatalogProviderBuilder" + }, + "docker": { + "$ref": "#/$defs/dockerProvider" + }, + "ecs": { + "$ref": "#/$defs/ecsProvider" + }, + "etcd": { + "$ref": "#/$defs/etcdProvider" + }, + "file": { + "$ref": "#/$defs/fileProvider" + }, + "http": { + "$ref": "#/$defs/httpProvider" + }, + "kubernetesCRD": { + "$ref": "#/$defs/crdProvider" + }, + "kubernetesGateway": { + "$ref": "#/$defs/gatewayProvider" + }, + "kubernetesIngress": { + "$ref": "#/$defs/ingressProvider" + }, + "nomad": { + "$ref": "#/$defs/nomadProviderBuilder" + }, + "plugin": { + "additionalProperties": { + "additionalProperties": {}, + "type": "object" + }, + "type": "object" + }, + "providersThrottleDuration": { + "type": "string" + }, + "redis": { + "$ref": "#/$defs/redisProvider" + }, + "rest": { + "$ref": "#/$defs/restProvider" + }, + "swarm": { + "$ref": "#/$defs/dockerSwarmProvider" + }, + "zooKeeper": { + "$ref": "#/$defs/zkProvider" + } + }, + "type": "object" + }, + "staticProxyProtocol": { + "additionalProperties": false, + "properties": { + "insecure": { + "type": "boolean" + }, + "trustedIPs": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + } + }, + "type": "object" + }, + "staticRedirectEntryPoint": { + "additionalProperties": false, + "properties": { + "permanent": { + "type": "boolean" + }, + "priority": { + "type": "integer" + }, + "scheme": { + "type": "string" + }, + "to": { + "type": "string" + } + }, + "type": "object" + }, + "staticRedirections": { + "additionalProperties": false, + "properties": { + "entryPoint": { + "$ref": "#/$defs/staticRedirectEntryPoint" + } + }, + "type": "object" + }, + "staticRespondingTimeouts": { + "additionalProperties": false, + "properties": { + "idleTimeout": { + "type": "string" + }, + "readTimeout": { + "type": "string" + }, + "writeTimeout": { + "type": "string" + } + }, + "type": "object" + }, + "staticServersTransport": { + "additionalProperties": false, + "properties": { + "forwardingTimeouts": { + "$ref": "#/$defs/staticForwardingTimeouts" + }, + "insecureSkipVerify": { + "type": "boolean" + }, + "maxIdleConnsPerHost": { + "type": "integer" + }, + "rootCAs": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "spiffe": { + "$ref": "#/$defs/staticSpiffe" + } + }, + "type": "object" + }, + "staticSpiffe": { + "additionalProperties": false, + "properties": { + "ids": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "trustDomain": { + "type": "string" + } + }, + "type": "object" + }, + "staticSpiffeClientConfig": { + "additionalProperties": false, + "properties": { + "workloadAPIAddr": { + "type": "string" + } + }, + "type": "object" + }, + "staticTCPServersTransport": { + "additionalProperties": false, + "properties": { + "dialKeepAlive": { + "type": "string" + }, + "dialTimeout": { + "type": "string" + }, + "terminationDelay": { + "type": "string" + }, + "tls": { + "$ref": "#/$defs/staticTLSClientConfig" + } + }, + "type": "object" + }, + "staticTLSClientConfig": { + "additionalProperties": false, + "properties": { + "insecureSkipVerify": { + "type": "boolean" + }, + "rootCAs": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "spiffe": { + "$ref": "#/$defs/staticSpiffe" + } + }, + "type": "object" + }, + "staticTLSConfig": { + "additionalProperties": false, + "properties": { + "certResolver": { + "type": "string" + }, + "domains": { + "items": { + "$ref": "#/$defs/typesDomain" + }, + "type": ["array", "null"] + }, + "options": { + "type": "string" + } + }, + "type": "object" + }, + "staticTracing": { + "additionalProperties": false, + "properties": { + "addInternals": { + "type": "boolean" + }, + "capturedRequestHeaders": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "capturedResponseHeaders": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "globalAttributes": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "otlp": { + "$ref": "#/$defs/typesOTelTracing" + }, + "resourceAttributes": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "safeQueryParams": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "sampleRate": { + "type": "number" + }, + "serviceName": { + "type": "string" + } + }, + "type": "object" + }, + "staticUDPConfig": { + "additionalProperties": false, + "properties": { + "timeout": { + "type": "string" + } + }, + "type": "object" + }, + "typesAccessLog": { + "additionalProperties": false, + "properties": { + "addInternals": { + "type": "boolean" + }, + "bufferingSize": { + "type": "integer" + }, + "fields": { + "$ref": "#/$defs/typesAccessLogFields" + }, + "filePath": { + "type": "string" + }, + "filters": { + "$ref": "#/$defs/typesAccessLogFilters" + }, + "format": { + "type": "string" + }, + "otlp": { + "$ref": "#/$defs/typesOTelLog" + } + }, + "type": "object" + }, + "typesAccessLogFields": { + "additionalProperties": false, + "properties": { + "defaultMode": { + "type": "string" + }, + "headers": { + "$ref": "#/$defs/typesFieldHeaders" + }, + "names": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "typesAccessLogFilters": { + "additionalProperties": false, + "properties": { + "minDuration": { + "type": "string" + }, + "retryAttempts": { + "type": "boolean" + }, + "statusCodes": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + } + }, + "type": "object" + }, + "typesClientTLS": { + "additionalProperties": false, + "properties": { + "ca": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "insecureSkipVerify": { + "type": "boolean" + }, + "key": { + "type": "string" + } + }, + "type": "object" + }, + "typesDatadog": { + "additionalProperties": false, + "properties": { + "addEntryPointsLabels": { + "type": "boolean" + }, + "addRoutersLabels": { + "type": "boolean" + }, + "addServicesLabels": { + "type": "boolean" + }, + "address": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "pushInterval": { + "type": "string" + } + }, + "type": "object" + }, + "typesDomain": { + "additionalProperties": false, + "properties": { + "main": { + "type": "string" + }, + "sans": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + } + }, + "type": "object" + }, + "typesFieldHeaders": { + "additionalProperties": false, + "properties": { + "defaultMode": { + "type": "string" + }, + "names": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "typesHostResolverConfig": { + "additionalProperties": false, + "properties": { + "cnameFlattening": { + "type": "boolean" + }, + "resolvConfig": { + "type": "string" + }, + "resolvDepth": { + "type": "integer" + } + }, + "type": "object" + }, + "typesInfluxDB2": { + "additionalProperties": false, + "properties": { + "addEntryPointsLabels": { + "type": "boolean" + }, + "addRoutersLabels": { + "type": "boolean" + }, + "addServicesLabels": { + "type": "boolean" + }, + "additionalLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "address": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "org": { + "type": "string" + }, + "pushInterval": { + "type": "string" + }, + "token": { + "type": "string" + } + }, + "type": "object" + }, + "typesMetrics": { + "additionalProperties": false, + "properties": { + "addInternals": { + "type": "boolean" + }, + "datadog": { + "$ref": "#/$defs/typesDatadog" + }, + "influxDB2": { + "$ref": "#/$defs/typesInfluxDB2" + }, + "otlp": { + "$ref": "#/$defs/typesOTLP" + }, + "prometheus": { + "$ref": "#/$defs/typesPrometheus" + }, + "statsD": { + "$ref": "#/$defs/typesStatsd" + } + }, + "type": "object" + }, + "typesOTLP": { + "additionalProperties": false, + "properties": { + "addEntryPointsLabels": { + "type": "boolean" + }, + "addRoutersLabels": { + "type": "boolean" + }, + "addServicesLabels": { + "type": "boolean" + }, + "explicitBoundaries": { + "items": { + "type": "number" + }, + "type": ["array", "null"] + }, + "grpc": { + "$ref": "#/$defs/typesOTelGRPC" + }, + "http": { + "$ref": "#/$defs/typesOTelHTTP" + }, + "pushInterval": { + "type": "string" + }, + "serviceName": { + "type": "string" + } + }, + "type": "object" + }, + "typesOTelGRPC": { + "additionalProperties": false, + "properties": { + "endpoint": { + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "insecure": { + "type": "boolean" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + } + }, + "type": "object" + }, + "typesOTelHTTP": { + "additionalProperties": false, + "properties": { + "endpoint": { + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "tls": { + "$ref": "#/$defs/typesClientTLS" + } + }, + "type": "object" + }, + "typesOTelLog": { + "additionalProperties": false, + "properties": { + "grpc": { + "$ref": "#/$defs/typesOTelGRPC" + }, + "http": { + "$ref": "#/$defs/typesOTelHTTP" + }, + "resourceAttributes": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "serviceName": { + "type": "string" + } + }, + "type": "object" + }, + "typesOTelTracing": { + "additionalProperties": false, + "properties": { + "grpc": { + "$ref": "#/$defs/typesOTelGRPC" + }, + "http": { + "$ref": "#/$defs/typesOTelHTTP" + } + }, + "type": "object" + }, + "typesPrometheus": { + "additionalProperties": false, + "properties": { + "addEntryPointsLabels": { + "type": "boolean" + }, + "addRoutersLabels": { + "type": "boolean" + }, + "addServicesLabels": { + "type": "boolean" + }, + "buckets": { + "items": { + "type": "number" + }, + "type": ["array", "null"] + }, + "entryPoint": { + "type": "string" + }, + "headerLabels": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "manualRouting": { + "type": "boolean" + } + }, + "type": "object" + }, + "typesStatsd": { + "additionalProperties": false, + "properties": { + "addEntryPointsLabels": { + "type": "boolean" + }, + "addRoutersLabels": { + "type": "boolean" + }, + "addServicesLabels": { + "type": "boolean" + }, + "address": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "pushInterval": { + "type": "string" + } + }, + "type": "object" + }, + "typesTraefikLog": { + "additionalProperties": false, + "properties": { + "compress": { + "type": "boolean" + }, + "filePath": { + "type": "string" + }, + "format": { + "type": "string" + }, + "level": { + "type": "string" + }, + "maxAge": { + "type": "integer" + }, + "maxBackups": { + "type": "integer" + }, + "maxSize": { + "type": "integer" + }, + "noColor": { + "type": "boolean" + }, + "otlp": { + "$ref": "#/$defs/typesOTelLog" + } + }, + "type": "object" + }, + "zkProvider": { + "additionalProperties": false, + "properties": { + "endpoints": { + "items": { + "type": "string" + }, + "type": ["array", "null"] + }, + "password": { + "type": "string" + }, + "rootKey": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "type": "object" + } + }, + "title": "Traefik v3 Static Configuration", + "properties": { + "accessLog": { + "$ref": "#/$defs/typesAccessLog" + }, + "api": { + "$ref": "#/$defs/staticAPI" + }, + "certificatesResolvers": { + "additionalProperties": { + "$ref": "#/$defs/staticCertificateResolver" + }, + "type": "object" + }, + "core": { + "$ref": "#/$defs/staticCore" + }, + "entryPoints": { + "additionalProperties": { + "$ref": "#/$defs/staticEntryPoint" + }, + "type": "object" + }, + "experimental": { + "$ref": "#/$defs/staticExperimental" + }, + "global": { + "$ref": "#/$defs/staticGlobal" + }, + "hostResolver": { + "$ref": "#/$defs/typesHostResolverConfig" + }, + "log": { + "$ref": "#/$defs/typesTraefikLog" + }, + "metrics": { + "$ref": "#/$defs/typesMetrics" + }, + "ping": { + "$ref": "#/$defs/pingHandler" + }, + "providers": { + "$ref": "#/$defs/staticProviders" + }, + "serversTransport": { + "$ref": "#/$defs/staticServersTransport" + }, + "spiffe": { + "$ref": "#/$defs/staticSpiffeClientConfig" + }, + "tcpServersTransport": { + "$ref": "#/$defs/staticTCPServersTransport" + }, + "tracing": { + "$ref": "#/$defs/staticTracing" + } + }, + "type": "object" +} diff --git a/traefik.sample.toml b/traefik.sample.toml deleted file mode 100644 index 7cf8ed2bf..000000000 --- a/traefik.sample.toml +++ /dev/null @@ -1,152 +0,0 @@ -################################################################ -# -# Configuration sample for Traefik v2. -# -# For Traefik v1: https://github.com/traefik/traefik/blob/v1.7/traefik.sample.toml -# -################################################################ - -################################################################ -# Global configuration -################################################################ -[global] - checkNewVersion = true - sendAnonymousUsage = true - -################################################################ -# Entrypoints configuration -################################################################ - -# Entrypoints definition -# -# Optional -# Default: -[entryPoints] - [entryPoints.web] - address = ":80" - - [entryPoints.websecure] - address = ":443" - -################################################################ -# Traefik logs configuration -################################################################ - -# Traefik logs -# Enabled by default and log to stdout -# -# Optional -# -[log] - - # Log level - # - # Optional - # Default: "ERROR" - # - # level = "DEBUG" - - # Sets the filepath for the traefik log. If not specified, stdout will be used. - # Intermediate directories are created if necessary. - # - # Optional - # Default: os.Stdout - # - # filePath = "log/traefik.log" - - # Format is either "json" or "common". - # - # Optional - # Default: "common" - # - # format = "json" - -################################################################ -# Access logs configuration -################################################################ - -# Enable access logs -# By default it will write to stdout and produce logs in the textual -# Common Log Format (CLF), extended with additional fields. -# -# Optional -# -# [accessLog] - - # Sets the file path for the access log. If not specified, stdout will be used. - # Intermediate directories are created if necessary. - # - # Optional - # Default: os.Stdout - # - # filePath = "/path/to/log/log.txt" - - # Format is either "json" or "common". - # - # Optional - # Default: "common" - # - # format = "json" - -################################################################ -# API and dashboard configuration -################################################################ - -# Enable API and dashboard -[api] - - # Enable the API in insecure mode - # - # Optional - # Default: false - # - # insecure = true - - # Enabled Dashboard - # - # Optional - # Default: true - # - # dashboard = false - -################################################################ -# Ping configuration -################################################################ - -# Enable ping -[ping] - - # Name of the related entry point - # - # Optional - # Default: "traefik" - # - # entryPoint = "traefik" - -################################################################ -# Docker configuration backend -################################################################ - -# Enable Docker configuration backend -[providers.docker] - - # Docker server endpoint. Can be a tcp or a unix socket endpoint. - # - # Required - # Default: "unix:///var/run/docker.sock" - # - # endpoint = "tcp://10.10.10.10:2375" - - # Default host rule. - # - # Optional - # Default: "Host(`{{ normalize .Name }}`)" - # - # defaultRule = "Host(`{{ normalize .Name }}.docker.localhost`)" - - # Expose containers by default in traefik - # - # Optional - # Default: true - # - # exposedByDefault = false diff --git a/traefik.sample.yml b/traefik.sample.yml deleted file mode 100644 index c13ebcd42..000000000 --- a/traefik.sample.yml +++ /dev/null @@ -1,151 +0,0 @@ -################################################################ -# -# Configuration sample for Traefik v2. -# -# For Traefik v1: https://github.com/traefik/traefik/blob/v1.7/traefik.sample.toml -# -################################################################ - -################################################################ -# Global configuration -################################################################ -global: - checkNewVersion: true - sendAnonymousUsage: true - -################################################################ -# EntryPoints configuration -################################################################ - -# EntryPoints definition -# -# Optional -# -entryPoints: - web: - address: :80 - - websecure: - address: :443 - -################################################################ -# Traefik logs configuration -################################################################ - -# Traefik logs -# Enabled by default and log to stdout -# -# Optional -# -#log: - # Log level - # - # Optional - # Default: "ERROR" - # -# level: DEBUG - - # Sets the filepath for the traefik log. If not specified, stdout will be used. - # Intermediate directories are created if necessary. - # - # Optional - # Default: os.Stdout - # -# filePath: log/traefik.log - - # Format is either "json" or "common". - # - # Optional - # Default: "common" - # -# format: json - -################################################################ -# Access logs configuration -################################################################ - -# Enable access logs -# By default it will write to stdout and produce logs in the textual -# Common Log Format (CLF), extended with additional fields. -# -# Optional -# -#accessLog: - # Sets the file path for the access log. If not specified, stdout will be used. - # Intermediate directories are created if necessary. - # - # Optional - # Default: os.Stdout - # -# filePath: /path/to/log/log.txt - - # Format is either "json" or "common". - # - # Optional - # Default: "common" - # -# format: json - -################################################################ -# API and dashboard configuration -################################################################ - -# Enable API and dashboard -# -# Optional -# -#api: - # Enable the API in insecure mode - # - # Optional - # Default: false - # -# insecure: true - - # Enabled Dashboard - # - # Optional - # Default: true - # -# dashboard: false - -################################################################ -# Ping configuration -################################################################ - -# Enable ping -#ping: - # Name of the related entry point - # - # Optional - # Default: "traefik" - # -# entryPoint: traefik - -################################################################ -# Docker configuration backend -################################################################ - -#providers: - # Enable Docker configuration backend -# docker: - # Docker server endpoint. Can be a tcp or a unix socket endpoint. - # - # Required - # Default: "unix:///var/run/docker.sock" - # -# endpoint: tcp://10.10.10.10:2375 - - # Default host rule. - # - # Optional - # Default: "Host(`{{ normalize .Name }}`)" - # -# defaultRule: Host(`{{ normalize .Name }}.docker.localhost`) - - # Expose containers by default in traefik - # - # Optional - # Default: true - # -# exposedByDefault: false diff --git a/traefik.yml b/traefik.yml new file mode 100644 index 000000000..7201c446e --- /dev/null +++ b/traefik.yml @@ -0,0 +1,54 @@ +api: + dashboard: true + +global: + updaterCallbacks: [http://127.0.0.1:56714/callback] + +providers: + docker: + constraints: '!Label(`traefik.host`, ``)' + defaultRule: Host(`{{ index .Labels "traefik.host" }}.wzray.com`) + exposedByDefault: true + allowEmptyServices: true + +certificatesResolvers: + cloudflare: + acme: + email: security@wzray.com + storage: /etc/certs/acme.json + caServer: https://acme-v02.api.letsencrypt.org/directory + dnsChallenge: + provider: cloudflare + +entryPoints: + https: + address: ':443' + asDefault: true + http: + tls: + certResolver: cloudflare + domains: + - main: wzray.com + sans: ['*.wzray.com'] + + ehttps: + address: ':8443' + proxyProtocol: + trustedIPs: + - 0.0.0.0/0 + http: + tls: + certResolver: cloudflare + domains: + - main: wzray.com + sans: ['*.wzray.com'] + + http: + address: ':80' + http: + redirections: + entryPoint: + to: https + scheme: https + +# yaml-language-server: $schema=schema.json