diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7a4d8c996..6b9ddb2dc 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,7 +8,7 @@ on: env: GO_VERSION: 1.17 CGO_ENABLED: 0 - PRE_TARGET: "" + IN_DOCKER: "" jobs: diff --git a/.github/workflows/test-unit.yaml b/.github/workflows/test-unit.yaml index 3502c2a92..b1bd61acd 100644 --- a/.github/workflows/test-unit.yaml +++ b/.github/workflows/test-unit.yaml @@ -7,7 +7,7 @@ on: env: GO_VERSION: 1.17 - PRE_TARGET: "" + IN_DOCKER: "" jobs: diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index d6b637642..16aa12d6a 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -9,7 +9,7 @@ env: GO_VERSION: 1.17 GOLANGCI_LINT_VERSION: v1.44.0 MISSSPELL_VERSION: v0.3.4 - PRE_TARGET: "" + IN_DOCKER: "" jobs: diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index a77104b2b..981c0a90d 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -41,7 +41,7 @@ blocks: commands: - make pull-images - touch webui/static/index.html # Avoid generating webui - - PRE_TARGET="" make binary + - IN_DOCKER="" make binary - make test-integration - df -h epilogue: @@ -65,7 +65,7 @@ blocks: value: 1.12.1 - name: CODENAME value: "rocamadour" - - name: PRE_TARGET + - name: IN_DOCKER value: "" prologue: commands: diff --git a/Makefile b/Makefile index df3a5013b..ee12b26e1 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,6 @@ SHA := $(shell git rev-parse HEAD) VERSION_GIT := $(if $(TAG_NAME),$(TAG_NAME),$(SHA)) VERSION := $(if $(VERSION),$(VERSION),$(VERSION_GIT)) -BIND_DIR := dist - GIT_BRANCH := $(subst heads/,,$(shell git rev-parse --abbrev-ref HEAD 2>/dev/null)) TRAEFIK_DEV_IMAGE := traefik-dev$(if $(GIT_BRANCH),:$(subst /,-,$(GIT_BRANCH))) @@ -29,14 +27,14 @@ TRAEFIK_ENVS := \ -e CI \ -e CONTAINER=DOCKER # Indicator for integration tests that we are running inside a container. -TRAEFIK_MOUNT := -v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/traefik/traefik/$(BIND_DIR)" +TRAEFIK_MOUNT := -v "$(CURDIR)/dist:/go/src/github.com/traefik/traefik/dist" DOCKER_RUN_OPTS := $(TRAEFIK_ENVS) $(TRAEFIK_MOUNT) "$(TRAEFIK_DEV_IMAGE)" DOCKER_NON_INTERACTIVE ?= false DOCKER_RUN_TRAEFIK := docker run $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -it) $(DOCKER_RUN_OPTS) DOCKER_RUN_TRAEFIK_TEST := docker run --add-host=host.docker.internal:127.0.0.1 --rm --name=traefik --network traefik-test-network -v $(PWD):$(PWD) -w $(PWD) $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -it) $(DOCKER_RUN_OPTS) DOCKER_RUN_TRAEFIK_NOTTY := docker run $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -i) $(DOCKER_RUN_OPTS) -PRE_TARGET ?= build-dev-image +IN_DOCKER ?= true PLATFORM_URL := $(if $(PLATFORM_URL),$(PLATFORM_URL),"https://pilot.traefik.io") @@ -44,7 +42,7 @@ default: binary ## Build Dev Docker image build-dev-image: dist - docker build $(DOCKER_BUILD_ARGS) -t "$(TRAEFIK_DEV_IMAGE)" -f build.Dockerfile . + $(if $(IN_DOCKER),docker build $(DOCKER_BUILD_ARGS) -t "$(TRAEFIK_DEV_IMAGE)" -f build.Dockerfile .,) ## Build Dev Docker image without cache build-dev-image-no-cache: dist @@ -52,7 +50,7 @@ build-dev-image-no-cache: dist ## Create the "dist" directory dist: - mkdir dist + mkdir -p dist ## Build WebUI Docker image build-webui-image: @@ -65,16 +63,20 @@ clean-webui: echo 'For more information show `webui/readme.md`' > webui/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md ## Generate WebUI -generate-webui: - if [ ! -f "webui/static/index.html" ]; then \ - $(MAKE) build-webui-image; \ - docker run --rm -v "$$PWD/webui/static":'/src/webui/static' traefik-webui yarn build:nc; \ - docker run --rm -v "$$PWD/webui/static":'/src/webui/static' traefik-webui chown -R $(shell id -u):$(shell id -g) ./static; \ - fi +webui/static/index.html: + $(MAKE) build-webui-image + docker run --rm -v "$$PWD/webui/static":'/src/webui/static' traefik-webui yarn build:nc + docker run --rm -v "$$PWD/webui/static":'/src/webui/static' traefik-webui chown -R $(shell id -u):$(shell id -g) ./static -## Build the linux binary -binary: generate-webui $(PRE_TARGET) - $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate binary +generate-webui: webui/static/index.html + +## Build the binary +binary: generate-webui build-dev-image + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate binary + +## Build the linux binary locally +binary-debug: generate-webui + GOOS=linux ./script/make.sh binary ## Build the binary for the standard platforms (linux, darwin, windows) crossbinary-default: generate-webui build-dev-image @@ -86,35 +88,35 @@ crossbinary-default-parallel: $(MAKE) build-dev-image crossbinary-default ## Run the unit and integration tests -test: $(PRE_TARGET) +test: build-dev-image -docker network create traefik-test-network --driver bridge --subnet 172.31.42.0/24 trap 'docker network rm traefik-test-network' EXIT; \ - $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK_TEST),) ./script/make.sh generate test-unit binary test-integration + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK_TEST),) ./script/make.sh generate test-unit binary test-integration ## Run the unit tests -test-unit: $(PRE_TARGET) +test-unit: build-dev-image -docker network create traefik-test-network --driver bridge --subnet 172.31.42.0/24 trap 'docker network rm traefik-test-network' EXIT; \ - $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK_TEST)) ./script/make.sh generate test-unit + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK_TEST)) ./script/make.sh generate test-unit ## Run the integration tests -test-integration: $(PRE_TARGET) +test-integration: build-dev-image -docker network create traefik-test-network --driver bridge --subnet 172.31.42.0/24 trap 'docker network rm traefik-test-network' EXIT; \ - $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK_TEST),) ./script/make.sh generate binary test-integration + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK_TEST),) ./script/make.sh generate binary test-integration ## Pull all images for integration tests pull-images: grep --no-filename -E '^\s+image:' ./integration/resources/compose/*.yml | awk '{print $$2}' | sort | uniq | xargs -P 6 -n 1 docker pull ## Validate code and docs -validate-files: $(PRE_TARGET) - $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell +validate-files: build-dev-image + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell bash $(CURDIR)/script/validate-shell-script.sh ## Validate code, docs, and vendor -validate: $(PRE_TARGET) - $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell validate-vendor +validate: build-dev-image + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell validate-vendor bash $(CURDIR)/script/validate-shell-script.sh ## Clean up static directory and build a Docker Traefik image @@ -125,6 +127,10 @@ build-image: clean-webui binary build-image-dirty: binary docker build -t $(TRAEFIK_IMAGE) . +## Locally build traefik for linux, then shove it an alpine image, with basic tools. +build-image-debug: binary-debug + docker build -t $(TRAEFIK_IMAGE) -f debug.Dockerfile . + ## Start a shell inside the build env shell: build-dev-image $(DOCKER_RUN_TRAEFIK) /bin/bash @@ -150,17 +156,17 @@ generate-genconf: go run ./cmd/internal/gen/ ## Create packages for the release -release-packages: generate-webui $(PRE_TARGET) +release-packages: generate-webui build-dev-image rm -rf dist - $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK_NOTTY)) goreleaser release --skip-publish --timeout="90m" - $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK_NOTTY)) tar cfz dist/traefik-${VERSION}.src.tar.gz \ + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK_NOTTY)) goreleaser release --skip-publish --timeout="90m" + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK_NOTTY)) tar cfz dist/traefik-${VERSION}.src.tar.gz \ --exclude-vcs \ --exclude .idea \ --exclude .travis \ --exclude .semaphoreci \ --exclude .github \ --exclude dist . - $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK_NOTTY)) chown -R $(shell id -u):$(shell id -g) dist/ + $(if $(IN_DOCKER),$(DOCKER_RUN_TRAEFIK_NOTTY)) chown -R $(shell id -u):$(shell id -g) dist/ ## Format the Code fmt: diff --git a/build.Dockerfile b/build.Dockerfile index 3025a75e9..e86cd0c2a 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -1,7 +1,6 @@ FROM golang:1.17-alpine -RUN apk --update upgrade \ - && apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ +RUN apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ && update-ca-certificates \ && rm -rf /var/cache/apk/* @@ -17,7 +16,7 @@ RUN mkdir -p /usr/local/bin \ RUN curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b $GOPATH/bin v1.44.0 # Download misspell binary to bin folder in $GOPATH -RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4 +RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4 # Download goreleaser binary to bin folder in $GOPATH RUN curl -sfL https://gist.githubusercontent.com/traefiker/6d7ac019c11d011e4f131bb2cca8900e/raw/goreleaser.sh | sh diff --git a/debug.Dockerfile b/debug.Dockerfile new file mode 100644 index 000000000..4dcf88bf8 --- /dev/null +++ b/debug.Dockerfile @@ -0,0 +1,10 @@ +FROM alpine:3.14 +# Feel free to add below any helpful dependency for debugging. +# iproute2 is for ss. +RUN apk --no-cache --no-progress add bash curl ca-certificates tzdata lsof iproute2 \ + && update-ca-certificates \ + && rm -rf /var/cache/apk/* +COPY dist/traefik / +EXPOSE 80 +VOLUME ["/tmp"] +ENTRYPOINT ["/traefik"] diff --git a/docs/content/contributing/building-testing.md b/docs/content/contributing/building-testing.md index 9c96ae784..0a3a9bdce 100644 --- a/docs/content/contributing/building-testing.md +++ b/docs/content/contributing/building-testing.md @@ -45,7 +45,7 @@ $ ls dist/ traefik* ``` -The following targets can be executed outside Docker by setting the variable `PRE_TARGET` to an empty string (we don't recommend that): +The following targets can be executed outside Docker by setting the variable `IN_DOCKER` to an empty string (although be aware that some of the tests might fail in that context): - `test-unit` - `test-integration` @@ -55,7 +55,7 @@ The following targets can be executed outside Docker by setting the variable `PR ex: ```bash -PRE_TARGET= make test-unit +IN_DOCKER= make test-unit ``` ### Method 2: Using `go` diff --git a/docs/content/getting-started/configuration-overview.md b/docs/content/getting-started/configuration-overview.md index 6d674b770..a44c9a396 100644 --- a/docs/content/getting-started/configuration-overview.md +++ b/docs/content/getting-started/configuration-overview.md @@ -51,7 +51,7 @@ Once positioned, this option sets (and resets) all the default values of the sub ### Configuration File -At startup, Traefik searches for a file named `traefik.yml` (or `traefik.yaml` or `traefik.toml`) in: +At startup, Traefik searches for static configuration in a file named `traefik.yml` (or `traefik.yaml` or `traefik.toml`) in: - `/etc/traefik/` - `$XDG_CONFIG_HOME/` diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index cff442cab..612bd78bd 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -143,11 +143,11 @@ The TLS options allow one to configure some parameters of the TLS connection. you must specify the provider namespace, for example: `traefik.http.routers.myrouter.tls.options=myoptions@file` -!!! important "TLSOptions in Kubernetes" +!!! important "TLSOption in Kubernetes" - When using the TLSOptions-CRD in Kubernetes, one might setup a default set of options that, + When using the [TLSOption resource](../../routing/providers/kubernetes-crd#kind-tlsoption) in Kubernetes, one might setup a default set of options that, if not explicitly overwritten, should apply to all ingresses. - To achieve that, you'll have to create a TLSOptions CR with the name `default`. + To achieve that, you'll have to create a TLSOption resource with the name `default`. There may exist only one TLSOption with the name `default` (across all namespaces) - otherwise they will be dropped. To explicitly use a different TLSOption (and using the Kubernetes Ingress resources) you'll have to add an annotation to the Ingress in the following form: diff --git a/docs/content/providers/docker.md b/docs/content/providers/docker.md index 357812a58..c659af73f 100644 --- a/docs/content/providers/docker.md +++ b/docs/content/providers/docker.md @@ -550,11 +550,11 @@ providers: _Optional, Default=""_ -The `constraints` option can be set to an expression that Traefik matches against the container tags to determine whether -to create any route for that container. If none of the container tags match the expression, no route for that container is +The `constraints` option can be set to an expression that Traefik matches against the container labels to determine whether +to create any route for that container. If none of the container labels match the expression, no route for that container is created. If the expression is empty, all detected containers are included. -The expression syntax is based on the ```Tag(`tag`)```, and ```TagRegex(`tag`)``` functions, +The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as the usual boolean logic, as shown in examples below. ??? example "Constraints Expression Examples" diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index 75fdee127..0eb1552b7 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -1485,39 +1485,40 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre apiVersion: traefik.containo.us/v1alpha1 kind: TLSOption metadata: - name: mytlsoption + name: mytlsoption # [1] namespace: default spec: - minVersion: VersionTLS12 # [1] - maxVersion: VersionTLS13 # [1] - curvePreferences: # [3] + minVersion: VersionTLS12 # [2] + maxVersion: VersionTLS13 # [3] + curvePreferences: # [4] - CurveP521 - CurveP384 - cipherSuites: # [4] + cipherSuites: # [5] - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_RSA_WITH_AES_256_GCM_SHA384 - clientAuth: # [5] - secretNames: # [6] + clientAuth: # [6] + secretNames: # [7] - secret-ca1 - secret-ca2 - clientAuthType: VerifyClientCertIfGiven # [7] - sniStrict: true # [8] - alpnProtocols: # [9] + clientAuthType: VerifyClientCertIfGiven # [8] + sniStrict: true # [9] + alpnProtocols: # [10] - foobar ``` -| Ref | Attribute | Purpose | -|-----|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [1] | `minVersion` | Defines the [minimum TLS version](../../https/tls.md#minimum-tls-version) that is acceptable | -| [2] | `maxVersion` | Defines the [maximum TLS version](../../https/tls.md#maximum-tls-version) that is acceptable | -| [3] | `cipherSuites` | list of supported [cipher suites](../../https/tls.md#cipher-suites) for TLS versions up to TLS 1.2 | -| [4] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake, in preference order | -| [5] | `clientAuth` | determines the server's policy for TLS [Client Authentication](../../https/tls.md#client-authentication-mtls) | -| [6] | `clientAuth.secretNames` | list of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace). The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. | -| [7] | `clientAuth.clientAuthType` | defines the client authentication type to apply. The available values are: `NoClientCert`, `RequestClientCert`, `VerifyClientCertIfGiven` and `RequireAndVerifyClientCert` | -| [8] | `sniStrict` | if `true`, Traefik won't allow connections from clients connections that do not specify a server_name extension | -| [9] | `alpnProtocols` | List of supported [application level protocols](../../https/tls.md#alpn-protocols) for the TLS handshake, in order of preference. | +| Ref | Attribute | Purpose | +|------|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [1] | `name` | Defines the name of the TLSOption resource. One can use `default` as name to redefine the [default TLSOption](../../https/tls.md#tls-options). | +| [2] | `minVersion` | Defines the [minimum TLS version](../../https/tls.md#minimum-tls-version) that is acceptable. | +| [3] | `maxVersion` | Defines the [maximum TLS version](../../https/tls.md#maximum-tls-version) that is acceptable. | +| [4] | `cipherSuites` | list of supported [cipher suites](../../https/tls.md#cipher-suites) for TLS versions up to TLS 1.2. | +| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake, in preference order. | +| [6] | `clientAuth` | determines the server's policy for TLS [Client Authentication](../../https/tls.md#client-authentication-mtls). | +| [7] | `clientAuth.secretNames` | list of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace). The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. | +| [8] | `clientAuth.clientAuthType` | defines the client authentication type to apply. The available values are: `NoClientCert`, `RequestClientCert`, `VerifyClientCertIfGiven` and `RequireAndVerifyClientCert`. | +| [9] | `sniStrict` | if `true`, Traefik won't allow connections from clients connections that do not specify a server_name extension. | +| [10] | `alpnProtocols` | List of supported [application level protocols](../../https/tls.md#alpn-protocols) for the TLS handshake, in order of preference. | !!! info "CA Secret" diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index fdfc0f6f2..4abc03a06 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -292,7 +292,7 @@ A value of `0` for the priority is ignored: `priority = 0` means that the defaul http: routers: Router-1: - rule: "HostRegexp(`.*\.traefik\.com`)" + rule: "HostRegexp(`{subdomain:[a-z]+}.traefik.com`)" # ... Router-2: rule: "Host(`foobar.traefik.com`)" @@ -303,7 +303,7 @@ A value of `0` for the priority is ignored: `priority = 0` means that the defaul ## Dynamic configuration [http.routers] [http.routers.Router-1] - rule = "HostRegexp(`.*\.traefik\.com`)" + rule = "HostRegexp(`{subdomain:[a-z]+}.traefik.com`)" # ... [http.routers.Router-2] rule = "Host(`foobar.traefik.com`)" @@ -312,10 +312,10 @@ A value of `0` for the priority is ignored: `priority = 0` means that the defaul In this case, all requests with host `foobar.traefik.com` will be routed through `Router-1` instead of `Router-2`. - | Name | Rule | Priority | - |----------|--------------------------------------|----------| - | Router-1 | ```HostRegexp(`.*\.traefik\.com`)``` | 30 | - | Router-2 | ```Host(`foobar.traefik.com`)``` | 26 | + | Name | Rule | Priority | + |----------|----------------------------------------------------|----------| + | Router-1 | ```HostRegexp(`{subdomain:[a-z]+}.traefik.com`)``` | 44 | + | Router-2 | ```Host(`foobar.traefik.com`)``` | 26 | The previous table shows that `Router-1` has a higher priority than `Router-2`. @@ -328,7 +328,7 @@ A value of `0` for the priority is ignored: `priority = 0` means that the defaul http: routers: Router-1: - rule: "HostRegexp(`.*\.traefik\.com`)" + rule: "HostRegexp(`{subdomain:[a-z]+}.traefik.com`)" entryPoints: - "web" service: service-1 @@ -345,7 +345,7 @@ A value of `0` for the priority is ignored: `priority = 0` means that the defaul ## Dynamic configuration [http.routers] [http.routers.Router-1] - rule = "HostRegexp(`.*\.traefik\.com`)" + rule = "HostRegexp(`{subdomain:[a-z]+}.traefik.com`)" entryPoints = ["web"] service = "service-1" priority = 1 diff --git a/exp.Dockerfile b/exp.Dockerfile index 50d0dc0a9..9e8a90271 100644 --- a/exp.Dockerfile +++ b/exp.Dockerfile @@ -14,8 +14,7 @@ RUN yarn build # BUILD FROM golang:1.17-alpine as gobuild -RUN apk --update upgrade \ - && apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ +RUN apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ && update-ca-certificates \ && rm -rf /var/cache/apk/*