1
0
mirror of https://github.com/containous/traefik.git synced 2025-10-04 05:44:22 +03:00

Compare commits

..

93 Commits

Author SHA1 Message Date
Ludovic Fernandez
ae9342208e Prepare release v1.5.0 2018-01-23 17:34:04 +01:00
Michael
3040d9df0d Build cross binary only on tags in travis 2018-01-23 17:00:06 +01:00
Ludovic Fernandez
00e0571811 Rename TLSConfigurations to TLS. 2018-01-23 16:30:07 +01:00
Ludovic Fernandez
bfb07746fe Deploy pages on all branches. 2018-01-23 14:48:04 +01:00
Ludovic Fernandez
171cda6186 New multi version documentation mechanism 2018-01-23 14:18:03 +01:00
Timo Reimann
4cc17e112f Fix goroutine leak in throttler logic. 2018-01-23 12:44:03 +01:00
Ludovic Fernandez
b6af61fa6e ACME and corporate proxy. 2018-01-23 09:52:03 +01:00
Emile Vauge
4e07d92190 Fix doc dynamic certificates 2018-01-23 09:12:03 +01:00
Roman Pridybailo
fc00e1c228 Don't reload configuration when rancher server is down 2018-01-22 11:00:07 +01:00
Eldon
ae34486b57 Fix some doc links 2018-01-22 10:26:03 +01:00
SALLEYRON Julien
d7b513e9aa Disable websocket compression 2018-01-19 17:34:03 +01:00
SALLEYRON Julien
d8297a055a Fix breaking change in web metrics 2018-01-19 14:30:04 +01:00
SALLEYRON Julien
ced5aa5dc6 Challenge HTTP must ignore deprecated web.path option 2018-01-17 18:46:03 +01:00
Martijn Heemels
adfa3f795c Fix typo in anonymous usage log message. 2018-01-17 12:20:04 +01:00
Michael
fe426f6fb2 Prepare release v1.5.0-rc5 2018-01-15 16:48:03 +01:00
SALLEYRON Julien
3e439cc39b Add Let's Encrypt HTTP Challenge 2018-01-15 16:04:05 +01:00
Blake Mesdag
56c0634918 Return errors from Docker client.Events 2018-01-15 14:26:03 +01:00
Tristan Colgate-McFarlane
bcadd68904 Fix data races. 2018-01-15 11:46:04 +01:00
Timo Reimann
9790aa91fe Apply various contentual and stylish improvements to the k8s docs. 2018-01-15 09:40:05 +01:00
Michael
5316b412d2 Fix concurrent map writes on digest auth 2018-01-12 20:00:05 +01:00
SALLEYRON Julien
b5ee5c34f2 Add compression and better error handling 2018-01-12 17:52:03 +01:00
Ludovic Fernandez
8239e04a19 fix: typo in Docker template. 2018-01-11 15:20:06 +01:00
SALLEYRON Julien
e2c5f3712f Fix redirect problem on dashboard + docs/tests on [web] 2018-01-11 09:46:03 +01:00
NicoMen
d0f3ad6024 Modify DEBUG messages to get ACME certificates 2018-01-10 15:20:03 +01:00
Ludovic Fernandez
044d87d96d Switch to golang/dep. 2018-01-09 21:46:04 +01:00
Ludovic Fernandez
d88554fa92 fix: list entries parsing. 2018-01-09 12:40:04 +01:00
Timo Reimann
e74a20de24 Document rewrite-target annotation. 2018-01-09 11:56:02 +01:00
Ludovic Fernandez
7c227392fa fix: glide files. 2018-01-09 11:24:03 +01:00
Ludovic Fernandez
8a697f7a39 Fix: timeout integration test 2018-01-09 10:08:03 +01:00
Julien Maitrehenry
60fd26e0b7 Add a clustering example with Docker Swarm 2018-01-07 15:54:03 +01:00
SALLEYRON Julien
acd0c1bcd5 GzipResponse must implement CloseNotifier if ResponseWriter implement it 2018-01-05 02:26:03 +01:00
SALLEYRON Julien
22bdbd2498 Prepare release 1.5.0-rc4 2018-01-04 15:22:03 +01:00
Ludovic Fernandez
287fb78654 Split Consul and Consul Catalog documentation 2018-01-04 14:48:03 +01:00
SALLEYRON Julien
5b24403c8e Don't panic if ResponseWriter does not implement CloseNotify 2018-01-04 11:18:03 +01:00
Julien Maitrehenry
e83599dd08 Add a note on how to add label to a docker compose file 2018-01-04 10:34:03 +01:00
SALLEYRON Julien
f30ad20c9b Use gorilla readMessage and writeMessage instead of just an io.Copy 2018-01-03 15:32:03 +01:00
Timo Reimann
01e17b6c3e k8s guide: Leave note about assumed DaemonSet usage. 2018-01-03 09:12:03 +01:00
SALLEYRON Julien
3e13ebec93 We need to flush the end of the body when retry is streamed 2018-01-02 16:02:03 +01:00
Fernandez Ludovic
23c1a9ca8e Merge branch 'v1.4' into v1.5 2018-01-02 13:10:11 +01:00
Michael
741c739ef1 Prepare release v1.4.6 2018-01-02 12:54:03 +01:00
SALLEYRON Julien
52f16e11a8 Use gorilla readMessage and writeMessage instead of just an io.Copy 2018-01-02 12:30:05 +01:00
Michael
0ee6973e2f Upgrade docs dependencies and adapt configuration 2018-01-02 11:28:02 +01:00
Timo Reimann
4819974a1c Improve Marathon service label documentation. 2018-01-02 11:08:02 +01:00
Michael
e8e8b41eed Normalize serviceName added to the service backend names 2018-01-02 10:52:03 +01:00
Krzysztof Pędrys
7d23d3c0a4 Typo in docker.endpoint TCP port. 2018-01-02 10:38:03 +01:00
Ludovic Fernandez
718fc7a79d Fix bug report command 2018-01-02 10:14:03 +01:00
Ludovic Fernandez
bfd142b13b Fix custom headers template 2018-01-02 10:10:04 +01:00
Ludovic Fernandez
75533b2beb Use prefix for sticky and stickiness tags. 2018-01-02 09:44:02 +01:00
NicoMen
9a7821b8fa Send empty configuration from file provider 2017-12-21 21:24:03 +01:00
lishaoxiong
e8333883df Add tests for TLS dynamic configuration in ETCD3 2017-12-21 18:02:04 +01:00
NicoMen
1e44e339ad Allow deleting dynamically all TLS certificates from an entryPoint 2017-12-21 14:16:03 +01:00
Ludovic Fernandez
89a79d0f1b Prepare release 1.5.0-rc3 2017-12-20 15:10:06 +01:00
NicoMen
9e41485ff1 Modify ACME configuration migration into KV store 2017-12-20 14:40:07 +01:00
Nimi Wariboko Jr
3c7c6c4d9f Mesos: Use slave.PID.Host as task SlaveIP. 2017-12-20 12:12:03 +01:00
Ludovic Fernandez
cd1b3904da Add missing entrypoints template. 2017-12-20 10:26:03 +01:00
Emile Vauge
b23b2611b3 Add non regex pathPrefix 2017-12-19 17:00:12 +01:00
Timo Reimann
877770f7cf Update go-marathon 2017-12-19 16:00:09 +01:00
lishaoxiong
3142a4f4b3 Fix stickiness bug due to template syntax error 2017-12-19 14:08:03 +01:00
Ludovic Fernandez
b4dc96527d Move rate limit documentation. 2017-12-19 09:48:03 +01:00
Ludovic Fernandez
35b5ca4c63 fix isHealthy logic. 2017-12-18 10:30:08 +01:00
Ludovic Fernandez
daf3023b02 Change Zookeeper default prefix. 2017-12-18 09:22:03 +01:00
Michael
b17d5b80b8 Reload configuration when port change for one service 2017-12-15 20:52:03 +01:00
Michael
48b4eb5c0d Fix bad Træfik update on Consul Catalog 2017-12-15 16:00:14 +01:00
Ludovic Fernandez
7ecd6d20ba Support regex redirect by frontend 2017-12-15 11:48:03 +01:00
Kevin Risden
bddad57a7b Fix RawPath handling in addPrefix 2017-12-15 03:50:07 +01:00
Ludovic Fernandez
799136a714 fix: backend name for Stateful services. (Service Fabric) 2017-12-15 01:22:03 +01:00
Timo Reimann
350d61b4a6 Fix github.com/containous/traefik-extra-service-fabric dep to v1.0.1. 2017-12-14 16:06:03 +01:00
Gérald Croës
b6f5a66fab Grammar 2017-12-13 18:22:05 +01:00
Ludovic Fernandez
b0c12e2422 Fix: frontend redirect 2017-12-13 17:02:04 +01:00
Michael MATUR
623a7dc7e6 Fix small missing property in documentation for consul catalog 2017-12-13 11:56:02 +01:00
Michael MATUR
709c7e5707 Improve documentation for Cloudflare API key 2017-12-13 11:56:02 +01:00
Mikhail Vasin
ee04f52a16 Fix broken links and improve ResponseCodeRatio() description 2017-12-08 16:12:04 +01:00
Ludovic Fernandez
7d98c1c4e0 Prepare release v1.5.0-rc2 2017-12-06 15:58:03 +01:00
Timo Reimann
4387cf38d7 Close ring buffer used in throttling function. 2017-12-06 14:54:03 +01:00
Michael MATUR
a9d38570ab Merge tag 'v1.4.5' into v1.5 2017-12-06 13:05:08 +01:00
SALLEYRON Julien
0e619369fd fix healthcheck when web is not specified 2017-12-06 11:20:03 +01:00
Michael
cda09c843a Prepare release v1.4.5 2017-12-06 10:44:03 +01:00
NicoMen
6333bfe6e8 Modify the ACME renewing logs level 2017-12-05 15:42:03 +01:00
Timo Reimann
41d8863d2f Fix pprof route order. 2017-12-05 10:50:03 +01:00
Jan Mara
523b7f96f8 Add note to Kubernetes RBAC docs about RoleBindings and namespaces 2017-12-05 02:46:03 +01:00
Mikhail Vasin
ab1a930705 Emphasize the necessity of enabling file backend 2017-12-05 02:30:02 +01:00
Ludovic Fernandez
3a99c86cb3 Change custom headers separator 2017-12-04 11:40:03 +01:00
Michael
d6ad7e2e64 Fix empty IP for backend when dnsrr in Docker swarm mode 2017-12-01 14:34:03 +01:00
Ludovic Fernandez
aaf120f263 Reduce logs with new Kubernetes security annotations 2017-12-01 14:00:04 +01:00
Ludovic Fernandez
c228e73b26 fix Docker labels documentation render. 2017-12-01 09:36:02 +01:00
SALLEYRON Julien
e27e65eb76 Fix wrong defaultentrypoint and unexisting entrypoint issue 2017-11-30 16:10:02 +01:00
SALLEYRON Julien
1c8acf3929 Doesn't ignore web params when web.metrics.prometheus is set 2017-11-30 14:12:04 +01:00
SALLEYRON Julien
40b3c17703 Fix metrics problem on multiple entrypoints 2017-11-30 12:18:03 +01:00
Daniel Tomcej
313357a6b3 quote template strings 2017-11-30 10:42:02 +01:00
Michael
37a1aaad64 Improve consul documentation 2017-11-30 10:12:03 +01:00
Ludovic Fernandez
f084d2a28b Fix Labels/annotation logs and values. 2017-11-30 09:26:03 +01:00
Michael
077b39d7c6 Add option -s to gofmt for autogen 2017-11-30 08:52:03 +01:00
Ludovic Fernandez
7081f3df58 Sync vendor and glide. 2017-11-29 13:26:03 +01:00
424 changed files with 47405 additions and 8880 deletions

2
.gitignore vendored
View File

@@ -11,4 +11,4 @@
*.log
*.exe
.DS_Store
/example/acme/acme.json
/examples/acme/acme.json

View File

@@ -1,6 +1,9 @@
sudo: required
dist: trusty
git:
depth: false
services:
- docker
@@ -21,22 +24,15 @@ before_deploy:
sudo -E apt-get -yq update;
sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install docker-ce=${DOCKER_VERSION}*;
docker version;
pip install --user -r requirements.txt;
make -j${N_MAKE_JOBS} crossbinary-parallel;
make image-dirty;
mkdocs build --clean;
tar cfz dist/traefik-${VERSION}.src.tar.gz --exclude-vcs --exclude dist .;
if [ "$TRAVIS_TAG" ]; then
make -j${N_MAKE_JOBS} crossbinary-parallel;
make image-dirty;
fi;
curl -sI https://github.com/containous/structor/releases/latest | grep -Fi Location | tr -d '\r' | sed "s/tag/download/g" | awk -F " " '{ print $2 "/structor_linux-amd64"}' | wget --output-document=$GOPATH/bin/structor -i -;
chmod +x $GOPATH/bin/structor;
structor -o containous -r traefik --dockerfile-url="https://raw.githubusercontent.com/containous/traefik/master/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/containous/structor/master/traefik-menu.js.gotmpl" --exp-branch=master --debug;
fi
deploy:
- provider: pages
edge: true
github_token: ${GITHUB_TOKEN}
local_dir: site
skip_cleanup: true
on:
repo: containous/traefik
tags: true
condition: ${TRAVIS_TAG} =~ ^v[0-9]+\.[0-9]+\.[0-9]+$
- provider: releases
api_key: ${GITHUB_TOKEN}
file: dist/traefik*
@@ -56,3 +52,11 @@ deploy:
skip_cleanup: true
on:
repo: containous/traefik
- provider: pages
edge: true
github_token: ${GITHUB_TOKEN}
local_dir: site
skip_cleanup: true
on:
repo: containous/traefik
all_branches: true

View File

@@ -1,5 +1,286 @@
# Change Log
## [v1.5.0](https://github.com/containous/traefik/tree/v1.5.0) (2018-01-23)
[All Commits](https://github.com/containous/traefik/compare/v1.4.0-rc1...v1.5.0)
**Enhancements:**
- **[acme,tls]** Rename TLSConfigurations to TLS. ([#2744](https://github.com/containous/traefik/pull/2744) by [ldez](https://github.com/ldez))
- **[acme,provider,docker,tls]** Make the TLS certificates management dynamic. ([#2233](https://github.com/containous/traefik/pull/2233) by [nmengin](https://github.com/nmengin))
- **[acme]** Add Let's Encrypt HTTP Challenge ([#2701](https://github.com/containous/traefik/pull/2701) by [Juliens](https://github.com/Juliens))
- **[acme]** Update github.com/xenolf/lego to 0.4.1 ([#2304](https://github.com/containous/traefik/pull/2304) by [oldmantaiter](https://github.com/oldmantaiter))
- **[api,healthcheck,metrics,provider,webui]** Split Web into API/Dashboard, ping, metric and Rest Provider ([#2335](https://github.com/containous/traefik/pull/2335) by [Juliens](https://github.com/Juliens))
- **[authentication]** Pass through certain forward auth negative response headers ([#2127](https://github.com/containous/traefik/pull/2127) by [wheresmysocks](https://github.com/wheresmysocks))
- **[cluster,consul,file]** Add file to storeconfig ([#2419](https://github.com/containous/traefik/pull/2419) by [emilevauge](https://github.com/emilevauge))
- **[cluster,provider]** Support Etcd v3, enhance KV support ([#2407](https://github.com/containous/traefik/pull/2407) by [nmengin](https://github.com/nmengin))
- **[docker,k8s,rancher,webui]** Redirect to another entryPoint per frontend ([#2133](https://github.com/containous/traefik/pull/2133) by [SantoDE](https://github.com/SantoDE))
- **[docker,k8s,rancher]** Support regex redirect by frontend ([#2570](https://github.com/containous/traefik/pull/2570) by [ldez](https://github.com/ldez))
- **[docker]** Add Custom header parsing to Docker Provider ([#2030](https://github.com/containous/traefik/pull/2030) by [dtomcej](https://github.com/dtomcej))
- **[docker]** Docker labels ([#2473](https://github.com/containous/traefik/pull/2473) by [ldez](https://github.com/ldez))
- **[docker]** Add docker security headers via labels ([#2334](https://github.com/containous/traefik/pull/2334) by [dtomcej](https://github.com/dtomcej))
- **[docker]** Use Node IP in Swarm Standalone with "host" NetworkMode ([#2274](https://github.com/containous/traefik/pull/2274) by [BlakeMesdag](https://github.com/BlakeMesdag))
- **[ecs]** ECS provider refactoring ([#2050](https://github.com/containous/traefik/pull/2050) by [mmatur](https://github.com/mmatur))
- **[ecs]** Add health check label to ECS ([#2421](https://github.com/containous/traefik/pull/2421) by [oldmantaiter](https://github.com/oldmantaiter))
- **[ecs]** Support Host NetworkMode for ECS provider ([#2320](https://github.com/containous/traefik/pull/2320) by [FriggaHel](https://github.com/FriggaHel))
- **[etcd]** Manage certificates dynamically in kv store ([#2411](https://github.com/containous/traefik/pull/2411) by [dahefanteng](https://github.com/dahefanteng))
- **[healthcheck]** Use health check for systemd watchdog ([#2283](https://github.com/containous/traefik/pull/2283) by [guilhem](https://github.com/guilhem))
- **[k8s]** Kubernetes security header annotations ([#2460](https://github.com/containous/traefik/pull/2460) by [dtomcej](https://github.com/dtomcej))
- **[k8s]** Add labels for `traefik.frontend.entryPoints` & `PassTLSCert` to Kubernetes ([#2324](https://github.com/containous/traefik/pull/2324) by [ryarnyah](https://github.com/ryarnyah))
- **[k8s]** Only listen to configured k8s namespaces. ([#1895](https://github.com/containous/traefik/pull/1895) by [timoreimann](https://github.com/timoreimann))
- **[logs,middleware,consul,docker]** Use constants from http package. ([#2425](https://github.com/containous/traefik/pull/2425) by [ldez](https://github.com/ldez))
- **[logs]** Add json format support for Traefik logs ([#2056](https://github.com/containous/traefik/pull/2056) by [marco-jantke](https://github.com/marco-jantke))
- **[marathon]** Marathon constraints filtering ([#2388](https://github.com/containous/traefik/pull/2388) by [aantono](https://github.com/aantono))
- **[marathon]** Remove unused lightMarathonClient. ([#2383](https://github.com/containous/traefik/pull/2383) by [timoreimann](https://github.com/timoreimann))
- **[metrics]** Add InfluxDB support for traefik metrics ([#2289](https://github.com/containous/traefik/pull/2289) by [adityacs](https://github.com/adityacs))
- **[middleware]** Added ReplacePathRegex middleware ([#2033](https://github.com/containous/traefik/pull/2033) by [Tiscs](https://github.com/Tiscs))
- **[middleware]** Fix custom headers replacement ([#2455](https://github.com/containous/traefik/pull/2455) by [mmatur](https://github.com/mmatur))
- **[oxy]** Resync oxy with original repository ([#2451](https://github.com/containous/traefik/pull/2451) by [Juliens](https://github.com/Juliens))
- **[provider]** Support template as raw string. ([#2413](https://github.com/containous/traefik/pull/2413) by [ldez](https://github.com/ldez))
- **[rancher]** Run Rancher tests cases in parallel. ([#2424](https://github.com/containous/traefik/pull/2424) by [ldez](https://github.com/ldez))
- **[rancher]** Update Rancher API integration to go-rancher client v2. ([#2291](https://github.com/containous/traefik/pull/2291) by [rawmind0](https://github.com/rawmind0))
- **[servicefabric]** Add Service Fabric Provider ([#2117](https://github.com/containous/traefik/pull/2117) by [lawrencegripper](https://github.com/lawrencegripper))
- **[tls]** Allow adding optional Client CA files ([#2306](https://github.com/containous/traefik/pull/2306) by [nmengin](https://github.com/nmengin))
- **[websocket]** Add tests for websocket headers ([#2379](https://github.com/containous/traefik/pull/2379) by [Juliens](https://github.com/Juliens))
- Upgrade libkermit/compose version ([#2071](https://github.com/containous/traefik/pull/2071) by [nmengin](https://github.com/nmengin))
- Add proxy protocol tests ([#2325](https://github.com/containous/traefik/pull/2325) by [emilevauge](https://github.com/emilevauge))
- Register pprof handlers. ([#2428](https://github.com/containous/traefik/pull/2428) by [timoreimann](https://github.com/timoreimann))
- Rate limiting for frontends ([#2034](https://github.com/containous/traefik/pull/2034) by [bparli](https://github.com/bparli))
- Stats collection. ([#2447](https://github.com/containous/traefik/pull/2447) by [ldez](https://github.com/ldez))
- Add request accepting grace period delaying graceful shutdown. ([#1971](https://github.com/containous/traefik/pull/1971) by [timoreimann](https://github.com/timoreimann))
- Put subcommand in dedicated files. ([#2265](https://github.com/containous/traefik/pull/2265) by [ldez](https://github.com/ldez))
**Bug fixes:**
- **[acme,docker]** Modify ACME configuration migration into KV store ([#2598](https://github.com/containous/traefik/pull/2598) by [nmengin](https://github.com/nmengin))
- **[acme,logs]** Modify DEBUG messages to get ACME certificates ([#2685](https://github.com/containous/traefik/pull/2685) by [nmengin](https://github.com/nmengin))
- **[acme]** Modify the ACME renewing logs level ([#2520](https://github.com/containous/traefik/pull/2520) by [nmengin](https://github.com/nmengin))
- **[acme]** ACME and corporate proxy. ([#2738](https://github.com/containous/traefik/pull/2738) by [ldez](https://github.com/ldez))
- **[acme]** Challenge HTTP must ignore deprecated web.path option ([#2719](https://github.com/containous/traefik/pull/2719) by [Juliens](https://github.com/Juliens))
- **[api]** Fix pprof route order. ([#2523](https://github.com/containous/traefik/pull/2523) by [timoreimann](https://github.com/timoreimann))
- **[authentication,middleware]** Fix concurrent map writes on digest auth ([#2695](https://github.com/containous/traefik/pull/2695) by [mmatur](https://github.com/mmatur))
- **[consulcatalog]** Use prefix for sticky and stickiness tags. ([#2624](https://github.com/containous/traefik/pull/2624) by [ldez](https://github.com/ldez))
- **[consulcatalog]** Fix bad Træfik update on Consul Catalog ([#2573](https://github.com/containous/traefik/pull/2573) by [mmatur](https://github.com/mmatur))
- **[consulcatalog]** Reload configuration when port change for one service ([#2574](https://github.com/containous/traefik/pull/2574) by [mmatur](https://github.com/mmatur))
- **[docker,k8s]** Fix Labels/annotation logs and values. ([#2488](https://github.com/containous/traefik/pull/2488) by [ldez](https://github.com/ldez))
- **[docker,k8s]** Change custom headers separator ([#2509](https://github.com/containous/traefik/pull/2509) by [ldez](https://github.com/ldez))
- **[docker]** Fix empty IP for backend when dnsrr in Docker swarm mode ([#2490](https://github.com/containous/traefik/pull/2490) by [mmatur](https://github.com/mmatur))
- **[docker]** Quote template strings ([#2496](https://github.com/containous/traefik/pull/2496) by [dtomcej](https://github.com/dtomcej))
- **[docker]** Return errors from Docker client.Events ([#2689](https://github.com/containous/traefik/pull/2689) by [BlakeMesdag](https://github.com/BlakeMesdag))
- **[docker]** Typo in Docker template. ([#2692](https://github.com/containous/traefik/pull/2692) by [ldez](https://github.com/ldez))
- **[ecs]** Add missing functions for ECS template ([#2312](https://github.com/containous/traefik/pull/2312) by [oldmantaiter](https://github.com/oldmantaiter))
- **[file,tls]** Send empty configuration from file provider ([#2609](https://github.com/containous/traefik/pull/2609) by [nmengin](https://github.com/nmengin))
- **[healthcheck]** Fix health check when web is not specified ([#2529](https://github.com/containous/traefik/pull/2529) by [Juliens](https://github.com/Juliens))
- **[k8s]** Reduce logs with new Kubernetes security annotations ([#2506](https://github.com/containous/traefik/pull/2506) by [ldez](https://github.com/ldez))
- **[k8s]** Add missing entry points template. ([#2594](https://github.com/containous/traefik/pull/2594) by [ldez](https://github.com/ldez))
- **[kv]** Fix stickiness bug due to template syntax error ([#2591](https://github.com/containous/traefik/pull/2591) by [dahefanteng](https://github.com/dahefanteng))
- **[kv]** List entries parsing. ([#2669](https://github.com/containous/traefik/pull/2669) by [ldez](https://github.com/ldez))
- **[logs]** Fix traefik logs to behave like configured ([#2176](https://github.com/containous/traefik/pull/2176) by [marco-jantke](https://github.com/marco-jantke))
- **[marathon]** Update go-marathon ([#2585](https://github.com/containous/traefik/pull/2585) by [timoreimann](https://github.com/timoreimann))
- **[mesos]** Mesos: Use slave.PID.Host as task SlaveIP. ([#2590](https://github.com/containous/traefik/pull/2590) by [nemosupremo](https://github.com/nemosupremo))
- **[metrics]** Fix breaking change in web metrics ([#2725](https://github.com/containous/traefik/pull/2725) by [Juliens](https://github.com/Juliens))
- **[metrics]** Do not ignore web params when web.metrics.prometheus is set ([#2499](https://github.com/containous/traefik/pull/2499) by [Juliens](https://github.com/Juliens))
- **[metrics]** Fix metrics problem on multiple entrypoints ([#2492](https://github.com/containous/traefik/pull/2492) by [Juliens](https://github.com/Juliens))
- **[metrics]** Fix data races. ([#2287](https://github.com/containous/traefik/pull/2287) by [tcolgate](https://github.com/tcolgate))
- **[metrics]** Flaky test Influxdb. ([#2386](https://github.com/containous/traefik/pull/2386) by [ldez](https://github.com/ldez))
- **[middleware,docker,k8s]** Fix custom headers template ([#2621](https://github.com/containous/traefik/pull/2621) by [ldez](https://github.com/ldez))
- **[middleware]** Don't panic if ResponseWriter does not implement CloseNotify ([#2651](https://github.com/containous/traefik/pull/2651) by [Juliens](https://github.com/Juliens))
- **[middleware]** GzipResponse must implement CloseNotifier if ResponseWriter implement it ([#2657](https://github.com/containous/traefik/pull/2657) by [Juliens](https://github.com/Juliens))
- **[middleware]** Fix RawPath handling in addPrefix ([#2560](https://github.com/containous/traefik/pull/2560) by [risdenk](https://github.com/risdenk))
- **[middleware]** We need to flush the end of the body when retry is streamed ([#2644](https://github.com/containous/traefik/pull/2644) by [Juliens](https://github.com/Juliens))
- **[provider]** Fix typo in frontend.headers.customresponseheaders label ([#2356](https://github.com/containous/traefik/pull/2356) by [nmandery](https://github.com/nmandery))
- **[provider]** Fix concurrent provider config reloads ([#2276](https://github.com/containous/traefik/pull/2276) by [marco-jantke](https://github.com/marco-jantke))
- **[rancher]** Don't reload configuration when rancher server is down ([#2706](https://github.com/containous/traefik/pull/2706) by [wacken89](https://github.com/wacken89))
- **[rules]** Add non regex pathPrefix ([#2592](https://github.com/containous/traefik/pull/2592) by [emilevauge](https://github.com/emilevauge))
- **[servicefabric]** Fix backend name for Stateful services. (Service Fabric) ([#2559](https://github.com/containous/traefik/pull/2559) by [ldez](https://github.com/ldez))
- **[servicefabric]** Fix isHealthy logic. ([#2577](https://github.com/containous/traefik/pull/2577) by [ldez](https://github.com/ldez))
- **[servicefabric]** Service Fabric 'expose' as boolean. ([#2476](https://github.com/containous/traefik/pull/2476) by [ldez](https://github.com/ldez))
- **[tls]** Allow deleting dynamically all TLS certificates from an entryPoint ([#2603](https://github.com/containous/traefik/pull/2603) by [nmengin](https://github.com/nmengin))
- **[websocket]** Disable websocket compression ([#2727](https://github.com/containous/traefik/pull/2727) by [Juliens](https://github.com/Juliens))
- **[websocket]** Add compression and better error handling ([#2702](https://github.com/containous/traefik/pull/2702) by [Juliens](https://github.com/Juliens))
- **[websocket]** Use gorilla readMessage and writeMessage instead of just an io.Copy ([#2650](https://github.com/containous/traefik/pull/2650) by [Juliens](https://github.com/Juliens))
- **[websocket]** RawPath and Transfer TLSConfig in websocket ([#2077](https://github.com/containous/traefik/pull/2077) by [Juliens](https://github.com/Juliens))
- **[zk]** Change Zookeeper default prefix. ([#2580](https://github.com/containous/traefik/pull/2580) by [ldez](https://github.com/ldez))
- Fix wrong default entry point and non-existing entry point issue ([#2501](https://github.com/containous/traefik/pull/2501) by [Juliens](https://github.com/Juliens))
- Fix goroutine leak in throttler logic. ([#2739](https://github.com/containous/traefik/pull/2739) by [timoreimann](https://github.com/timoreimann))
- Fix timeout integration test ([#2679](https://github.com/containous/traefik/pull/2679) by [ldez](https://github.com/ldez))
- Fix frontend redirect ([#2544](https://github.com/containous/traefik/pull/2544) by [ldez](https://github.com/ldez))
- Close ring buffer used in throttling function. ([#2532](https://github.com/containous/traefik/pull/2532) by [timoreimann](https://github.com/timoreimann))
**Documentation:**
- **[acme]** Improve documentation for Cloudflare API key ([#2558](https://github.com/containous/traefik/pull/2558) by [mmatur](https://github.com/mmatur))
- **[acme]** Update Let's Encrypt provider list ([#2347](https://github.com/containous/traefik/pull/2347) by [mmatur](https://github.com/mmatur))
- **[cluster]** Add a clustering example with Docker Swarm ([#2589](https://github.com/containous/traefik/pull/2589) by [jmaitrehenry](https://github.com/jmaitrehenry))
- **[consul,consulcatalog]** Split Consul and Consul Catalog documentation ([#2654](https://github.com/containous/traefik/pull/2654) by [ldez](https://github.com/ldez))
- **[consul]** Improve Consul documentation ([#2485](https://github.com/containous/traefik/pull/2485) by [mmatur](https://github.com/mmatur))
- **[docker/swarm]** Typo in docker.endpoint TCP port. ([#2626](https://github.com/containous/traefik/pull/2626) by [redhandpl](https://github.com/redhandpl))
- **[docker]** Fix Docker labels documentation render. ([#2505](https://github.com/containous/traefik/pull/2505) by [ldez](https://github.com/ldez))
- **[docker]** Add a note on how to add label to a docker compose file ([#2611](https://github.com/containous/traefik/pull/2611) by [jmaitrehenry](https://github.com/jmaitrehenry))
- **[etcd]** Fix typo in examples ([#2446](https://github.com/containous/traefik/pull/2446) by [dahefanteng](https://github.com/dahefanteng))
- **[k8s]** Add note to Kubernetes RBAC docs about RoleBindings and namespaces ([#2498](https://github.com/containous/traefik/pull/2498) by [jmara](https://github.com/jmara))
- **[k8s]** k8s guide: Leave note about assumed DaemonSet usage. ([#2634](https://github.com/containous/traefik/pull/2634) by [timoreimann](https://github.com/timoreimann))
- **[k8s]** Apply various contentual and stylish improvements to the k8s docs. ([#2677](https://github.com/containous/traefik/pull/2677) by [timoreimann](https://github.com/timoreimann))
- **[k8s]** Document rewrite-target annotation. ([#2676](https://github.com/containous/traefik/pull/2676) by [timoreimann](https://github.com/timoreimann))
- **[k8s]** Remove obsolete links in k8s docs ([#2465](https://github.com/containous/traefik/pull/2465) by [marco-jantke](https://github.com/marco-jantke))
- **[k8s]** Document filename parameter for Kubernetes. ([#2464](https://github.com/containous/traefik/pull/2464) by [timoreimann](https://github.com/timoreimann))
- **[marathon]** Improve Marathon service label documentation. ([#2635](https://github.com/containous/traefik/pull/2635) by [timoreimann](https://github.com/timoreimann))
- **[metrics]** Add entrypoint in Prometheus doc and remove web on Influxdb doc ([#2452](https://github.com/containous/traefik/pull/2452) by [Juliens](https://github.com/Juliens))
- **[provider,webui]** Fix redirect problem on dashboard + docs/tests on [web] ([#2686](https://github.com/containous/traefik/pull/2686) by [Juliens](https://github.com/Juliens))
- **[servicefabric]** Describe 'refreshSecond' configuration. ([#2471](https://github.com/containous/traefik/pull/2471) by [ldez](https://github.com/ldez))
- **[tls]** Fix doc dynamic certificates ([#2737](https://github.com/containous/traefik/pull/2737) by [emilevauge](https://github.com/emilevauge))
- **[tls]** Add link to crypto/tls godoc. ([#2470](https://github.com/containous/traefik/pull/2470) by [ldez](https://github.com/ldez))
- Move rate limit documentation. ([#2588](https://github.com/containous/traefik/pull/2588) by [ldez](https://github.com/ldez))
- Grammar ([#2562](https://github.com/containous/traefik/pull/2562) by [geraldcroes](https://github.com/geraldcroes))
- Fix some doc links ([#2731](https://github.com/containous/traefik/pull/2731) by [eldondev](https://github.com/eldondev))
- Fix broken links and improve ResponseCodeRatio() description ([#2538](https://github.com/containous/traefik/pull/2538) by [mvasin](https://github.com/mvasin))
- Fix typo in anonymous usage log message. ([#2711](https://github.com/containous/traefik/pull/2711) by [Yggdrasil](https://github.com/Yggdrasil))
- Fix typos in changelog ([#2387](https://github.com/containous/traefik/pull/2387) by [ferhatelmas](https://github.com/ferhatelmas))
- Add mmatur to maintainers ([#2303](https://github.com/containous/traefik/pull/2303) by [emilevauge](https://github.com/emilevauge))
- Add a note about redirection rule to precise how regex/replacement work. ([#2243](https://github.com/containous/traefik/pull/2243) by [nmengin](https://github.com/nmengin))
- Add docker things for documentation ([#2020](https://github.com/containous/traefik/pull/2020) by [tcoupin](https://github.com/tcoupin))
- Prepare release v1.5.0-rc5 ([#2707](https://github.com/containous/traefik/pull/2707) by [mmatur](https://github.com/mmatur))
- Prepare release v1.5.0-rc4 ([#2656](https://github.com/containous/traefik/pull/2656) by [Juliens](https://github.com/Juliens))
- Prepare release v1.5.0-rc3 ([#2599](https://github.com/containous/traefik/pull/2599) by [ldez](https://github.com/ldez))
- Prepare release v1.5.0-rc2 ([#2533](https://github.com/containous/traefik/pull/2533) by [ldez](https://github.com/ldez))
- Prepare release v1.5.0-rc1 ([#2480](https://github.com/containous/traefik/pull/2480) by [ldez](https://github.com/ldez))
**Misc:**
- **[acme]** dumpcerts.sh: Fix call to "base64" for Alpine ([#2344](https://github.com/containous/traefik/pull/2344) by [nknapp](https://github.com/nknapp))
- **[acme]** dumpcerts.sh: fixed sed, extracted domain keys ([#2161](https://github.com/containous/traefik/pull/2161) by [sjawhar](https://github.com/sjawhar))
- **[etcd,kv,tls]** Add tests for TLS dynamic configuration in ETCD3 ([#2606](https://github.com/containous/traefik/pull/2606) by [dahefanteng](https://github.com/dahefanteng))
- Upgrade libkermit/compose version ([#2074](https://github.com/containous/traefik/pull/2074) by [nmengin](https://github.com/nmengin))
- Merge v1.4.6 into v1.5 ([#2642](https://github.com/containous/traefik/pull/2642) by [ldez](https://github.com/ldez))
- Merge v1.4.5 into v1.5 ([#2530](https://github.com/containous/traefik/pull/2530) by [mmatur](https://github.com/mmatur))
- Merge current v1.4 into master ([#2479](https://github.com/containous/traefik/pull/2479) by [ldez](https://github.com/ldez))
- Merge v1.4.3 into master ([#2415](https://github.com/containous/traefik/pull/2415) by [ldez](https://github.com/ldez))
- Merge v1.4.4 into master ([#2457](https://github.com/containous/traefik/pull/2457) by [ldez](https://github.com/ldez))
- Merge v1.4.3 into master ([#2406](https://github.com/containous/traefik/pull/2406) by [ldez](https://github.com/ldez))
- Revert "Merge v1.4.2 into master" ([#2414](https://github.com/containous/traefik/pull/2414) by [ldez](https://github.com/ldez))
- Merge v1.4.2 into master ([#2358](https://github.com/containous/traefik/pull/2358) by [ldez](https://github.com/ldez))
- Merge v1.4.1 into master ([#2318](https://github.com/containous/traefik/pull/2318) by [ldez](https://github.com/ldez))
- Merge v1.4.0 ([#2271](https://github.com/containous/traefik/pull/2271) by [ldez](https://github.com/ldez))
- Merge v1.4.0-rc5 into master ([#2242](https://github.com/containous/traefik/pull/2242) by [ldez](https://github.com/ldez))
- Merge v1.4.0-rc4 into master ([#2202](https://github.com/containous/traefik/pull/2202) by [ldez](https://github.com/ldez))
- Merge current v1.4 into master ([#2469](https://github.com/containous/traefik/pull/2469) by [ldez](https://github.com/ldez))
- Merge current v1.4 ([#2154](https://github.com/containous/traefik/pull/2154) by [ldez](https://github.com/ldez))
- Merge v1.4.0-rc3 into master ([#2140](https://github.com/containous/traefik/pull/2140) by [ldez](https://github.com/ldez))
- Merge v1.4.0-rc2 into master ([#2092](https://github.com/containous/traefik/pull/2092) by [ldez](https://github.com/ldez))
- Merge current 1.4 ([#2064](https://github.com/containous/traefik/pull/2064) by [ldez](https://github.com/ldez))
## [v1.5.0-rc5](https://github.com/containous/traefik/tree/v1.5.0-rc5) (2018-01-15)
[All Commits](https://github.com/containous/traefik/compare/v1.5.0-rc4...v1.5.0-rc5)
**Enhancements:**
- **[acme]** Add Let's Encrypt HTTP Challenge ([#2701](https://github.com/containous/traefik/pull/2701) by [Juliens](https://github.com/Juliens))
**Bug fixes:**
- **[acme,logs]** Modify DEBUG messages to get ACME certificates ([#2685](https://github.com/containous/traefik/pull/2685) by [nmengin](https://github.com/nmengin))
- **[authentication,middleware]** Fix concurrent map writes on digest auth ([#2695](https://github.com/containous/traefik/pull/2695) by [mmatur](https://github.com/mmatur))
- **[docker]** Typo in Docker template. ([#2692](https://github.com/containous/traefik/pull/2692) by [ldez](https://github.com/ldez))
- **[docker]** Return errors from Docker client.Events ([#2689](https://github.com/containous/traefik/pull/2689) by [BlakeMesdag](https://github.com/BlakeMesdag))
- **[kv]** List entries parsing. ([#2669](https://github.com/containous/traefik/pull/2669) by [ldez](https://github.com/ldez))
- **[metrics]** Fix data races. ([#2287](https://github.com/containous/traefik/pull/2287) by [tcolgate](https://github.com/tcolgate))
- **[middleware]** GzipResponse must implement CloseNotifier if ResponseWriter implement it ([#2657](https://github.com/containous/traefik/pull/2657) by [Juliens](https://github.com/Juliens))
- **[websocket]** Add compression and better error handling ([#2702](https://github.com/containous/traefik/pull/2702) by [Juliens](https://github.com/Juliens))
- Fix: timeout integration test ([#2679](https://github.com/containous/traefik/pull/2679) by [ldez](https://github.com/ldez))
**Documentation:**
- **[cluster]** Add a clustering example with Docker Swarm ([#2589](https://github.com/containous/traefik/pull/2589) by [jmaitrehenry](https://github.com/jmaitrehenry))
- **[k8s]** Apply various contentual and stylish improvements to the k8s docs. ([#2677](https://github.com/containous/traefik/pull/2677) by [timoreimann](https://github.com/timoreimann))
- **[k8s]** Document rewrite-target annotation. ([#2676](https://github.com/containous/traefik/pull/2676) by [timoreimann](https://github.com/timoreimann))
- **[provider,webui]** Fix redirect problem on dashboard + docs/tests on [web] ([#2686](https://github.com/containous/traefik/pull/2686) by [Juliens](https://github.com/Juliens))
## [v1.5.0-rc4](https://github.com/containous/traefik/tree/v1.5.0-rc4) (2018-01-04)
[All Commits](https://github.com/containous/traefik/compare/v1.5.0-rc3...v1.5.0-rc4)
**Bug fixes:**
- **[consulcatalog]** Use prefix for sticky and stickiness tags. ([#2624](https://github.com/containous/traefik/pull/2624) by [ldez](https://github.com/ldez))
- **[file,tls]** Send empty configuration from file provider ([#2609](https://github.com/containous/traefik/pull/2609) by [nmengin](https://github.com/nmengin))
- **[middleware,docker,k8s]** Fix custom headers template ([#2621](https://github.com/containous/traefik/pull/2621) by [ldez](https://github.com/ldez))
- **[middleware]** Don't panic if ResponseWriter does not implement CloseNotify ([#2651](https://github.com/containous/traefik/pull/2651) by [Juliens](https://github.com/Juliens))
- **[middleware]** We need to flush the end of the body when retry is streamed ([#2644](https://github.com/containous/traefik/pull/2644) by [Juliens](https://github.com/Juliens))
- **[tls]** Allow deleting dynamically all TLS certificates from an entryPoint ([#2603](https://github.com/containous/traefik/pull/2603) by [nmengin](https://github.com/nmengin))
- **[websocket]** Use gorilla readMessage and writeMessage instead of just an io.Copy ([#2650](https://github.com/containous/traefik/pull/2650) by [Juliens](https://github.com/Juliens))
**Documentation:**
- **[consul,consulcatalog]** Split Consul and Consul Catalog documentation ([#2654](https://github.com/containous/traefik/pull/2654) by [ldez](https://github.com/ldez))
- **[docker/swarm]** Typo in docker.endpoint TCP port. ([#2626](https://github.com/containous/traefik/pull/2626) by [redhandpl](https://github.com/redhandpl))
- **[docker]** Add a note on how to add label to a docker compose file ([#2611](https://github.com/containous/traefik/pull/2611) by [jmaitrehenry](https://github.com/jmaitrehenry))
- **[k8s]** k8s guide: Leave note about assumed DaemonSet usage. ([#2634](https://github.com/containous/traefik/pull/2634) by [timoreimann](https://github.com/timoreimann))
- **[marathon]** Improve Marathon service label documentation. ([#2635](https://github.com/containous/traefik/pull/2635) by [timoreimann](https://github.com/timoreimann))
**Misc:**
- **[etcd,kv,tls]** Add tests for TLS dynamic configuration in ETCD3 ([#2606](https://github.com/containous/traefik/pull/2606) by [dahefanteng](https://github.com/dahefanteng))
- Merge v1.4.6 into v1.5 ([#2642](https://github.com/containous/traefik/pull/2642) by [ldez](https://github.com/ldez))
## [v1.4.6](https://github.com/containous/traefik/tree/v1.4.6) (2018-01-02)
[All Commits](https://github.com/containous/traefik/compare/v1.4.5...v1.4.6)
**Bug fixes:**
- **[docker]** Normalize serviceName added to the service backend names ([#2631](https://github.com/containous/traefik/pull/2631) by [mmatur](https://github.com/mmatur))
- **[websocket]** Use gorilla readMessage and writeMessage instead of just an io.Copy ([#2640](https://github.com/containous/traefik/pull/2640) by [Juliens](https://github.com/Juliens))
- Fix bug report command ([#2638](https://github.com/containous/traefik/pull/2638) by [ldez](https://github.com/ldez))
## [v1.5.0-rc3](https://github.com/containous/traefik/tree/v1.5.0-rc3) (2017-12-20)
[All Commits](https://github.com/containous/traefik/compare/v1.5.0-rc2...v1.5.0-rc3)
**Enhancements:**
- **[docker,k8s,rancher]** Support regex redirect by frontend ([#2570](https://github.com/containous/traefik/pull/2570) by [ldez](https://github.com/ldez))
**Bug fixes:**
- **[acme,docker]** Modify ACME configuration migration into KV store ([#2598](https://github.com/containous/traefik/pull/2598) by [nmengin](https://github.com/nmengin))
- **[consulcatalog]** Reload configuration when port change for one service ([#2574](https://github.com/containous/traefik/pull/2574) by [mmatur](https://github.com/mmatur))
- **[consulcatalog]** Fix bad Træfik update on Consul Catalog ([#2573](https://github.com/containous/traefik/pull/2573) by [mmatur](https://github.com/mmatur))
- **[k8s]** Add missing entrypoints template. ([#2594](https://github.com/containous/traefik/pull/2594) by [ldez](https://github.com/ldez))
- **[kv]** Fix stickiness bug due to template syntax error ([#2591](https://github.com/containous/traefik/pull/2591) by [dahefanteng](https://github.com/dahefanteng))
- **[marathon]** Update go-marathon ([#2585](https://github.com/containous/traefik/pull/2585) by [timoreimann](https://github.com/timoreimann))
- **[mesos]** Mesos: Use slave.PID.Host as task SlaveIP. ([#2590](https://github.com/containous/traefik/pull/2590) by [nemosupremo](https://github.com/nemosupremo))
- **[middleware]** Fix RawPath handling in addPrefix ([#2560](https://github.com/containous/traefik/pull/2560) by [risdenk](https://github.com/risdenk))
- **[rules]** Add non regex pathPrefix ([#2592](https://github.com/containous/traefik/pull/2592) by [emilevauge](https://github.com/emilevauge))
- **[servicefabric]** Fix backend name for Stateful services. (Service Fabric) ([#2559](https://github.com/containous/traefik/pull/2559) by [ldez](https://github.com/ldez))
- **[servicefabric]** Fix isHealthy logic. ([#2577](https://github.com/containous/traefik/pull/2577) by [ldez](https://github.com/ldez))
- **[zk]** Change Zookeeper default prefix. ([#2580](https://github.com/containous/traefik/pull/2580) by [ldez](https://github.com/ldez))
- Fix frontend redirect ([#2544](https://github.com/containous/traefik/pull/2544) by [ldez](https://github.com/ldez))
**Documentation:**
- **[acme]** Improve documentation for Cloudflare API key ([#2558](https://github.com/containous/traefik/pull/2558) by [mmatur](https://github.com/mmatur))
- Move rate limit documentation. ([#2588](https://github.com/containous/traefik/pull/2588) by [ldez](https://github.com/ldez))
- Grammar ([#2562](https://github.com/containous/traefik/pull/2562) by [geraldcroes](https://github.com/geraldcroes))
- Fix broken links and improve ResponseCodeRatio() description ([#2538](https://github.com/containous/traefik/pull/2538) by [mvasin](https://github.com/mvasin))
## [v1.5.0-rc2](https://github.com/containous/traefik/tree/v1.5.0-rc2) (2017-12-06)
[All Commits](https://github.com/containous/traefik/compare/v1.5.0-rc1...v1.5.0-rc2)
**Bug fixes:**
- **[acme]** Modify the ACME renewing logs level ([#2520](https://github.com/containous/traefik/pull/2520) by [nmengin](https://github.com/nmengin))
- **[api]** Fix pprof route order. ([#2523](https://github.com/containous/traefik/pull/2523) by [timoreimann](https://github.com/timoreimann))
- **[docker,k8s]** Change custom headers separator ([#2509](https://github.com/containous/traefik/pull/2509) by [ldez](https://github.com/ldez))
- **[docker,k8s]** Fix Labels/annotation logs and values. ([#2488](https://github.com/containous/traefik/pull/2488) by [ldez](https://github.com/ldez))
- **[docker]** Quote template strings ([#2496](https://github.com/containous/traefik/pull/2496) by [dtomcej](https://github.com/dtomcej))
- **[docker]** Fix empty IP for backend when dnsrr in Docker swarm mode ([#2490](https://github.com/containous/traefik/pull/2490) by [mmatur](https://github.com/mmatur))
- **[healthcheck]** Fix healthcheck when web is not specified ([#2529](https://github.com/containous/traefik/pull/2529) by [Juliens](https://github.com/Juliens))
- **[k8s]** Reduce logs with new Kubernetes security annotations ([#2506](https://github.com/containous/traefik/pull/2506) by [ldez](https://github.com/ldez))
- **[metrics]** Do not ignore web params when web.metrics.prometheus is set ([#2499](https://github.com/containous/traefik/pull/2499) by [Juliens](https://github.com/Juliens))
- **[metrics]** Fix metrics problem on multiple entrypoints ([#2492](https://github.com/containous/traefik/pull/2492) by [Juliens](https://github.com/Juliens))
- Close ring buffer used in throttling function. ([#2532](https://github.com/containous/traefik/pull/2532) by [timoreimann](https://github.com/timoreimann))
- Fix wrong default entrypoint and non-existing entrypoint issue ([#2501](https://github.com/containous/traefik/pull/2501) by [Juliens](https://github.com/Juliens))
**Documentation:**
- **[consul]** Improve Consul documentation ([#2485](https://github.com/containous/traefik/pull/2485) by [mmatur](https://github.com/mmatur))
- **[docker]** Fix Docker labels documentation render. ([#2505](https://github.com/containous/traefik/pull/2505) by [ldez](https://github.com/ldez))
- **[k8s]** Add note to Kubernetes RBAC docs about RoleBindings and namespaces ([#2498](https://github.com/containous/traefik/pull/2498) by [jmara](https://github.com/jmara))
**Misc:**
- Merge v1.4.5 into v1.5 ([#2530](https://github.com/containous/traefik/pull/2530) by [mmatur](https://github.com/mmatur))
## [v1.4.5](https://github.com/containous/traefik/tree/v1.4.5) (2017-12-05)
[All Commits](https://github.com/containous/traefik/compare/v1.4.4...v1.4.5)
**Bug fixes:**
- **[docker]** Fix empty ip when container is stopped ([#2478](https://github.com/containous/traefik/pull/2478) by [mmatur](https://github.com/mmatur))
- **[k8s]** Fix kubernetes path prefix rule with rewrite-target ([#2461](https://github.com/containous/traefik/pull/2461) by [cheungpat](https://github.com/cheungpat))
**Documentation:**
- **[file]** Emphasize the necessity of enabling file backend ([#2483](https://github.com/containous/traefik/pull/2483) by [mvasin](https://github.com/mvasin))
- Add link to future 1.5 documentation. ([#2477](https://github.com/containous/traefik/pull/2477) by [ldez](https://github.com/ldez))
## [v1.5.0-rc1](https://github.com/containous/traefik/tree/v1.5.0-rc1) (2017-11-28)
[All Commits](https://github.com/containous/traefik/compare/v1.4.0-rc1...v1.5.0-rc1)

View File

@@ -2,7 +2,8 @@
## Building
You need either [Docker](https://github.com/docker/docker) and `make` (Method 1), or `go` (Method 2) in order to build Traefik. For changes to its dependencies, the `glide` dependency management tool and `glide-vc` plugin are required.
You need either [Docker](https://github.com/docker/docker) and `make` (Method 1), or `go` (Method 2) in order to build Traefik.
For changes to its dependencies, the `dep` dependency management tool is required.
### Method 1: Using `Docker` and `Makefile`
@@ -14,7 +15,7 @@ docker build -t "traefik-dev:no-more-godep-ever" -f build.Dockerfile .
Sending build context to Docker daemon 295.3 MB
Step 0 : FROM golang:1.9-alpine
---> 8c6473912976
Step 1 : RUN go get github.com/Masterminds/glide
Step 1 : RUN go get github.com/golang/dep/cmd/dep
[...]
docker run --rm -v "/var/run/docker.sock:/var/run/docker.sock" -it -e OS_ARCH_ARG -e OS_PLATFORM_ARG -e TESTFLAGS -v "/home/user/go/src/github.com/containous/traefik/"dist":/go/src/github.com/containous/traefik/"dist"" "traefik-dev:no-more-godep-ever" ./script/make.sh generate binary
---> Making bundle: generate (in .)
@@ -82,21 +83,20 @@ You will find the Træfik executable in the `~/go/src/github.com/containous/trae
If you happen to update the provider templates (in `/templates`), you need to run `go generate` to update the `autogen` package.
### Setting up `glide` and `glide-vc` for dependency management
### Setting up dependency management
- Glide is not required for building; however, it is necessary to modify dependencies (i.e., add, update, or remove third-party packages)
- Glide can be installed either via homebrew: `$ brew install glide` or via the official glide script: `$ curl https://glide.sh/get | sh`
- The glide plugin `glide-vc` must be installed from source: `go get github.com/sgotti/glide-vc`
[dep](https://github.com/golang/dep) is not required for building; however, it is necessary to modify dependencies (i.e., add, update, or remove third-party packages)
If you want to add a dependency, use `$ glide get` to have glide put it into the vendor folder and update the glide manifest/lock files (`glide.yaml` and `glide.lock`, respectively). A following `glide-vc` run should be triggered to trim down the size of the vendor folder. The final result must be committed into VCS.
If you want to add a dependency, use `dep ensure -add` to have [dep](https://github.com/golang/dep) put it into the vendor folder and update the dep manifest/lock files (`Gopkg.toml` and `Gopkg.lock`, respectively).
Care must be taken to choose the right arguments to `glide` when dealing with dependencies, or otherwise risk ending up with a broken build. For that reason, the helper script `script/glide.sh` encapsulates the gory details and conveniently calls `glide-vc` as well. Call it without parameters for basic usage instructions.
A following `make prune-dep` run should be triggered to trim down the size of the vendor folder.
The final result must be committed into VCS.
Here's a full example using glide to add a new dependency:
Here's a full example using dep to add a new dependency:
```bash
# install the new main dependency github.com/foo/bar and minimize vendor size
$ ./script/glide.sh get github.com/foo/bar
$ dep ensure -add github.com/foo/bar
# generate (Only required to integrate other components such as web dashboard)
$ go generate
# Standard go build
@@ -127,6 +127,7 @@ Test success
```
For development purposes, you can specify which tests to run by using:
```bash
# Run every tests in the MyTest suite
TESTFLAGS="-check.f MyTestSuite" make test-integration
@@ -146,6 +147,7 @@ More: https://labix.org/gocheck
#### Method 2: `go`
Unit tests can be run from the cloned directory by `$ go test ./...` which should return `ok` similar to:
```
ok _/home/user/go/src/github/containous/traefik 0.004s
```

1391
Gopkg.lock generated Normal file

File diff suppressed because it is too large Load Diff

192
Gopkg.toml Normal file
View File

@@ -0,0 +1,192 @@
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
ignored = ["github.com/sirupsen/logrus"]
[[constraint]]
branch = "master"
name = "github.com/ArthurHlt/go-eureka-client"
[[constraint]]
branch = "master"
name = "github.com/BurntSushi/toml"
[[constraint]]
branch = "master"
name = "github.com/BurntSushi/ty"
[[constraint]]
branch = "master"
name = "github.com/NYTimes/gziphandler"
[[constraint]]
branch = "containous-fork"
name = "github.com/abbot/go-http-auth"
source = "github.com/containous/go-http-auth"
[[constraint]]
branch = "master"
name = "github.com/armon/go-proxyproto"
[[constraint]]
name = "github.com/aws/aws-sdk-go"
version = "1.6.18"
[[constraint]]
branch = "master"
name = "github.com/cenk/backoff"
[[constraint]]
name = "github.com/containous/flaeg"
version = "1.0.1"
[[constraint]]
branch = "master"
name = "github.com/containous/mux"
[[constraint]]
name = "github.com/containous/staert"
version = "2.0.0"
[[constraint]]
name = "github.com/containous/traefik-extra-service-fabric"
version = "1.0.5"
[[constraint]]
name = "github.com/coreos/go-systemd"
version = "14.0.0"
[[constraint]]
branch = "master"
name = "github.com/docker/leadership"
source = "github.com/containous/leadership"
[[constraint]]
name = "github.com/docker/libkv"
source = "github.com/abronan/libkv"
[[constraint]]
name = "github.com/eapache/channels"
version = "1.1.0"
[[constraint]]
branch = "master"
name = "github.com/elazarl/go-bindata-assetfs"
[[constraint]]
name = "github.com/go-check/check"
source = "github.com/containous/check"
[[constraint]]
name = "github.com/go-kit/kit"
version = "0.3.0"
[[constraint]]
name = "github.com/influxdata/influxdb"
version = "1.3.7"
[[constraint]]
branch = "master"
name = "github.com/jjcollinge/servicefabric"
[[constraint]]
name = "github.com/mattn/go-shellwords"
version = "1.0.3"
[[constraint]]
name = "github.com/mesosphere/mesos-dns"
source = "https://github.com/containous/mesos-dns.git"
[[constraint]]
branch = "master"
name = "github.com/mitchellh/copystructure"
[[constraint]]
branch = "master"
name = "github.com/mitchellh/hashstructure"
[[constraint]]
branch = "master"
name = "github.com/mitchellh/mapstructure"
[[constraint]]
branch = "master"
name = "github.com/rancher/go-rancher-metadata"
[[constraint]]
branch = "master"
name = "github.com/ryanuber/go-glob"
[[constraint]]
name = "github.com/satori/go.uuid"
version = "1.1.0"
[[constraint]]
branch = "master"
name = "github.com/stvp/go-udp-testing"
[[constraint]]
name = "github.com/vdemeester/shakers"
version = "0.1.0"
[[constraint]]
branch = "containous-fork"
name = "github.com/vulcand/oxy"
source = "https://github.com/containous/oxy.git"
[[constraint]]
name = "github.com/xenolf/lego"
version = "0.4.1"
[[constraint]]
name = "google.golang.org/grpc"
version = "1.5.2"
[[constraint]]
name = "gopkg.in/fsnotify.v1"
version = "1.4.2"
[[constraint]]
name = "k8s.io/client-go"
version = "2.0.0"
[[override]]
name = "github.com/Nvveen/Gotty"
revision = "6018b68f96b839edfbe3fb48668853f5dbad88a3"
source = "github.com/ijc25/Gotty"
[[override]]
name = "github.com/gorilla/websocket"
revision = "a69d9f6de432e2c6b296a947d8a5ee88f68522cf"
[[override]]
# always keep this override
name = "github.com/mailgun/timetools"
revision = "7e6055773c5137efbeb3bd2410d705fe10ab6bfd"
[[override]]
name = "github.com/vulcand/predicate"
revision = "19b9dde14240d94c804ae5736ad0e1de10bf8fe6"
[[override]]
# remove override on master
name = "github.com/coreos/bbolt"
revision = "32c383e75ce054674c53b5a07e55de85332aee14"

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016-2017 Containous SAS
Copyright (c) 2016-2018 Containous SAS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -74,7 +74,7 @@ test-integration: build ## run the integration tests
TEST_HOST=1 ./script/make.sh test-integration
validate: build ## validate gofmt, golint and go vet
$(DOCKER_RUN_TRAEFIK) ./script/make.sh validate-glide validate-gofmt validate-govet validate-golint validate-misspell validate-vendor validate-autogen
$(DOCKER_RUN_TRAEFIK) ./script/make.sh validate-gofmt validate-govet validate-golint validate-misspell validate-vendor validate-autogen
build: dist
docker build $(DOCKER_BUILD_ARGS) -t "$(TRAEFIK_DEV_IMAGE)" -f build.Dockerfile .
@@ -127,5 +127,8 @@ fmt:
pull-images:
grep --no-filename -E '^\s+image:' ./integration/resources/compose/*.yml | awk '{print $$2}' | sort | uniq | xargs -P 6 -n 1 docker pull
prune-dep:
./script/prune-dep.sh
help: ## this help
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

View File

@@ -43,7 +43,7 @@ If you want your users to access some of your microservices from the Internet, y
- path `domain.com/web` will point the microservice `web` in your private network
- domain `backoffice.domain.com` will point the microservices `backoffice` in your private network, load-balancing between your multiple instances
But a microservices architecture is dynamic... Services are added, removed, killed or upgraded often, eventually several times a day.
Microservices are often deployed in dynamic environments where services are added, removed, killed, upgraded or scaled many times a day.
Traditional reverse-proxies are not natively dynamic. You can't change their configuration and hot-reload easily.

View File

@@ -24,6 +24,7 @@ type Account struct {
PrivateKey []byte
DomainsCertificate DomainsCertificates
ChallengeCerts map[string]*ChallengeCert
HTTPChallenge map[string]map[string][]byte
}
// ChallengeCert stores a challenge certificate

View File

@@ -7,6 +7,8 @@ import (
"fmt"
"io/ioutil"
fmtlog "log"
"net"
"net/http"
"os"
"regexp"
"strings"
@@ -14,6 +16,8 @@ import (
"github.com/BurntSushi/ty/fun"
"github.com/cenk/backoff"
"github.com/containous/flaeg"
"github.com/containous/mux"
"github.com/containous/staert"
"github.com/containous/traefik/cluster"
"github.com/containous/traefik/log"
@@ -33,25 +37,39 @@ var (
// ACME allows to connect to lets encrypt and retrieve certs
type ACME struct {
Email string `description:"Email address used for registration"`
Domains []Domain `description:"SANs (alternative domains) to each main domain using format: --acme.domains='main.com,san1.com,san2.com' --acme.domains='main.net,san1.net,san2.net'"`
Storage string `description:"File or key used for certificates storage."`
StorageFile string // deprecated
OnDemand bool `description:"Enable on demand certificate. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate."`
OnHostRule bool `description:"Enable certificate generation on frontends Host rules."`
CAServer string `description:"CA server to use."`
EntryPoint string `description:"Entrypoint to proxy acme challenge to."`
DNSProvider string `description:"Use a DNS based challenge provider rather than HTTPS."`
DelayDontCheckDNS int `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."`
ACMELogging bool `description:"Enable debug logging of ACME actions."`
client *acme.Client
defaultCertificate *tls.Certificate
store cluster.Store
challengeProvider *challengeProvider
checkOnDemandDomain func(domain string) bool
jobs *channels.InfiniteChannel
TLSConfig *tls.Config `description:"TLS config in case wildcard certs are used"`
dynamicCerts *safe.Safe
Email string `description:"Email address used for registration"`
Domains []Domain `description:"SANs (alternative domains) to each main domain using format: --acme.domains='main.com,san1.com,san2.com' --acme.domains='main.net,san1.net,san2.net'"`
Storage string `description:"File or key used for certificates storage."`
StorageFile string // deprecated
OnDemand bool `description:"Enable on demand certificate generation. This will request a certificate from Let's Encrypt during the first TLS handshake for a hostname that does not yet have a certificate."` //deprecated
OnHostRule bool `description:"Enable certificate generation on frontends Host rules."`
CAServer string `description:"CA server to use."`
EntryPoint string `description:"Entrypoint to proxy acme challenge to."`
DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge"`
HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge"`
DNSProvider string `description:"Use a DNS-01 acme challenge rather than TLS-SNI-01 challenge."` // deprecated
DelayDontCheckDNS flaeg.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."` // deprecated
ACMELogging bool `description:"Enable debug logging of ACME actions."`
client *acme.Client
defaultCertificate *tls.Certificate
store cluster.Store
challengeTLSProvider *challengeTLSProvider
challengeHTTPProvider *challengeHTTPProvider
checkOnDemandDomain func(domain string) bool
jobs *channels.InfiniteChannel
TLSConfig *tls.Config `description:"TLS config in case wildcard certs are used"`
dynamicCerts *safe.Safe
}
// DNSChallenge contains DNS challenge Configuration
type DNSChallenge struct {
Provider string `description:"Use a DNS-01 based challenge provider rather than HTTPS."`
DelayBeforeCheck flaeg.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."`
}
// HTTPChallenge contains HTTP challenge Configuration
type HTTPChallenge struct {
EntryPoint string `description:"HTTP challenge EntryPoint"`
}
//Domains parse []Domain
@@ -96,6 +114,20 @@ type Domain struct {
}
func (a *ACME) init() error {
// FIXME temporary fix, waiting for https://github.com/xenolf/lego/pull/478
acme.HTTPClient = http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 15 * time.Second,
ResponseHeaderTimeout: 15 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
},
}
if a.ACMELogging {
acme.Logger = fmtlog.New(os.Stderr, "legolog: ", fmtlog.LstdFlags)
} else {
@@ -107,15 +139,39 @@ func (a *ACME) init() error {
return err
}
a.defaultCertificate = cert
// TODO: to remove in the futurs
if len(a.StorageFile) > 0 && len(a.Storage) == 0 {
log.Warn("ACME.StorageFile is deprecated, use ACME.Storage instead")
a.Storage = a.StorageFile
}
a.jobs = channels.NewInfiniteChannel()
return nil
}
// AddRoutes add routes on internal router
func (a *ACME) AddRoutes(router *mux.Router) {
router.Methods(http.MethodGet).
Path(acme.HTTP01ChallengePath("{token}")).
Handler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if a.challengeHTTPProvider == nil {
rw.WriteHeader(http.StatusNotFound)
return
}
vars := mux.Vars(req)
if token, ok := vars["token"]; ok {
domain, _, err := net.SplitHostPort(req.Host)
if err != nil {
log.Debugf("Unable to split host and port: %v. Fallback to request host.", err)
domain = req.Host
}
tokenValue := a.challengeHTTPProvider.getTokenValue(token, domain)
if len(tokenValue) > 0 {
rw.WriteHeader(http.StatusOK)
rw.Write(tokenValue)
return
}
}
rw.WriteHeader(http.StatusNotFound)
}))
}
// CreateClusterConfig creates a tls.config using ACME configuration in cluster mode
func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tls.Config, certs *safe.Safe, checkOnDemandDomain func(domain string) bool) error {
err := a.init()
@@ -155,7 +211,7 @@ func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tl
}
a.store = datastore
a.challengeProvider = &challengeProvider{store: a.store}
a.challengeTLSProvider = &challengeTLSProvider{store: a.store}
ticker := time.NewTicker(24 * time.Hour)
leadership.Pool.AddGoCtx(func(ctx context.Context) {
@@ -171,69 +227,69 @@ func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tl
}
})
leadership.AddListener(func(elected bool) error {
if elected {
_, err := a.store.Load()
leadership.AddListener(a.leadershipListener)
return nil
}
func (a *ACME) leadershipListener(elected bool) error {
if elected {
_, err := a.store.Load()
if err != nil {
return err
}
transaction, object, err := a.store.Begin()
if err != nil {
return err
}
account := object.(*Account)
account.Init()
var needRegister bool
if account == nil || len(account.Email) == 0 {
account, err = NewAccount(a.Email)
if err != nil {
return err
}
transaction, object, err := a.store.Begin()
needRegister = true
}
a.client, err = a.buildACMEClient(account)
if err != nil {
return err
}
if needRegister {
// New users will need to register; be sure to save it
log.Debug("Register...")
reg, err := a.client.Register()
if err != nil {
return err
}
account := object.(*Account)
account.Init()
var needRegister bool
if account == nil || len(account.Email) == 0 {
account, err = NewAccount(a.Email)
if err != nil {
return err
}
needRegister = true
}
account.Registration = reg
}
// The client has a URL to the current Let's Encrypt Subscriber
// Agreement. The user will need to agree to it.
log.Debug("AgreeToTOS...")
err = a.client.AgreeToTOS()
if err != nil {
log.Debug(err)
// Let's Encrypt Subscriber Agreement renew ?
reg, err := a.client.QueryRegistration()
if err != nil {
return err
}
a.client, err = a.buildACMEClient(account)
if err != nil {
return err
}
if needRegister {
// New users will need to register; be sure to save it
log.Debug("Register...")
reg, err := a.client.Register()
if err != nil {
return err
}
account.Registration = reg
}
// The client has a URL to the current Let's Encrypt Subscriber
// Agreement. The user will need to agree to it.
log.Debug("AgreeToTOS...")
account.Registration = reg
err = a.client.AgreeToTOS()
if err != nil {
// Let's Encrypt Subscriber Agreement renew ?
reg, err := a.client.QueryRegistration()
if err != nil {
return err
}
account.Registration = reg
err = a.client.AgreeToTOS()
if err != nil {
log.Errorf("Error sending ACME agreement to TOS: %+v: %s", account, err.Error())
}
log.Errorf("Error sending ACME agreement to TOS: %+v: %s", account, err.Error())
}
err = transaction.Commit(account)
if err != nil {
return err
}
a.retrieveCertificates()
a.renewCertificates()
a.runJobs()
}
return nil
})
err = transaction.Commit(account)
if err != nil {
return err
}
a.retrieveCertificates()
a.renewCertificates()
a.runJobs()
}
return nil
}
@@ -253,7 +309,7 @@ func (a *ACME) CreateLocalConfig(tlsConfig *tls.Config, certs *safe.Safe, checkO
a.TLSConfig = tlsConfig
localStore := NewLocalStore(a.Storage)
a.store = localStore
a.challengeProvider = &challengeProvider{store: a.store}
a.challengeTLSProvider = &challengeTLSProvider{store: a.store}
var needRegister bool
var account *Account
@@ -337,7 +393,7 @@ func (a *ACME) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificat
return providedCertificate, nil
}
if challengeCert, ok := a.challengeProvider.getCertificate(domain); ok {
if challengeCert, ok := a.challengeTLSProvider.getCertificate(domain); ok {
log.Debugf("ACME got challenge %s", domain)
return challengeCert, nil
}
@@ -351,7 +407,7 @@ func (a *ACME) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificat
}
return a.loadCertificateOnDemand(clientHello)
}
log.Debugf("ACME got nothing %s", domain)
log.Debugf("No certificate found or generated for %s", domain)
return nil, nil
}
@@ -394,44 +450,27 @@ func (a *ACME) retrieveCertificates() {
func (a *ACME) renewCertificates() {
a.jobs.In() <- func() {
log.Debug("Testing certificate renew...")
log.Info("Testing certificate renew...")
account := a.store.Get().(*Account)
for _, certificateResource := range account.DomainsCertificate.Certs {
if certificateResource.needRenew() {
log.Debugf("Renewing certificate %+v", certificateResource.Domains)
renewedCert, err := a.client.RenewCertificate(acme.CertificateResource{
Domain: certificateResource.Certificate.Domain,
CertURL: certificateResource.Certificate.CertURL,
CertStableURL: certificateResource.Certificate.CertStableURL,
PrivateKey: certificateResource.Certificate.PrivateKey,
Certificate: certificateResource.Certificate.Certificate,
}, true, OSCPMustStaple)
log.Infof("Renewing certificate from LE : %+v", certificateResource.Domains)
renewedACMECert, err := a.renewACMECertificate(certificateResource)
if err != nil {
log.Errorf("Error renewing certificate: %v", err)
log.Errorf("Error renewing certificate from LE: %v", err)
continue
}
log.Debugf("Renewed certificate %+v", certificateResource.Domains)
renewedACMECert := &Certificate{
Domain: renewedCert.Domain,
CertURL: renewedCert.CertURL,
CertStableURL: renewedCert.CertStableURL,
PrivateKey: renewedCert.PrivateKey,
Certificate: renewedCert.Certificate,
operation := func() error {
return a.storeRenewedCertificate(account, certificateResource, renewedACMECert)
}
transaction, object, err := a.store.Begin()
notify := func(err error, time time.Duration) {
log.Warnf("Renewed certificate storage error: %v, retrying in %s", err, time)
}
ebo := backoff.NewExponentialBackOff()
ebo.MaxElapsedTime = 60 * time.Second
err = backoff.RetryNotify(safe.OperationWithRecover(operation), ebo, notify)
if err != nil {
log.Errorf("Error renewing certificate: %v", err)
continue
}
account = object.(*Account)
err = account.DomainsCertificate.renewCertificates(renewedACMECert, certificateResource.Domains)
if err != nil {
log.Errorf("Error renewing certificate: %v", err)
continue
}
if err = transaction.Commit(account); err != nil {
log.Errorf("Error Saving ACME account %+v: %s", account, err.Error())
log.Errorf("Datastore cannot sync: %v", err)
continue
}
}
@@ -439,16 +478,66 @@ func (a *ACME) renewCertificates() {
}
}
func dnsOverrideDelay(delay int) error {
func (a *ACME) renewACMECertificate(certificateResource *DomainsCertificate) (*Certificate, error) {
renewedCert, err := a.client.RenewCertificate(acme.CertificateResource{
Domain: certificateResource.Certificate.Domain,
CertURL: certificateResource.Certificate.CertURL,
CertStableURL: certificateResource.Certificate.CertStableURL,
PrivateKey: certificateResource.Certificate.PrivateKey,
Certificate: certificateResource.Certificate.Certificate,
}, true, OSCPMustStaple)
if err != nil {
return nil, err
}
log.Infof("Renewed certificate from LE: %+v", certificateResource.Domains)
return &Certificate{
Domain: renewedCert.Domain,
CertURL: renewedCert.CertURL,
CertStableURL: renewedCert.CertStableURL,
PrivateKey: renewedCert.PrivateKey,
Certificate: renewedCert.Certificate,
}, nil
}
func (a *ACME) storeRenewedCertificate(account *Account, certificateResource *DomainsCertificate, renewedACMECert *Certificate) error {
transaction, object, err := a.store.Begin()
if err != nil {
return fmt.Errorf("error during transaction initialization for renewing certificate: %v", err)
}
log.Infof("Renewing certificate in data store : %+v ", certificateResource.Domains)
account = object.(*Account)
err = account.DomainsCertificate.renewCertificates(renewedACMECert, certificateResource.Domains)
if err != nil {
return fmt.Errorf("error renewing certificate in datastore: %v ", err)
}
log.Infof("Commit certificate renewed in data store : %+v", certificateResource.Domains)
if err = transaction.Commit(account); err != nil {
return fmt.Errorf("error saving ACME account %+v: %v", account, err)
}
oldAccount := a.store.Get().(*Account)
for _, oldCertificateResource := range oldAccount.DomainsCertificate.Certs {
if oldCertificateResource.Domains.Main == certificateResource.Domains.Main && strings.Join(oldCertificateResource.Domains.SANs, ",") == strings.Join(certificateResource.Domains.SANs, ",") && certificateResource.Certificate != renewedACMECert {
return fmt.Errorf("renewed certificate not stored: %+v", certificateResource.Domains)
}
}
log.Infof("Certificate successfully renewed in data store: %+v", certificateResource.Domains)
return nil
}
func dnsOverrideDelay(delay flaeg.Duration) error {
var err error
if delay > 0 {
log.Debugf("Delaying %d seconds rather than validating DNS propagation", delay)
log.Debugf("Delaying %d rather than validating DNS propagation", delay)
acme.PreCheckDNS = func(_, _ string) (bool, error) {
time.Sleep(time.Duration(delay) * time.Second)
time.Sleep(time.Duration(delay))
return true, nil
}
} else if delay < 0 {
err = fmt.Errorf("Invalid negative DelayDontCheckDNS: %d", delay)
err = fmt.Errorf("invalid negative DelayBeforeCheck: %d", delay)
}
return err
}
@@ -464,25 +553,29 @@ func (a *ACME) buildACMEClient(account *Account) (*acme.Client, error) {
return nil, err
}
if len(a.DNSProvider) > 0 {
log.Debugf("Using DNS Challenge provider: %s", a.DNSProvider)
if a.DNSChallenge != nil && len(a.DNSChallenge.Provider) > 0 {
log.Debugf("Using DNS Challenge provider: %s", a.DNSChallenge.Provider)
err = dnsOverrideDelay(a.DelayDontCheckDNS)
err = dnsOverrideDelay(a.DNSChallenge.DelayBeforeCheck)
if err != nil {
return nil, err
}
var provider acme.ChallengeProvider
provider, err = dns.NewDNSChallengeProviderByName(a.DNSProvider)
provider, err = dns.NewDNSChallengeProviderByName(a.DNSChallenge.Provider)
if err != nil {
return nil, err
}
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.TLSSNI01})
err = client.SetChallengeProvider(acme.DNS01, provider)
} else if a.HTTPChallenge != nil && len(a.HTTPChallenge.EntryPoint) > 0 {
client.ExcludeChallenges([]acme.Challenge{acme.DNS01, acme.TLSSNI01})
a.challengeHTTPProvider = &challengeHTTPProvider{store: a.store}
err = client.SetChallengeProvider(acme.HTTP01, a.challengeHTTPProvider)
} else {
client.ExcludeChallenges([]acme.Challenge{acme.HTTP01, acme.DNS01})
err = client.SetChallengeProvider(acme.TLSSNI01, a.challengeProvider)
err = client.SetChallengeProvider(acme.TLSSNI01, a.challengeTLSProvider)
}
if err != nil {
@@ -590,7 +683,7 @@ func (a *ACME) LoadCertificateForDomains(domains []string) {
// Get provided certificate which check a domains list (Main and SANs)
// from static and dynamic provided certificates
func (a *ACME) getProvidedCertificate(domains []string) *tls.Certificate {
log.Debugf("Look for provided certificate to validate %s...", domains)
log.Debugf("Looking for provided certificate to validate %s...", domains)
cert := searchProvidedCertificateForDomains(domains, a.TLSConfig.NameToCertificate)
if cert == nil && a.dynamicCerts != nil && a.dynamicCerts.Get() != nil {
cert = searchProvidedCertificateForDomains(domains, a.dynamicCerts.Get().(*traefikTls.DomainsCertificates).Get().(map[string]*tls.Certificate))
@@ -626,7 +719,7 @@ func (a *ACME) getDomainsCertificates(domains []string) (*Certificate, error) {
certificate, failures := a.client.ObtainCertificate(domains, bundle, nil, OSCPMustStaple)
if len(failures) > 0 {
log.Error(failures)
return nil, fmt.Errorf("Cannot obtain certificates %s+v", failures)
return nil, fmt.Errorf("cannot obtain certificates %+v", failures)
}
log.Debugf("Loaded ACME certificates %s", domains)
return &Certificate{

43
acme/acme_example.json Normal file
View File

@@ -0,0 +1,43 @@
{
"Email": "test@traefik.io",
"Registration": {
"body": {
"resource": "reg",
"id": 3,
"key": {
"kty": "RSA",
"n": "y5a71suIqvEtovDmDVQ3SSNagk5IVCFI_TvqWpEXSrdbcDE2C-PTEtEUJuLkYwygcpiWYbPmXgdS628vQCw5Uo4DeDyHiuysJOWBLaWow3p9goOdhnPbGBq0liIR9xXyRoctdipVk8UiO9scWsu4jMBM3sMr7_yBWPfYYiLEQmZGFO3iE7Oqr55h_kncHIj5lUQY1j_jkftqxlxUB5_0quyJ7l915j5QY--eY7h4GEhRvx0TlUpi-CnRtRblGeDDDilXZD6bQN2962WdKecsmRaYx-ttLz6jCPXz2VDJRWNcIS501ne2Zh3hzw_DS6IRd2GIia1Wg4sisi9epC9sumXPHi6xzR6-_i_nsFjdtTkUcV8HmorOYoc820KQVZaLScxa8e7-ixpOd6mr6AIbEf7dBAkb9f_iK3GwpqKD8yNcaj1EQgNSyJSjnKSulXI_GwkGnuXe00Qpb1a8ha5Z8yWg7XmZZnJyAZrmK60RfwRNQ1rO5ioerNUBJ2KYTYNzVjBdob9Ug6Cjh4bEKNNjqcbjQ50_Z97Vw40xzpDQ_fYllc6n92eSuv6olxFJTmK7EhHuanDzITngaqei3zL9RwQ7P-1jfEZ03qmGrQYYqXcsS46PQ8cE-frzY2mKp16pRNCG7-03gKVGV0JHyW1aYbevNUk7OumCAXhC2YOigBk",
"e": "AQAB"
},
"contact": [
"mailto:test@traefik.io"
],
"agreement": "http://boulder:4000/terms/v1"
},
"uri": "http://127.0.0.1:4000/acme/reg/3",
"new_authzr_uri": "http://127.0.0.1:4000/acme/new-authz",
"terms_of_service": "http://boulder:4000/terms/v1"
},
"PrivateKey": "MIIJJwIBAAKCAgEAy5a71suIqvEtovDmDVQ3SSNagk5IVCFI/TvqWpEXSrdbcDE2C+PTEtEUJuLkYwygcpiWYbPmXgdS628vQCw5Uo4DeDyHiuysJOWBLaWow3p9goOdhnPbGBq0liIR9xXyRoctdipVk8UiO9scWsu4jMBM3sMr7/yBWPfYYiLEQmZGFO3iE7Oqr55h/kncHIj5lUQY1j/jkftqxlxUB5/0quyJ7l915j5QY++eY7h4GEhRvx0TlUpi+CnRtRblGeDDDilXZD6bQN2962WdKecsmRaYx+ttLz6jCPXz2VDJRWNcIS501ne2Zh3hzw/DS6IRd2GIia1Wg4sisi9epC9sumXPHi6xzR6+/i/nsFjdtTkUcV8HmorOYoc820KQVZaLScxa8e7+ixpOd6mr6AIbEf7dBAkb9f/iK3GwpqKD8yNcaj1EQgNSyJSjnKSulXI/GwkGnuXe00Qpb1a8ha5Z8yWg7XmZZnJyAZrmK60RfwRNQ1rO5ioerNUBJ2KYTYNzVjBdob9Ug6Cjh4bEKNNjqcbjQ50/Z97Vw40xzpDQ/fYllc6n92eSuv6olxFJTmK7EhHuanDzITngaqei3zL9RwQ7P+1jfEZ03qmGrQYYqXcsS46PQ8cE+frzY2mKp16pRNCG7+03gKVGV0JHyW1aYbevNUk7OumCAXhC2YOigBkCAwEAAQKCAgA8XW1EuwTC6tAFSDhuK1JZNUpY6K05hMUHkQRj5jFpzgQmt/C2hc7H/YZkIVJmrA/G6sdsINNlffZwKH9yH6q/d6w/snLeFl7UcdhjmIL5sxAT6sKCY0fLVd/FxERfZvp3Pw2Tw+mr7v+/j7BQm6cU1M/2HRiiB9SydIqMTpKyvXB6NC6ceOFbQTL9GxlQvKyEPbS/kiH/3vRB7I5d1GfPZmNfcp6ark9X0my8VK4HRSo36H8t/OhrfLrZXvh/O82aHVf0OTv/d8AgU/jNu+XVXoXegUfWglQFDChJf1KuaE+g5w1tqgFDNgkGRD475soXA6xgZi0Iw/B9tN3zALzT4IiAW1q72feeTgKOMA2zGtKXxQZZSOV+DuWFZNz/tT7XqGQThqxM09CHv2WGOe80vobtegXYTUt90hysrqIZmBW5XYdzQlJh1KWTtfCaTrWd47kbGvhkEPc8aA3Ji4/AqfkVXiqwaLu+MSlgzPpRj7U7UAIDqnpZjgttgLp74Ujnk3bTaUzdyyNqYDBG3IFGr/Sv+2GQDAUn/PYRJKWr0BteqOzX9zvW3zY8g9CYVXfK/AW3RMWLV8ly6vH/gWqa9gEuzRNRlzjUU6/HCVbUx3UT8RMWH2TQ0uuQZr5JX1iTwjeeT0dEIly1NnRQC92wcrE4UUTBEF3krGVpDBf0AQKCAQEA4jB8w+2fwzbF8X+gCODcY7sTeJRunzGy+jbdaLkcThuylga+6W3ZgWx0BD30ql9K2mouCVu86fCTnBeXXEC3QoTdgw/EzJ83+4JU3QSDdzs9Ta9vLHyvrpUkQfZ8UZpeLLmFsmsBMbBbnfw0S1TzXDsgrAc+G4tia8nO/Iqu75kEMGzmHQAvmN3iSqc1aTS4qumbB19g+v+csq9NEht4F9jt39KotG+OD3MxCxtMu7vxAkJRjFFcgcbb2Rtqe/kQEKA1vLEAJg27lV4k8XibCSerVUR6IzT8WZHrNiXmpRguTLl2k8uFUdCOOx6aLGyRVJ6+8SgIsMR540vnxwQzEQKCAQEA5mu2wtWT19mvXopC3easPsXIPzc5oaRkqfWZYT1KHcVQ7NIXsE3vCjcf/3igZ8l/FVQ4G4fpk/GoTqlpV5Aq/JHCpVOR2O69uB+W4kWgliejpHvF9gszzAYnC8lIXqDbWiinBhmm3ii8sDGAoBaSDw5NMUq3mI+nd8zZ+jx1bLBczDafmQ0YKr8k0YaROxIgoBgDOQDdSqG387lwzpza2DKI5Al3HfS42zjT0RmBahPiuT2aEoUZmIYuvFY0fEjfkpbdvLyexHfZCILRUGlG1nAwASFg86lp+mFSBJ3E3cvbP0CpbFGxon5u4Ao3/7htoOh6huh7MQ91h41fv1hsiQKCAQAe7WRR4e7jYVzlbX7zV9Oqq0y5QwpxJ/mB7viNNiphn7Xmf5uhDU0dPjgK0HHgzdDNVpFe5DVLg4KbaDpg+dRU+xfSsNhG5kpgUGzMH67eIbJ7Kc64tX/MDkZ74nkTK1lPIjrer3TlV2jfjDmWR1JTPR51hzP9ziwx8tEjhM7woeqJuIoqUvkvHL+xV3WdIgFSFUkGVAtNpp/FauTN4gWktRupbAN3UH2LLUP6ccwnK0aD+Y9u8T0F3av33qDLvL1umIlgeI89pMkOXmYMwmHoeY0axpcwszECCkqwB7SmxEyoXv+Qq9ZZ3ntkKAYKpvmkKWSQUtoFWYgVBS727mMRAoIBABLdwusU/bPwuPEutObiWjwRiaHTbb6UbUGVQGe70vO5EjUxxorC9s2JUe9i+w9EakleyfFHIZLheHxoVp26yio/7QYIX6q5cYM/4uTH+qwQts9i6wSISkdsQYovguNsnEk3huVy+Dy8bSaoBvYUowTkkOF2Uq4FJRskBLz+ckbh8dcuqcaoUdA+Mk+NixqhE1bIYIssTPItZ5hnGJtyMGD/UkIJnF0ximk4r+8w/W2oDypHpvPZPg1E/1KgZE/Az7166NDpSL6haX3O6ECDPi+Uo/mTuBJ7TpgXm9WQ7WuTo3H8Y2LhFYBOhdmGPKuNeDxyjIW7R0rvDxp4MtzB6rECggEAJIl7/qp1lxUQPQJRTsEYBkOtdRw0IGG1Rcj0emhHaBN05c9opCy+Osb7mVeU5ZiULe5kD02phL+36pEumprz7QzN46Y5pZc8AQ2W/QkeL4Wo9U9QzczvQQzc1EqrBkzvQTZtBhn4DRzz0IuTn1beVyHtBZeNpBFgMQFv9VYQuUNwFoTOkkQrBRnYbXH6KEnhF3c/1Hzi4KHVdHdfZ3LH7KFQJ34xio0q2tWQSQYeybmwOXdd9sxpz/Y4KBS9fqm7UrwnPK8yuOc05HLEaws+1iam5YyJprlQo3mGKe0wRztwn44HDeQr70LlFm0lzigVAv0hSiWO1Q5hJL7nDu8m/Q==",
"DomainsCertificate": {
"Certs": [
{
"Domains": {
"Main": "local1.com",
"SANs": [
"test1.local1.com",
"test2.local1.com"
]
},
"Certificate": {
"Domain": "local1.com",
"CertURL": "http://127.0.0.1:4000/acme/cert/ffc4f3f14def9ee6ec6a0522b5c0baa3379d",
"CertStableURL": "",
"PrivateKey": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS1FJQkFBS0NBZ0VBdVNoTTR4enF6cE5YcFNaNnAvZnQrRmt5VmgyK1BSZXJUelV0OERRSng2UkVjQS9FCnN2RnNIVmNOSkZMS2twYTNlOEd3SUZBakJQNnJPK3hoR1JjWlJrdENON1gyOW5LZFhGbHZkYzJxd0hyTFF5WWkKTTB3ODhTck41VERiNi96TWU2dTB0dERiYWtDbDd6ZEJKUXJ6a1h5ZU1MeVkzTUs3aVkrMHpwL2JqMVhvbk5DdQpaQStkZ3hsMVNrV01DVUYvQk9HNWFyT1hwb0x4S0dQWGdzV3hOTVNLVmJKSHczL3ZqNTViZU92Um5lT3BNWlhvCmMwOWpZT3VBakNka1Z5czBSWHJLNWNCRDRMbVRXdnN4MFdTK2VMVHlGTTdQTHVZM3lEWkNNWEhjVmlqRHhnbFMKYjB1ZVRQcGFUWEQwYkxqZ0RNOUVEdE15ZEJzMUNPWlpPWG9ickN5Q2I1eWxTOFdVd1NzVXM1UldxZnlVbnAvcgpSNGx2c2RZOWRVZjRPdkNMVnJvWWk5NWFGc1Zxa0xLOExuL0Eyc3kxYWlDTnR4RmpKOXRXbWU0V0NhdzRoU0YvCkR4NWVNNWNYR2JSYXduVlZJQlZXeHhzNTBPMFJlUWRvbXBQZEFNS1RDWk9SRmxYaDdOWTdxQVdWRGtpdzhyam8Kekd3Ni9XdjlOR3hTNTliKzc0YVAxcjBxOTZ2RS9Rdi8zTCtjbjhiN0lBLytPYmFKdzhIT3RGbXc4RjBxQkN3MAprYWVVSloxb1JueGFYQUo4RHhHREpFOVdNUzh0QmJtVm16YkxoRkMzeDdVc0xGeTBrSzh1SFBFT3dQb2NKNUFUCkE1UHBvclNEMmFleHA0Z3VqYVp5c1JManpmY0dnaTdva0JFNlZVNWVqRE1iYS9lNERQNEJQUVg5VmtVQ0F3RUEKQVFLQ0FnQmZjMWdYcUp1ZmZMT3REcVlpbXh4UmIrSVVKT2NpWldaSndmZDVvY244NGtEcHFDZFZ2RUZvNnF4NgpzamQ5MURhb2xOUHdCSC9aSGxRMTR3aTNQNEluQzdzS0wwTXVEeTN5SXFUa0RPOWVwSzdPWWdVMWZyTFgvS0lCCjZlc2x2Ny9HYldFTzhhSjdKdktqM0U4NEFtcEg4UDgzenJIYTlJUnJTT3NEcmNNcEpEZHpSOXp1OW1IVDZMYmYKWC9UdC9KYTNkSW42YUxUZ0FSYkRKSjAvN0J3TFFOcXpqT0dUOWdzUWRhbGdMK2x5eEo4L1ViRndhRmVwNmgzdApvbzBHcHQ0ZWgwdTdueDhlNVd3Q2RnWmJsTnpnS3grMC9Gd3dLRHhQZVRFc2ZpOEJONmlkR2NjbVdzd3prTWdtCnJmbERaeGNSWTNRSlZIVHBCL0dTTWZXRFBPQ3dRdGltQk1WN3kxM2hPMTdPWXpSNDBMZnpUalJBbmtna2V2eWYKcFowb3dLR3o4QS9haHhRWWJmYVQ5VEhXV0wrYUpYeUhFanBKckp5aTg3UExVbzhsOFVydU56MDRWNXpLOFJPbgo2cG9EWmVtbm1EYWRlU09pK3hZRWlGT1NwSXNWbzlpcm9jUGFKN2YzYWpiNUU4RHpuN1o1MmhzL2R6akpLcFZJCm5mVDFkUU9SZEowSXRUNlRlQ2RTL0dpS25IS1RtNjR2T21IbmlJcm8rUGRhUmFjV0IrTUJ0VytRd0cyUStyRGkKc3g4NlpQbHRpTVpLMDZ5TVlyVHZUdGk2aFVGaUY5cWh4b3RGazdNQkNrZlIwYUVhaUREQUpKNm1jb1lpRUQ2QgpBVGJhVmpVaGNaUiswYkRST25PN0ozRk5rZmx3K2dMaVhvcXFRRW9pU2ZWb2h5SWY3UUtDQVFFQThjYTM5K0g4CjN3L2Qrcm0yUGNhM0RMQnBYaWU4Z3ZYcGpjazVYSkpvSGVmbnJjZWQrcFpXaTZEYncwYld0MEdtYkxmVjJNSlAKV2I1aTZzSXhmdkN3YlFqbHY0UnExMVA5ZEswT3poMnVpKzZ6cXVBMG5YTVcrN0lJS0cvdDhmS2NJZGRRNnRGcwpFclFVTFBDak56ODA2cHBiSlhPRmVvMW1BK293TGhHNlA3dDhCdlZHSk1NaTNxejNlSUNuVVE2eDNFY01ITXNuClhrM21DUzI1WUZaNk96cytFK254cGVraTAzZmQwblp3UE1jdElHZys1c3hleE9zREsrTHlvb2FqQnc5N0oyUzIKcUNNWXFtT0tLcmxEQ3Y1WmQ4dlZLN3hXVmpKRVhGTTNMZ2pieHBRcCtuVXNVVWxwS01LOVlGS0lRREl0RU9aMApWcWExTXJaOElzN1l5d0tDQVFFQXhBemZIa2pIVGlvTHdZbG5EcEk0MWlOTDh5Y0ZBallrTC94dWhPU2tlVkE4CjdRWDZPZUpDekR3Z0FUYXVqOWR6Y0wwby9yTndWV0xWcnQ3OXk3YnJvVDdFREZKWVNTY25GRXNMTlVWSXRncGkKckNSUXJTL1F2TkVGTmE5K0pRc1dmYkdBNHdIUTFaSjI4MFp1cWMvNlEyUi9kZVh3cUZBQVBHN2NIcEhHWlR6ZQoyRmFRUHFLRkV4WlEyZkpvRys0SVBRNHVQVERybXlGMmVUWXk2T3BaaDBHbWJRYlVTa1dFWDlQRmF1cHJIWVdGCk8wK25DaVVPNVRaMFZoaGR2dUNKMWdPclZHYzhBUlJtUVZ1aUNEWTZCaGlvVTU0ZmZsSXlDTXZ5a3MwcmRXZ3MKWVJ2TmN4TXNlRGJpTDRKSURkMHhiN1d4VUdmVjRVNHZPMks5Vms1N0x3S0NBUUVBMkd1eE1jcXd1RnRUc0tPYwpaaUFDcXZFZTRKRmhSVGtySHlnSW1MelZSaS9ZU3M1c3MycnZmWDA0T3N5bVZ0UUZUVHdoeUMzbktjWXFkVW52ClZGblBFMHJyblV2Qzk0elBUQ205SHZPaTBzK1JORndOdlFMUWgrME5NR1ZBOFZyaU44aXRQZ1RJWU5XaFdianQKNFA1TE45V0QwVHBmT1J4cFBRZmNxT0JsZjdjcmhtNzNvdUNwemZtMmE3OStCaWpKUFF5NzR1cFhDeXRmeHNlUApNSlU0Uk56NjdJaDFMclpKM2xGbDFvYitZT2xKazhDOHpZd1RLT0hWck9zeGxobyt4SXN2Q2t3MDFMelZ6Mi9hCnRmT3Y5NTlHSnQzbXE0ZWpJUFZPQy9iUlpmdTMvMEdSY2dpQTZ5SnpaM0VxWTVaOU1EbTU3VzdjcE5RRlRxZmEKNXEyUmtRS0NBUUErNGhZSzQ3TXg2aUNkTWxKaEJSdS82OUJucktOWm96NFdPalRFNFlXejk3MmpGU0Mrd2tsRQpzeUJjNDBvNGp4WFRHb2wwc04rZU03WndnY3dNTko3OXVHRXZ4cFhVMlA4YTdqc3BHaEVKZXVsTlo5U015R0orCnZkaWE4TEJZZDJiK2FCbjhOay9pd1Rqd0xTNC92NXI1Vk5uaFdpRElDK2tYZVVPWGRwQ1pWbDN3TEV2V0cxRHQKMzJHTmxzZzM5VENsVE5BZUJudjc1VTdYOEQrQ0gvRVpoa0E0aGxFL2hXN0JRZTczclRzd1creHhLc3BjWWFpVwpjdEg3NzVMYUw3Rm1lUVRTYk01OVZpcTZXZ2J0OVY3Rko5R09DSkQzZHF2ZjBITDlEVndjSzQ3WWt3OWlFc3RYCnY5cnEvREhhYUpGNzBGNlFlTTNNbDhSa212WTZJYkEzQW9JQkFRRGt6RmZLeG9HQ3dWUDlua3k4NmFQSjFvd2kKc2FDZEx6RjRWTENRZzkrUXJITzEyY0p5MFFQUnJ2cUQyMGp1cDFlOWJhWVZzbkdYc1FZTFg2NVR6UzJSSCtlSAp6S0NPTTdnMVE3djMxNWpjMDMvN1lQck4rb3RrV0VBOUkyaDZjUE1vY3c0aERTNk02OFlxQVlKTS9RclVhenZhCnhBTFJaZEVkQW1xWDA4VHhuY1hRUEVxYkk0ZnlSZ2pVM1BYR3RRaFFFbERpR2kwbThjQTJNTXdsR1RmbTdOSXgKaENjZ2ZkL296TEp2VUhiMkxLRi82cXEySmJVRHlOMkVoK0xSZUJjdnp6Y1grZE5MdGQxY0Uvcm1SM2hMbWxmNgo3KzRpTVMxK0t1eWV3VlJVUEE1c1F1aUYyVUVoeEs1MUpZK1FpOG9HbERKdGRrOXB3QlZNN1F0WW9KVEwKLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K",
"Certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZvakNDQklxZ0F3SUJBZ0lUQVAvRTgvRk43NTdtN0dvRklyWEF1cU0zblRBTkJna3Foa2lHOXcwQkFRc0YKQURBZk1SMHdHd1lEVlFRRERCUm9NbkJ3ZVNCb01tTnJaWElnWm1GclpTQkRRVEFlRncweE9EQXhNVFV3TnpJNQpNREJhRncweE9EQTBNVFV3TnpJNU1EQmFNRVF4RXpBUkJnTlZCQU1UQ214dlkyRnNNUzVqYjIweExUQXJCZ05WCkJBVVRKR1ptWXpSbU0yWXhOR1JsWmpsbFpUWmxZelpoTURVeU1tSTFZekJpWVdFek16YzVaRENDQWlJd0RRWUoKS29aSWh2Y05BUUVCQlFBRGdnSVBBRENDQWdvQ2dnSUJBTGtvVE9NYzZzNlRWNlVtZXFmMzdmaFpNbFlkdmowWApxMDgxTGZBMENjZWtSSEFQeExMeGJCMVhEU1JTeXBLV3QzdkJzQ0JRSXdUK3F6dnNZUmtYR1VaTFFqZTE5dlp5Cm5WeFpiM1hOcXNCNnkwTW1Jak5NUFBFcXplVXcyK3Y4ekh1cnRMYlEyMnBBcGU4M1FTVUs4NUY4bmpDOG1OekMKdTRtUHRNNmYyNDlWNkp6UXJtUVBuWU1aZFVwRmpBbEJmd1RodVdxemw2YUM4U2hqMTRMRnNUVEVpbFd5UjhOLwo3NCtlVzNqcjBaM2pxVEdWNkhOUFkyRHJnSXduWkZjck5FVjZ5dVhBUStDNWsxcjdNZEZrdm5pMDhoVE96eTdtCk44ZzJRakZ4M0ZZb3c4WUpVbTlMbmt6NldrMXc5R3k0NEF6UFJBN1RNblFiTlFqbVdUbDZHNndzZ20rY3BVdkYKbE1FckZMT1VWcW44bEo2ZjYwZUpiN0hXUFhWSCtEcndpMWE2R0l2ZVdoYkZhcEN5dkM1L3dOck10V29namJjUgpZeWZiVnBudUZnbXNPSVVoZnc4ZVhqT1hGeG0wV3NKMVZTQVZWc2NiT2REdEVYa0hhSnFUM1FEQ2t3bVRrUlpWCjRleldPNmdGbFE1SXNQSzQ2TXhzT3Yxci9UUnNVdWZXL3UrR2o5YTlLdmVyeFAwTC85eS9uSi9HK3lBUC9qbTIKaWNQQnpyUlpzUEJkS2dRc05KR25sQ1dkYUVaOFdsd0NmQThSZ3lSUFZqRXZMUVc1bFpzMnk0UlF0OGUxTEN4Ywp0SkN2TGh6eERzRDZIQ2VRRXdPVDZhSzBnOW1uc2FlSUxvMm1jckVTNDgzM0JvSXU2SkFST2xWT1hvd3pHMnYzCnVBeitBVDBGL1ZaRkFnTUJBQUdqZ2dHd01JSUJyREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdIUVlEVlIwbEJCWXcKRkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ01Bd0dBMVVkRXdFQi93UUNNQUF3SFFZRFZSME9CQllFRk5LZQpBVUZYc2Z2N2lML0lYVVBXdzY2ZU5jQnhNQjhHQTFVZEl3UVlNQmFBRlB0NFR4TDVZQldETEo4WGZ6UVpzeTQyCjZrR0pNR1lHQ0NzR0FRVUZCd0VCQkZvd1dEQWlCZ2dyQmdFRkJRY3dBWVlXYUhSMGNEb3ZMekV5Tnk0d0xqQXUKTVRvME1EQXlMekF5QmdnckJnRUZCUWN3QW9ZbWFIUjBjRG92THpFeU55NHdMakF1TVRvME1EQXdMMkZqYldVdgphWE56ZFdWeUxXTmxjblF3T1FZRFZSMFJCREl3TUlJS2JHOWpZV3d4TG1OdmJZSVFkR1Z6ZERFdWJHOWpZV3d4CkxtTnZiWUlRZEdWemRESXViRzlqWVd3eExtTnZiVEFuQmdOVkhSOEVJREFlTUJ5Z0dxQVloaFpvZEhSd09pOHYKWlhoaGJYQnNaUzVqYjIwdlkzSnNNR0VHQTFVZElBUmFNRmd3Q0FZR1o0RU1BUUlCTUV3R0F5b0RCREJGTUNJRwpDQ3NHQVFVRkJ3SUJGaFpvZEhSd09pOHZaWGhoYlhCc1pTNWpiMjB2WTNCek1COEdDQ3NHQVFVRkJ3SUNNQk1NCkVVUnZJRmRvWVhRZ1ZHaHZkU0JYYVd4ME1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ3A0Q2FxZlR4THNQTzQKS2JueDJZdEc4bTN3MC9keTVVR1VRNjZHbGxPVTk0L2I0MmNhbTRuNUZrTWlpZ01IaUx4c2JZVXh0cDZKQ3R5cQpLKzFNcDFWWEtSTTVKbFBTNWRIaWhxdHk1U3BrTUhjampwQSs3U2YyVWtoNmpKRWYxTUVJY2JnWnpJRk5IT0hYClVUUUppVFhKcno3blJDZnlQWFZtbWErUGtIRlU4R0VEVzJGOVptU1kzVFBiQWhiWkV2UkZubjUrR1lxbkZuancKWWw3Y0I2MXYwRzVpOGQwbnVvbTB4a2hiNTU3Y3BiZHhLblhsaFU4N2RZSTR5SUdPdUFGUWpYcXFXN2NIZCtXUQpWSDB2dFA3cEgrRmt2YnY4WkkxMHMrNU5ZcCtzZjFQZGQxekJsRmdNSGF3dnFFYUg3SU9sejdkajlCdmtVc0dpClhxQWVqQnFPCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVpakNDQTNLZ0F3SUJBZ0lDRWswd0RRWUpLb1pJaHZjTkFRRUxCUUF3S3pFcE1DY0dBMVVFQXd3Z1kyRmoKYTJ4cGJtY2dZM0o1Y0hSdlozSmhjR2hsY2lCbVlXdGxJRkpQVDFRd0hoY05NVFV4TURJeE1qQXhNVFV5V2hjTgpNakF4TURFNU1qQXhNVFV5V2pBZk1SMHdHd1lEVlFRREV4Um9ZWEJ3ZVNCb1lXTnJaWElnWm1GclpTQkRRVENDCkFTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTUlLUjNtYUJjVVNzbmNYWXpRVDEzRDUKTnIrWjNtTHhNTWgzVFVkdDZzQUNtcWJKMGJ0UmxnWGZNdE5MTTJPVTFJNmEzSnUrdElaU2RuMnYyMUpCd3Z4VQp6cFpRNHp5MmNpbUlpTVFEWkNRSEp3ekM5R1puOEhhVzA5MWl6OUgwR28zQTdXRFh3WU5tc2RMTlJpMDBvMTRVCmpvYVZxYVBzWXJaV3ZSS2FJUnFhVTBoSG1TMEFXd1FTdk4vOTNpTUlYdXlpd3l3bWt3S2JXbm54Q1EvZ3NjdEsKRlV0Y05yd0V4OVdnajZLbGh3RFR5STFRV1NCYnhWWU55VWdQRnpLeHJTbXdNTzB5TmZmN2hvK1FUOXg1K1kvNwpYRTU5UzRNYzRaWHhjWEtldy9nU2xOOVU1bXZUK0QyQmhEdGtDdXBkZnNaTkNRV3AyN0ErYi9EbXJGSTlOcXNDCkF3RUFBYU9DQWNJd2dnRytNQklHQTFVZEV3RUIvd1FJTUFZQkFmOENBUUF3UXdZRFZSMGVCRHd3T3FFNE1BYUMKQkM1dGFXd3dDb2NJQUFBQUFBQUFBQUF3SW9jZ0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQpBQUFBQUFBd0RnWURWUjBQQVFIL0JBUURBZ0dHTUg4R0NDc0dBUVVGQndFQkJITXdjVEF5QmdnckJnRUZCUWN3CkFZWW1hSFIwY0RvdkwybHpjbWN1ZEhKMWMzUnBaQzV2WTNOd0xtbGtaVzUwY25WemRDNWpiMjB3T3dZSUt3WUIKQlFVSE1BS0dMMmgwZEhBNkx5OWhjSEJ6TG1sa1pXNTBjblZ6ZEM1amIyMHZjbTl2ZEhNdlpITjBjbTl2ZEdOaAplRE11Y0Rkak1COEdBMVVkSXdRWU1CYUFGT21rUCs2ZXBlYnkxZGQ1WUR5VHBpNGtqcGVxTUZRR0ExVWRJQVJOCk1Fc3dDQVlHWjRFTUFRSUJNRDhHQ3lzR0FRUUJndDhUQVFFQk1EQXdMZ1lJS3dZQkJRVUhBZ0VXSW1oMGRIQTYKTHk5amNITXVjbTl2ZEMxNE1TNXNaWFJ6Wlc1amNubHdkQzV2Y21jd1BBWURWUjBmQkRVd016QXhvQytnTFlZcgphSFIwY0RvdkwyTnliQzVwWkdWdWRISjFjM1F1WTI5dEwwUlRWRkpQVDFSRFFWZ3pRMUpNTG1OeWJEQWRCZ05WCkhRNEVGZ1FVKzNoUEV2bGdGWU1zbnhkL05CbXpMamJxUVlrd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFBMFkKQWVMWE9rbHg0aGhDaWtVVWwrQmRuRmZuMWcwVzVBaVFMVk5JT0w2UG5xWHUwd2puaE55aHFkd25maFlNbm95NAppZFJoNGxCNnB6OEdmOXBubExkL0RuV1NWM2dTKy9JL21BbDFkQ2tLYnk2SDJWNzkwZTZJSG1JSzJLWW0zam0rClUrK0ZJZEdwQmRzUVRTZG1pWC9yQXl1eE1ETTBhZE1rTkJ3VGZRbVpRQ3o2bkdIdzFRY1NQWk12WnBzQzhTa3YKZWt6eHNqRjFvdE9yTVVQTlBRdnRUV3JWeDhHbFIycWZ4LzR4YlFhMXYyZnJOdkZCQ21PNTlnb3oram5XdmZUdApqMk5qd0RaN3ZsTUJzUG0xNmRiS1lDODQwdXZSb1pqeHFzZGMzQ2hDWmpxaW1GcWxORy94b1BBOCtkVGljWnpDClhFOWlqUEljdlc2eTFhYTNiR3c9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
}
}
]
},
"ChallengeCerts": {}
}

View File

@@ -267,7 +267,7 @@ cijFkALeQp/qyeXdFld2v9gUN3eCgljgcl0QweRoIc=---`)
}`))
}))
defer ts.Close()
a := ACME{DNSProvider: "manual", DelayDontCheckDNS: 10, CAServer: ts.URL}
a := ACME{DNSChallenge: &DNSChallenge{Provider: "manual", DelayBeforeCheck: 10}, CAServer: ts.URL}
client, err := a.buildACMEClient(account)
if err != nil {

View File

@@ -0,0 +1,92 @@
package acme
import (
"fmt"
"sync"
"time"
"github.com/cenk/backoff"
"github.com/containous/traefik/cluster"
"github.com/containous/traefik/log"
"github.com/containous/traefik/safe"
"github.com/xenolf/lego/acme"
)
var _ acme.ChallengeProviderTimeout = (*challengeHTTPProvider)(nil)
type challengeHTTPProvider struct {
store cluster.Store
lock sync.RWMutex
}
func (c *challengeHTTPProvider) getTokenValue(token, domain string) []byte {
log.Debugf("Looking for an existing ACME challenge for token %v...", token)
c.lock.RLock()
defer c.lock.RUnlock()
account := c.store.Get().(*Account)
if account.HTTPChallenge == nil {
return []byte{}
}
var result []byte
operation := func() error {
var ok bool
if result, ok = account.HTTPChallenge[token][domain]; !ok {
return fmt.Errorf("cannot find challenge for token %v", token)
}
return nil
}
notify := func(err error, time time.Duration) {
log.Errorf("Error getting challenge for token retrying in %s", time)
}
ebo := backoff.NewExponentialBackOff()
ebo.MaxElapsedTime = 60 * time.Second
err := backoff.RetryNotify(safe.OperationWithRecover(operation), ebo, notify)
if err != nil {
log.Errorf("Error getting challenge for token: %v", err)
return []byte{}
}
return result
}
func (c *challengeHTTPProvider) Present(domain, token, keyAuth string) error {
log.Debugf("Challenge Present %s", domain)
c.lock.Lock()
defer c.lock.Unlock()
transaction, object, err := c.store.Begin()
if err != nil {
return err
}
account := object.(*Account)
if account.HTTPChallenge == nil {
account.HTTPChallenge = map[string]map[string][]byte{}
}
if _, ok := account.HTTPChallenge[token]; !ok {
account.HTTPChallenge[token] = map[string][]byte{}
}
account.HTTPChallenge[token][domain] = []byte(keyAuth)
return transaction.Commit(account)
}
func (c *challengeHTTPProvider) CleanUp(domain, token, keyAuth string) error {
log.Debugf("Challenge CleanUp %s", domain)
c.lock.Lock()
defer c.lock.Unlock()
transaction, object, err := c.store.Begin()
if err != nil {
return err
}
account := object.(*Account)
if _, ok := account.HTTPChallenge[token]; ok {
if _, domainOk := account.HTTPChallenge[token][domain]; domainOk {
delete(account.HTTPChallenge[token], domain)
}
if len(account.HTTPChallenge[token]) == 0 {
delete(account.HTTPChallenge, token)
}
}
return transaction.Commit(account)
}
func (c *challengeHTTPProvider) Timeout() (timeout, interval time.Duration) {
return 60 * time.Second, 5 * time.Second
}

View File

@@ -23,15 +23,15 @@ import (
"github.com/xenolf/lego/acme"
)
var _ acme.ChallengeProviderTimeout = (*challengeProvider)(nil)
var _ acme.ChallengeProviderTimeout = (*challengeTLSProvider)(nil)
type challengeProvider struct {
type challengeTLSProvider struct {
store cluster.Store
lock sync.RWMutex
}
func (c *challengeProvider) getCertificate(domain string) (cert *tls.Certificate, exists bool) {
log.Debugf("Challenge GetCertificate %s", domain)
func (c *challengeTLSProvider) getCertificate(domain string) (cert *tls.Certificate, exists bool) {
log.Debugf("Looking for an existing ACME challenge for %s...", domain)
if !strings.HasSuffix(domain, ".acme.invalid") {
return nil, false
}
@@ -67,7 +67,7 @@ func (c *challengeProvider) getCertificate(domain string) (cert *tls.Certificate
return result, true
}
func (c *challengeProvider) Present(domain, token, keyAuth string) error {
func (c *challengeTLSProvider) Present(domain, token, keyAuth string) error {
log.Debugf("Challenge Present %s", domain)
cert, _, err := tlsSNI01ChallengeCert(keyAuth)
if err != nil {
@@ -88,7 +88,7 @@ func (c *challengeProvider) Present(domain, token, keyAuth string) error {
return transaction.Commit(account)
}
func (c *challengeProvider) CleanUp(domain, token, keyAuth string) error {
func (c *challengeTLSProvider) CleanUp(domain, token, keyAuth string) error {
log.Debugf("Challenge CleanUp %s", domain)
c.lock.Lock()
defer c.lock.Unlock()
@@ -101,7 +101,7 @@ func (c *challengeProvider) CleanUp(domain, token, keyAuth string) error {
return transaction.Commit(account)
}
func (c *challengeProvider) Timeout() (timeout, interval time.Duration) {
func (c *challengeTLSProvider) Timeout() (timeout, interval time.Duration) {
return 60 * time.Second, 5 * time.Second
}

41
acme/localStore_test.go Normal file
View File

@@ -0,0 +1,41 @@
package acme
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)
func TestLoad(t *testing.T) {
acmeFile := "./acme_example.json"
folder, prefix := filepath.Split(acmeFile)
tmpFile, err := ioutil.TempFile(folder, prefix)
defer os.Remove(tmpFile.Name())
if err != nil {
t.Error(err)
}
fileContent, err := ioutil.ReadFile(acmeFile)
if err != nil {
t.Error(err)
}
tmpFile.Write(fileContent)
localStore := NewLocalStore(tmpFile.Name())
obj, err := localStore.Load()
if err != nil {
t.Error(err)
}
account, ok := obj.(*Account)
if !ok {
t.Error("Object is not an ACME Account")
}
if len(account.DomainsCertificate.Certs) != 1 {
t.Errorf("Must found %d and found %d certificates in Account", 3, len(account.DomainsCertificate.Certs))
}
}

View File

@@ -15,7 +15,7 @@ type DashboardHandler struct{}
func (g DashboardHandler) AddRoutes(router *mux.Router) {
// Expose dashboard
router.Methods(http.MethodGet).Path("/").HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
http.Redirect(response, request, "/dashboard/", 302)
http.Redirect(response, request, request.Header.Get("X-Forwarded-Prefix")+"/dashboard/", 302)
})
router.Methods(http.MethodGet).PathPrefix("/dashboard/").
Handler(http.StripPrefix("/dashboard/", http.FileServer(&assetfs.AssetFS{Asset: genstatic.Asset, AssetInfo: genstatic.AssetInfo, AssetDir: genstatic.AssetDir, Prefix: "static"})))

View File

@@ -38,9 +38,9 @@ func (g DebugHandler) AddRoutes(router *mux.Router) {
fmt.Fprint(w, "\n}\n")
})
router.Methods(http.MethodGet).PathPrefix("/debug/pprof/").HandlerFunc(pprof.Index)
router.Methods(http.MethodGet).PathPrefix("/debug/pprof/cmdline").HandlerFunc(pprof.Cmdline)
router.Methods(http.MethodGet).PathPrefix("/debug/pprof/profile").HandlerFunc(pprof.Profile)
router.Methods(http.MethodGet).PathPrefix("/debug/pprof/symbol").HandlerFunc(pprof.Symbol)
router.Methods(http.MethodGet).PathPrefix("/debug/pprof/trace").HandlerFunc(pprof.Trace)
router.Methods(http.MethodGet).PathPrefix("/debug/pprof/").HandlerFunc(pprof.Index)
}

View File

@@ -19,9 +19,9 @@ type Handler struct {
Dashboard bool `description:"Activate dashboard" export:"true"`
Debug bool `export:"true"`
CurrentConfigurations *safe.Safe
Statistics *types.Statistics `description:"Enable more detailed statistics" export:"true"`
Stats *thoas_stats.Stats
StatsRecorder *middlewares.StatsRecorder
Statistics *types.Statistics `description:"Enable more detailed statistics" export:"true"`
Stats *thoas_stats.Stats `json:"-"`
StatsRecorder *middlewares.StatsRecorder `json:"-"`
}
var (

View File

@@ -135,7 +135,7 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
method = "{{getLoadBalancerMethod $backend}}"
sticky = {{getSticky $backend}}
{{if hasStickinessLabel $backend}}
[backends.backend-{{$backendName}}.loadBalancer.stickiness]
[backends.backend-{{$backendName}}.loadbalancer.stickiness]
cookieName = "{{getStickinessCookieName $backend}}"
{{end}}
{{end}}
@@ -172,7 +172,6 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
[frontends."frontend-{{getServiceBackend $container $serviceName}}"]
backend = "backend-{{getServiceBackend $container $serviceName}}"
passHostHeader = {{getServicePassHostHeader $container $serviceName}}
redirect = "{{getServiceRedirect $container $serviceName}}"
{{if getWhitelistSourceRange $container}}
whitelistSourceRange = [{{range getWhitelistSourceRange $container}}
"{{.}}",
@@ -185,14 +184,21 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
basicAuth = [{{range getServiceBasicAuth $container $serviceName}}
"{{.}}",
{{end}}]
[frontends."frontend-{{getServiceBackend $container $serviceName}}".routes."service-{{$serviceName | replace "/" "" | replace "." "-"}}"]
{{if hasServiceRedirect $container $serviceName}}
[frontends."frontend-{{getServiceBackend $container $serviceName}}".redirect]
entryPoint = "{{getServiceRedirectEntryPoint $container $serviceName}}"
regex = "{{getServiceRedirectRegex $container $serviceName}}"
replacement = "{{getServiceRedirectReplacement $container $serviceName}}"
{{end}}
[frontends."frontend-{{getServiceBackend $container $serviceName}}".routes."service-{{$serviceName | replace "/" "" | replace "." "-"}}"]
rule = "{{getServiceFrontendRule $container $serviceName}}"
{{end}}
{{else}}
[frontends."frontend-{{$frontend}}"]
backend = "backend-{{getBackend $container}}"
passHostHeader = {{getPassHostHeader $container}}
redirect = "{{getRedirect $container}}"
{{if getWhitelistSourceRange $container}}
whitelistSourceRange = [{{range getWhitelistSourceRange $container}}
"{{.}}",
@@ -205,6 +211,15 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
basicAuth = [{{range getBasicAuth $container}}
"{{.}}",
{{end}}]
{{if hasRedirect $container}}
[frontends."frontend-{{$frontend}}".redirect]
entryPoint = "{{getRedirectEntryPoint $container}}"
regex = "{{getRedirectRegex $container}}"
replacement = "{{getRedirectReplacement $container}}"
{{end}}
{{ if hasHeaders $container}}
[frontends."frontend-{{$frontend}}".headers]
{{if hasSSLRedirectHeaders $container}}
SSLRedirect = {{getSSLRedirectHeaders $container}}
@@ -213,7 +228,7 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
SSLTemporaryRedirect = {{getSSLTemporaryRedirectHeaders $container}}
{{end}}
{{if hasSSLHostHeaders $container}}
SSLHost = {{getSSLHostHeaders $container}}
SSLHost = "{{getSSLHostHeaders $container}}"
{{end}}
{{if hasSTSSecondsHeaders $container}}
STSSeconds = {{getSTSSecondsHeaders $container}}
@@ -231,7 +246,7 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
FrameDeny = {{getFrameDenyHeaders $container}}
{{end}}
{{if hasCustomFrameOptionsValueHeaders $container}}
CustomFrameOptionsValue = {{getCustomFrameOptionsValueHeaders $container}}
CustomFrameOptionsValue = "{{getCustomFrameOptionsValueHeaders $container}}"
{{end}}
{{if hasContentTypeNosniffHeaders $container}}
ContentTypeNosniff = {{getContentTypeNosniffHeaders $container}}
@@ -240,17 +255,27 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
BrowserXSSFilter = {{getBrowserXSSFilterHeaders $container}}
{{end}}
{{if hasContentSecurityPolicyHeaders $container}}
ContentSecurityPolicy = {{getContentSecurityPolicyHeaders $container}}
ContentSecurityPolicy = "{{getContentSecurityPolicyHeaders $container}}"
{{end}}
{{if hasPublicKeyHeaders $container}}
PublicKey = {{getPublicKeyHeaders $container}}
PublicKey = "{{getPublicKeyHeaders $container}}"
{{end}}
{{if hasReferrerPolicyHeaders $container}}
ReferrerPolicy = {{getReferrerPolicyHeaders $container}}
ReferrerPolicy = "{{getReferrerPolicyHeaders $container}}"
{{end}}
{{if hasIsDevelopmentHeaders $container}}
IsDevelopment = {{getIsDevelopmentHeaders $container}}
{{end}}
{{if hasAllowedHostsHeaders $container}}
AllowedHosts = [{{range getAllowedHostsHeaders $container}}
"{{.}}",
{{end}}]
{{end}}
{{if hasHostsProxyHeaders $container}}
HostsProxyHeaders = [{{range getHostsProxyHeaders $container}}
"{{.}}",
{{end}}]
{{end}}
{{if hasRequestHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.customrequestheaders]
{{range $k, $v := getRequestHeaders $container}}
@@ -263,24 +288,14 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
{{if hasAllowedHostsHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.AllowedHosts]
{{range getAllowedHostsHeaders $container}}
"{{.}}"
{{end}}
{{end}}
{{if hasHostsProxyHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.HostsProxyHeaders]
{{range getHostsProxyHeaders $container}}
"{{.}}"
{{end}}
{{end}}
{{if hasSSLProxyHeaders $container}}
[frontends."frontend-{{$frontend}}".headers.SSLProxyHeaders]
{{range $k, $v := getSSLProxyHeaders $container}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
{{end}}
[frontends."frontend-{{$frontend}}".routes."route-frontend-{{$frontend}}"]
rule = "{{getFrontendRule $container}}"
{{end}}
@@ -414,13 +429,24 @@ var _templatesKubernetesTmpl = []byte(`[backends]{{range $backendName, $backend
backend = "{{$frontend.Backend}}"
priority = {{$frontend.Priority}}
passHostHeader = {{$frontend.PassHostHeader}}
redirect = "{{$frontend.Redirect}}"
entryPoints = [{{range $frontend.EntryPoints}}
"{{.}}",
{{end}}]
basicAuth = [{{range $frontend.BasicAuth}}
"{{.}}",
{{end}}]
whitelistSourceRange = [{{range $frontend.WhitelistSourceRange}}
"{{.}}",
{{end}}]
{{if $frontend.Redirect}}
[frontends."{{$frontendName}}".redirect]
entryPoint = "{{$frontend.RedirectEntryPoint}}"
regex = "{{$frontend.RedirectRegex}}"
replacement = "{{$frontend.RedirectReplacement}}"
{{end}}
{{ if $frontend.Headers }}
[frontends."{{$frontendName}}".headers]
SSLRedirect = {{$frontend.Headers.SSLRedirect}}
SSLTemporaryRedirect = {{$frontend.Headers.SSLTemporaryRedirect}}
@@ -437,40 +463,45 @@ var _templatesKubernetesTmpl = []byte(`[backends]{{range $backendName, $backend
PublicKey = "{{$frontend.Headers.PublicKey}}"
ReferrerPolicy = "{{$frontend.Headers.ReferrerPolicy}}"
IsDevelopment = {{$frontend.Headers.IsDevelopment}}
{{if $frontend.Headers.CustomRequestHeaders}}
[frontends."{{$frontendName}}".headers.customrequestheaders]
{{if $frontend.Headers.AllowedHosts}}
AllowedHosts = [{{range $frontend.Headers.AllowedHosts}}
"{{.}}",
{{end}}]
{{end}}
{{if $frontend.Headers.HostsProxyHeaders}}
HostsProxyHeaders = [{{range $frontend.Headers.HostsProxyHeaders}}
"{{.}}",
{{end}}]
{{end}}
{{if $frontend.Headers.CustomRequestHeaders}}
[frontends."{{$frontendName}}".headers.customrequestheaders]
{{range $k, $v := $frontend.Headers.CustomRequestHeaders}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
{{if $frontend.Headers.CustomResponseHeaders}}
[frontends."{{$frontendName}}".headers.customresponseheaders]
{{end}}
{{if $frontend.Headers.CustomResponseHeaders}}
[frontends."{{$frontendName}}".headers.customresponseheaders]
{{range $k, $v := $frontend.Headers.CustomResponseHeaders}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
{{if $frontend.Headers.AllowedHosts}}
[frontends."{{$frontendName}}".headers.AllowedHosts]
{{range $frontend.Headers.AllowedHosts}}
"{{.}}"
{{end}}
{{end}}
{{if $frontend.Headers.HostsProxyHeaders}}
[frontends."{{$frontendName}}".headers.HostsProxyHeaders]
{{range $frontend.Headers.HostsProxyHeaders}}
"{{.}}"
{{end}}
{{end}}
{{if $frontend.Headers.SSLProxyHeaders}}
[frontends."{{$frontendName}}".headers.SSLProxyHeaders]
{{end}}
{{if $frontend.Headers.SSLProxyHeaders}}
[frontends."{{$frontendName}}".headers.SSLProxyHeaders]
{{range $k, $v := $frontend.Headers.SSLProxyHeaders}}
{{$k}} = "{{$v}}"
{{end}}
{{end}}
{{end}}
{{range $routeName, $route := $frontend.Routes}}
[frontends."{{$frontendName}}".routes."{{$routeName}}"]
{{range $routeName, $route := $frontend.Routes}}
[frontends."{{$frontendName}}".routes."{{$routeName}}"]
rule = "{{$route.Rule}}"
{{end}}
{{end}}
{{end}}
`)
@@ -491,7 +522,7 @@ func templatesKubernetesTmpl() (*asset, error) {
var _templatesKvTmpl = []byte(`{{$frontends := List .Prefix "/frontends/" }}
{{$backends := List .Prefix "/backends/"}}
{{$tlsconfiguration := List .Prefix "/tlsconfiguration/"}}
{{$tls := List .Prefix "/tls/"}}
[backends]{{range $backends}}
{{$backend := .}}
@@ -511,7 +542,7 @@ var _templatesKvTmpl = []byte(`{{$frontends := List .Prefix "/frontends/" }}
sticky = {{ getSticky . }}
{{if hasStickinessLabel $backend}}
[backends."{{$backendName}}".loadBalancer.stickiness]
cookieName = {{getStickinessCookieName $backend}}
cookieName = "{{getStickinessCookieName $backend}}"
{{end}}
{{end}}
@@ -541,7 +572,7 @@ var _templatesKvTmpl = []byte(`{{$frontends := List .Prefix "/frontends/" }}
[frontends]{{range $frontends}}
{{$frontend := Last .}}
{{$entryPoints := SplitGet . "/entrypoints"}}
{{$entryPoints := GetList . "/entrypoints"}}
[frontends."{{$frontend}}"]
backend = "{{Get "" . "/backend"}}"
passHostHeader = {{Get "true" . "/passHostHeader"}}
@@ -556,13 +587,13 @@ var _templatesKvTmpl = []byte(`{{$frontends := List .Prefix "/frontends/" }}
{{end}}
{{end}}
{{range $tlsconfiguration}}
{{range $tls}}
{{$entryPoints := SplitGet . "/entrypoints"}}
[[tlsConfiguration]]
[[tls]]
entryPoints = [{{range $entryPoints}}
"{{.}}",
{{end}}]
[tlsConfiguration.certificate]
[tls.certificate]
certFile = """{{Get "" . "/certificate" "/certfile"}}"""
keyFile = """{{Get "" . "/certificate" "/keyfile"}}"""
{{end}}
@@ -752,13 +783,20 @@ var _templatesRancherTmpl = []byte(`{{$backendServers := .Backends}}
backend = "backend-{{getBackend $service}}"
passHostHeader = {{getPassHostHeader $service}}
priority = {{getPriority $service}}
redirect = "{{getRedirect $service}}"
entryPoints = [{{range getEntryPoints $service}}
"{{.}}",
{{end}}]
basicAuth = [{{range getBasicAuth $service}}
"{{.}}",
{{end}}]
{{if hasRedirect $service}}
[frontends."frontend-{{$frontendName}}".redirect]
entryPoint = "{{getRedirectEntryPoint $service}}"
regex = "{{getRedirectRegex $service}}"
replacement = "{{getRedirectReplacement $service}}"
{{end}}
[frontends."frontend-{{$frontendName}}".routes."route-frontend-{{$frontendName}}"]
rule = "{{getFrontendRule $service}}"
{{end}}
@@ -884,17 +922,17 @@ type bintree struct {
}
var _bintree = &bintree{nil, map[string]*bintree{
"templates": &bintree{nil, map[string]*bintree{
"consul_catalog.tmpl": &bintree{templatesConsul_catalogTmpl, map[string]*bintree{}},
"docker.tmpl": &bintree{templatesDockerTmpl, map[string]*bintree{}},
"ecs.tmpl": &bintree{templatesEcsTmpl, map[string]*bintree{}},
"eureka.tmpl": &bintree{templatesEurekaTmpl, map[string]*bintree{}},
"kubernetes.tmpl": &bintree{templatesKubernetesTmpl, map[string]*bintree{}},
"kv.tmpl": &bintree{templatesKvTmpl, map[string]*bintree{}},
"marathon.tmpl": &bintree{templatesMarathonTmpl, map[string]*bintree{}},
"mesos.tmpl": &bintree{templatesMesosTmpl, map[string]*bintree{}},
"notFound.tmpl": &bintree{templatesNotfoundTmpl, map[string]*bintree{}},
"rancher.tmpl": &bintree{templatesRancherTmpl, map[string]*bintree{}},
"templates": {nil, map[string]*bintree{
"consul_catalog.tmpl": {templatesConsul_catalogTmpl, map[string]*bintree{}},
"docker.tmpl": {templatesDockerTmpl, map[string]*bintree{}},
"ecs.tmpl": {templatesEcsTmpl, map[string]*bintree{}},
"eureka.tmpl": {templatesEurekaTmpl, map[string]*bintree{}},
"kubernetes.tmpl": {templatesKubernetesTmpl, map[string]*bintree{}},
"kv.tmpl": {templatesKvTmpl, map[string]*bintree{}},
"marathon.tmpl": {templatesMarathonTmpl, map[string]*bintree{}},
"mesos.tmpl": {templatesMesosTmpl, map[string]*bintree{}},
"notFound.tmpl": {templatesNotfoundTmpl, map[string]*bintree{}},
"rancher.tmpl": {templatesRancherTmpl, map[string]*bintree{}},
}},
}}

View File

@@ -7,20 +7,18 @@ RUN apk --update upgrade \
RUN go get github.com/jteeuwen/go-bindata/... \
&& go get github.com/golang/lint/golint \
&& go get github.com/kisielk/errcheck \
&& go get github.com/client9/misspell/cmd/misspell \
&& go get github.com/mattfarina/glide-hash \
&& go get github.com/sgotti/glide-vc
&& go get github.com/client9/misspell/cmd/misspell
# Which docker version to test on
ARG DOCKER_VERSION=17.03.2
ARG DEP_VERSION=0.3.2
# Which glide version to test on
ARG GLIDE_VERSION=v0.12.3
# Download glide
# Download dep binary to bin folder in $GOPATH
RUN mkdir -p /usr/local/bin \
&& curl -fL https://github.com/Masterminds/glide/releases/download/${GLIDE_VERSION}/glide-${GLIDE_VERSION}-linux-amd64.tar.gz \
| tar -xzC /usr/local/bin --transform 's#^.+/##x'
&& curl -fsSL -o /usr/local/bin/dep https://github.com/golang/dep/releases/download/v${DEP_VERSION}/dep-linux-amd64 \
&& chmod +x /usr/local/bin/dep
# Download docker
RUN mkdir -p /usr/local/bin \

View File

@@ -57,7 +57,7 @@ func TestDo_globalConfiguration(t *testing.T) {
Optional: false,
},
},
Redirect: &configuration.Redirect{
Redirect: &types.Redirect{
Replacement: "foo Replacement",
Regex: "foo Regex",
EntryPoint: "foo EntryPoint",
@@ -103,7 +103,7 @@ func TestDo_globalConfiguration(t *testing.T) {
Optional: false,
},
},
Redirect: &configuration.Redirect{
Redirect: &types.Redirect{
Replacement: "fii Replacement",
Regex: "fii Regex",
EntryPoint: "fii EntryPoint",
@@ -168,7 +168,7 @@ func TestDo_globalConfiguration(t *testing.T) {
OnHostRule: true,
CAServer: "CAServer",
EntryPoint: "EntryPoint",
DNSProvider: "DNSProvider",
DNSChallenge: &acme.DNSChallenge{Provider: "DNSProvider"},
DelayDontCheckDNS: 666,
ACMELogging: true,
TLSConfig: &tls.Config{

View File

@@ -84,7 +84,7 @@ Add more configuration information here.
)
// newBugCmd builds a new Bug command
func newBugCmd(traefikConfiguration interface{}, traefikPointersConfiguration interface{}) *flaeg.Command {
func newBugCmd(traefikConfiguration *TraefikConfiguration, traefikPointersConfiguration *TraefikConfiguration) *flaeg.Command {
//version Command init
return &flaeg.Command{
@@ -99,7 +99,7 @@ func newBugCmd(traefikConfiguration interface{}, traefikPointersConfiguration in
}
}
func runBugCmd(traefikConfiguration interface{}) func() error {
func runBugCmd(traefikConfiguration *TraefikConfiguration) func() error {
return func() error {
body, err := createBugReport(traefikConfiguration)
@@ -113,7 +113,7 @@ func runBugCmd(traefikConfiguration interface{}) func() error {
}
}
func createBugReport(traefikConfiguration interface{}) (string, error) {
func createBugReport(traefikConfiguration *TraefikConfiguration) (string, error) {
var version bytes.Buffer
if err := getVersionPrint(&version); err != nil {
return "", err
@@ -124,7 +124,7 @@ func createBugReport(traefikConfiguration interface{}) (string, error) {
return "", err
}
config, err := anonymize.Do(&traefikConfiguration, true)
config, err := anonymize.Do(traefikConfiguration, true)
if err != nil {
return "", err
}

View File

@@ -7,16 +7,27 @@ import (
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/provider/file"
"github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
)
func Test_createBugReport(t *testing.T) {
traefikConfiguration := TraefikConfiguration{
traefikConfiguration := &TraefikConfiguration{
ConfigFile: "FOO",
GlobalConfiguration: configuration.GlobalConfiguration{
EntryPoints: configuration.EntryPoints{
"goo": &configuration.EntryPoint{
Address: "hoo.bar",
Auth: &types.Auth{
Basic: &types.Basic{
UsersFile: "foo Basic UsersFile",
Users: types.Users{"foo Basic Users 1", "foo Basic Users 2", "foo Basic Users 3"},
},
Digest: &types.Digest{
UsersFile: "foo Digest UsersFile",
Users: types.Users{"foo Digest Users 1", "foo Digest Users 2", "foo Digest Users 3"},
},
},
},
},
File: &file.Provider{
@@ -28,6 +39,11 @@ func Test_createBugReport(t *testing.T) {
report, err := createBugReport(traefikConfiguration)
assert.NoError(t, err, report)
// exported anonymous configuration
assert.NotContains(t, "web Basic Users ", report)
assert.NotContains(t, "foo Digest Users ", report)
assert.NotContains(t, "hoo.bar", report)
}
func Test_anonymize_traefikConfiguration(t *testing.T) {

View File

@@ -61,7 +61,8 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
// TODO: Deprecated - default Metrics
defaultWeb.Metrics = &types.Metrics{
Prometheus: &types.Prometheus{
Buckets: types.Buckets{0.1, 0.3, 1.2, 5},
Buckets: types.Buckets{0.1, 0.3, 1.2, 5},
EntryPoint: configuration.DefaultInternalEntryPointName,
},
Datadog: &types.Datadog{
Address: "localhost:8125",
@@ -112,7 +113,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
var defaultZookeeper zk.Provider
defaultZookeeper.Watch = true
defaultZookeeper.Endpoint = "127.0.0.1:2181"
defaultZookeeper.Prefix = "/traefik"
defaultZookeeper.Prefix = "traefik"
defaultZookeeper.Constraints = types.Constraints{}
//default Boltdb
@@ -220,7 +221,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
defaultMetrics := types.Metrics{
Prometheus: &types.Prometheus{
Buckets: types.Buckets{0.1, 0.3, 1.2, 5},
EntryPoint: "traefik",
EntryPoint: configuration.DefaultInternalEntryPointName,
},
Datadog: &types.Datadog{
Address: "localhost:8125",
@@ -279,7 +280,7 @@ func NewTraefikConfiguration() *TraefikConfiguration {
LogLevel: "ERROR",
EntryPoints: map[string]*configuration.EntryPoint{},
Constraints: types.Constraints{},
DefaultEntryPoints: []string{},
DefaultEntryPoints: []string{"http"},
ProvidersThrottleDuration: flaeg.Duration(2 * time.Second),
MaxIdleConnsPerHost: 200,
IdleTimeout: flaeg.Duration(0),

View File

@@ -64,6 +64,9 @@ func healthCheck(globalConfiguration configuration.GlobalConfiguration) (*http.R
}
client.Transport = tr
}
return client.Head(protocol + "://" + pingEntryPoint.Address + globalConfiguration.Web.Path + "ping")
path := "/"
if globalConfiguration.Web != nil {
path = globalConfiguration.Web.Path
}
return client.Head(protocol + "://" + pingEntryPoint.Address + path + "ping")
}

View File

@@ -67,12 +67,21 @@ func runStoreConfig(kv *staert.KvSource, traefikConfiguration *TraefikConfigurat
return err
}
}
if traefikConfiguration.GlobalConfiguration.ACME != nil && len(traefikConfiguration.GlobalConfiguration.ACME.StorageFile) > 0 {
// convert ACME json file to KV store
localStore := acme.NewLocalStore(traefikConfiguration.GlobalConfiguration.ACME.StorageFile)
object, err := localStore.Load()
if err != nil {
return err
if traefikConfiguration.GlobalConfiguration.ACME != nil {
var object cluster.Object
if len(traefikConfiguration.GlobalConfiguration.ACME.StorageFile) > 0 {
// convert ACME json file to KV store
localStore := acme.NewLocalStore(traefikConfiguration.GlobalConfiguration.ACME.StorageFile)
object, err = localStore.Load()
if err != nil {
return err
}
} else {
// Create an empty account to create all the keys into the KV store
account := &acme.Account{}
account.Init()
object = account
}
meta := cluster.NewMetadata(object)
@@ -89,6 +98,11 @@ func runStoreConfig(kv *staert.KvSource, traefikConfiguration *TraefikConfigurat
if err != nil {
return err
}
// Force to delete storagefile
err = kv.Delete(kv.Prefix + "/acme/storagefile")
if err != nil {
return err
}
}
return nil
}

View File

@@ -261,14 +261,14 @@ func stats(globalConfiguration *configuration.GlobalConfiguration) {
Stats collection is enabled.
Many thanks for contributing to Traefik's improvement by allowing us to receive anonymous information from your configuration.
Help us improve Traefik by leaving this feature on :)
More details on: https://docs.traefik.io/basic/#collected-data
More details on: https://docs.traefik.io/basics/#collected-data
`)
collect(globalConfiguration)
} else {
log.Info(`
Stats collection is disabled.
Help us improve Traefik by turning this feature on :)
More details on: https://docs.traefik.io/basic/#collected-data
More details on: https://docs.traefik.io/basics/#collected-data
`)
}
}

View File

@@ -240,6 +240,23 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
log.Errorln("Error using file configuration backend, no filename defined")
}
}
if gc.ACME != nil {
// TODO: to remove in the futurs
if len(gc.ACME.StorageFile) > 0 && len(gc.ACME.Storage) == 0 {
log.Warn("ACME.StorageFile is deprecated, use ACME.Storage instead")
gc.ACME.Storage = gc.ACME.StorageFile
}
if len(gc.ACME.DNSProvider) > 0 {
log.Warn("ACME.DNSProvider is deprecated, use ACME.DNSChallenge instead")
gc.ACME.DNSChallenge = &acme.DNSChallenge{Provider: gc.ACME.DNSProvider, DelayBeforeCheck: gc.ACME.DelayDontCheckDNS}
}
if gc.ACME.OnDemand {
log.Warn("ACME.OnDemand is deprecated")
}
}
}
// DefaultEntryPoints holds default entry points
@@ -317,9 +334,9 @@ func (ep *EntryPoints) Set(value string) error {
Optional: optional,
}
}
var redirect *Redirect
var redirect *types.Redirect
if len(result["redirect_entrypoint"]) > 0 || len(result["redirect_regex"]) > 0 || len(result["redirect_replacement"]) > 0 {
redirect = &Redirect{
redirect = &types.Redirect{
EntryPoint: result["redirect_entrypoint"],
Regex: result["redirect_regex"],
Replacement: result["redirect_replacement"],
@@ -422,22 +439,15 @@ func (ep *EntryPoints) Type() string {
type EntryPoint struct {
Network string
Address string
TLS *tls.TLS `export:"true"`
Redirect *Redirect `export:"true"`
Auth *types.Auth `export:"true"`
TLS *tls.TLS `export:"true"`
Redirect *types.Redirect `export:"true"`
Auth *types.Auth `export:"true"`
WhitelistSourceRange []string
Compress bool `export:"true"`
ProxyProtocol *ProxyProtocol `export:"true"`
ForwardedHeaders *ForwardedHeaders `export:"true"`
}
// Redirect configures a redirection of an entry point to another, or to an URL
type Redirect struct {
EntryPoint string
Regex string
Replacement string
}
// Retry contains request retry config
type Retry struct {
Attempts int `description:"Number of attempts" export:"true"`

View File

@@ -8,6 +8,7 @@ import (
"github.com/containous/traefik/provider"
"github.com/containous/traefik/provider/file"
"github.com/containous/traefik/tls"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -138,7 +139,7 @@ func TestEntryPoints_Set(t *testing.T) {
expectedEntryPointName: "foo",
expectedEntryPoint: &EntryPoint{
Address: ":8000",
Redirect: &Redirect{
Redirect: &types.Redirect{
EntryPoint: "RedirectEntryPoint",
Regex: "RedirectRegex",
Replacement: "RedirectReplacement",
@@ -171,7 +172,7 @@ func TestEntryPoints_Set(t *testing.T) {
expectedEntryPointName: "foo",
expectedEntryPoint: &EntryPoint{
Address: ":8000",
Redirect: &Redirect{
Redirect: &types.Redirect{
EntryPoint: "RedirectEntryPoint",
Regex: "RedirectRegex",
Replacement: "RedirectReplacement",

View File

@@ -1,23 +0,0 @@
## Current versions documentation
- [Latest stable](https://docs.traefik.io)
## Future version documentation
- [Experimental](https://master--traefik-docs.netlify.com/)
## Previous versions documentation
- [v1.5 aka Cancoillotte](http://v1-5.archive.docs.traefik.io/)
- [v1.4 aka Roquefort](http://v1-4.archive.docs.traefik.io/)
- [v1.3 aka Raclette](http://v1-3.archive.docs.traefik.io/)
- [v1.2 aka Morbier](http://v1-2.archive.docs.traefik.io/)
- [v1.1 aka Camembert](http://v1-1.archive.docs.traefik.io/)
## More
[Change log](https://github.com/containous/traefik/blob/master/CHANGELOG.md)

View File

@@ -321,42 +321,13 @@ In this example, traffic routed through the first frontend will have the `X-Fram
!!! note
The detailed documentation for those security headers can be found in [unrolled/secure](https://github.com/unrolled/secure#available-options).
#### Rate limiting
Rate limiting can be configured per frontend.
Multiple sets of rates can be added to each frontend, but the time periods must be unique.
```toml
[frontends]
[frontends.frontend1]
passHostHeader = true
entrypoints = ["http"]
backend = "backend1"
[frontends.frontend1.routes.test_1]
rule = "Path:/"
[frontends.frontend1.ratelimit]
extractorfunc = "client.ip"
[frontends.frontend1.ratelimit.rateset.rateset1]
period = "10s"
average = 100
burst = 200
[frontends.frontend1.ratelimit.rateset.rateset2]
period = "3s"
average = 5
burst = 10
```
In the above example, frontend1 is configured to limit requests by the client's ip address.
An average of 5 requests every 3 seconds is allowed and an average of 100 requests every 10 seconds.
These can "burst" up to 10 and 200 in each period respectively.
### Backends
A backend is responsible to load-balance the traffic coming from one or more frontends to a set of http servers.
Various methods of load-balancing are supported:
- `wrr`: Weighted Round Robin
- `wrr`: Weighted Round Robin.
- `drr`: Dynamic Round Robin: increases weights on servers that perform better than others.
It also rolls back to original weights if the servers have changed.
@@ -373,16 +344,13 @@ It can be configured using:
For example:
- `NetworkErrorRatio() > 0.5`: watch error ratio over 10 second sliding window for a frontend
- `NetworkErrorRatio() > 0.5`: watch error ratio over 10 second sliding window for a frontend.
- `LatencyAtQuantileMS(50.0) > 50`: watch latency at quantile in milliseconds.
- `ResponseCodeRatio(500, 600, 0, 600) > 0.5`: ratio of response codes in range [500-600) to [0-600)
- `ResponseCodeRatio(500, 600, 0, 600) > 0.5`: ratio of response codes in ranges [500-600) and [0-600).
To proactively prevent backends from being overwhelmed with high load, a maximum connection limit can
also be applied to each backend.
To proactively prevent backends from being overwhelmed with high load, a maximum connection limit can also be applied to each backend.
Maximum connections can be configured by specifying an integer value for `maxconn.amount` and
`maxconn.extractorfunc` which is a strategy used to determine how to categorize requests in order to
evaluate the maximum connections.
Maximum connections can be configured by specifying an integer value for `maxconn.amount` and `maxconn.extractorfunc` which is a strategy used to determine how to categorize requests in order to evaluate the maximum connections.
For example:
```toml
@@ -499,8 +467,8 @@ Here is an example of backends and servers definition:
Træfik's configuration has two parts:
- The [static Træfik configuration](/basics#static-trfk-configuration) which is loaded only at the beginning.
- The [dynamic Træfik configuration](/basics#dynamic-trfk-configuration) which can be hot-reloaded (no need to restart the process).
- The [static Træfik configuration](/basics#static-trfik-configuration) which is loaded only at the beginning.
- The [dynamic Træfik configuration](/basics#dynamic-trfik-configuration) which can be hot-reloaded (no need to restart the process).
### Static Træfik configuration
@@ -585,7 +553,7 @@ traefik [command] [--flag=flag_argument]
List of Træfik available commands with description :
- `version` : Print version
- `storeconfig` : Store the static Traefik configuration into a Key-value stores. Please refer to the [Store Træfik configuration](/user-guide/kv-config/#store-trfk-configuration) section to get documentation on it.
- `storeconfig` : Store the static Traefik configuration into a Key-value stores. Please refer to the [Store Træfik configuration](/user-guide/kv-config/#store-configuration-in-key-value-store) section to get documentation on it.
- `bug`: The easiest way to submit a pre-filled issue.
- `healthcheck`: Calls Traefik `/ping` to check health.
@@ -620,7 +588,7 @@ This command allows to check the health of Traefik. Its exit status is `0` if Tr
This can be used with Docker [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) instruction or any other health check orchestration mechanism.
!!! note
The [`web` provider](/configuration/backends/web) must be enabled to allow `/ping` calls by the `healthcheck` command.
The [`ping`](/configuration/ping) must be enabled to allow the `healthcheck` command to call `/ping`.
```bash
traefik healthcheck
@@ -664,8 +632,7 @@ Once a day (the first call begins 10 minutes after the start of Træfik), we col
[entryPoints.http]
address = ":80"
[web]
address = ":8080"
[api]
[Docker]
endpoint = "tcp://10.10.10.10:2375"
@@ -695,8 +662,7 @@ Once a day (the first call begins 10 minutes after the start of Træfik), we col
[entryPoints.http]
address = ":80"
[web]
address = ":8080"
[api]
[Docker]
Endpoint = "xxxx"

View File

@@ -7,10 +7,14 @@ See also [Let's Encrypt examples](/user-guide/examples/#lets-encrypt-support) an
```toml
# Sample entrypoint configuration when using ACME.
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
```
```toml
# Enable ACME (Let's Encrypt): automatic SSL.
[acme]
@@ -20,6 +24,12 @@ See also [Let's Encrypt examples](/user-guide/examples/#lets-encrypt-support) an
#
email = "test@traefik.io"
# File used for certificates storage.
#
# Optional (Deprecated)
#
#storageFile = "acme.json"
# File or key used for certificates storage.
#
# Required
@@ -27,17 +37,16 @@ email = "test@traefik.io"
storage = "acme.json"
# or `storage = "traefik/acme/account"` if using KV store.
# Entrypoint to proxy acme challenge/apply certificates to.
# WARNING, must point to an entrypoint on port 443
# Entrypoint to proxy acme apply certificates to.
# WARNING, if the TLS-SNI-01 challenge is used, it must point to an entrypoint on port 443
#
# Required
#
entryPoint = "https"
# Use a DNS based acme challenge rather than external HTTPS access
# Use a DNS-01 acme challenge rather than TLS-SNI-01 challenge
#
#
# Optional
# Optional (Deprecated, replaced by [acme.dnsChallenge])
#
# dnsProvider = "digitalocean"
@@ -45,25 +54,29 @@ entryPoint = "https"
# If delayDontCheckDNS is greater than zero, avoid this & instead just wait so many seconds.
# Useful if internal networks block external DNS queries.
#
# Optional
# Optional (Deprecated, replaced by [acme.dnsChallenge])
# Default: 0
#
# delayDontCheckDNS = 0
# If true, display debug log messages from the acme client library.
#
# Optional
# Default: false
#
# acmeLogging = true
# Enable on demand certificate.
# Enable on demand certificate generation.
#
# Optional
# Optional (Deprecated)
# Default: false
#
# onDemand = true
# Enable certificate generation on frontends Host rules.
#
# Optional
# Default: false
#
# onHostRule = true
@@ -72,22 +85,64 @@ entryPoint = "https"
# - Leave comment to go to prod.
#
# Optional
# Default: "https://acme-v01.api.letsencrypt.org/directory"
#
# caServer = "https://acme-staging.api.letsencrypt.org/directory"
# Domains list.
#
# [[acme.domains]]
# main = "local1.com"
# sans = ["test1.local1.com", "test2.local1.com"]
# main = "local1.com"
# sans = ["test1.local1.com", "test2.local1.com"]
# [[acme.domains]]
# main = "local2.com"
# sans = ["test1.local2.com", "test2.local2.com"]
# main = "local2.com"
# sans = ["test1.local2.com", "test2.local2.com"]
# [[acme.domains]]
# main = "local3.com"
# main = "local3.com"
# [[acme.domains]]
# main = "local4.com"
# main = "local4.com"
# Use a HTTP-01 acme challenge rather than TLS-SNI-01 challenge
#
# Optional but recommend
#
[acme.httpChallenge]
# EntryPoint to use for the challenges.
#
# Required
#
entryPoint = "http"
# Use a DNS-01 acme challenge rather than TLS-SNI-01 challenge
#
# Optional
#
# [acme.dnsChallenge]
# Provider used.
#
# Required
#
# provider = "digitalocean"
# By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
# If delayBeforeCheck is greater than zero, avoid this & instead just wait so many seconds.
# Useful if internal networks block external DNS queries.
#
# Optional
# Default: 0
#
# delayBeforeCheck = 0
```
!!! note
Even if `TLS-SNI-01` challenge is [disabled](https://community.letsencrypt.org/t/2018-01-11-update-regarding-acme-tls-sni-and-shared-hosting-infrastructure/50188) for the moment, it stays the _by default_ ACME Challenge in Træfik.
If `TLS-SNI-01` challenge is not re-enabled in the future, it we will be removed from Træfik.
!!! note
If `TLS-SNI-01` challenge is used, `acme.entryPoint` has to be reachable by Let's Encrypt through the port 443.
If `HTTP-01` challenge is used, `acme.httpChallenge.entryPoint` has to be defined and reachable by Let's Encrypt through the port 80.
These are Let's Encrypt limitations as described on the [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72).
### `storage`
@@ -100,7 +155,7 @@ storage = "acme.json"
File or key used for certificates storage.
**WARNING** If you use Traefik in Docker, you have 2 options:
**WARNING:** If you use Træfik in Docker, you have 2 options:
- create a file on your host and mount it as a volume:
```toml
@@ -118,16 +173,65 @@ storage = "/etc/traefik/acme/acme.json"
docker run -v "/my/host/acme:/etc/traefik/acme" traefik
```
### `dnsProvider`
!!! note
`storage` replaces `storageFile` which is deprecated.
!!! note
During Træfik configuration migration from a configuration file to a KV store (thanks to `storeconfig` subcommand as described [here](/user-guide/kv-config/#store-configuration-in-key-value-store)), if ACME certificates have to be migrated too, use both `storageFile` and `storage`.
- `storageFile` will contain the path to the `acme.json` file to migrate.
- `storage` will contain the key where the certificates will be stored.
### `acme.httpChallenge`
Use `HTTP-01` challenge to generate/renew ACME certificates.
```toml
[acme]
# ...
dnsProvider = "digitalocean"
entryPoint = "https"
[acme.httpChallenge]
entryPoint = "http"
```
#### `entryPoint`
Specify the entryPoint to use during the challenges.
```toml
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
# ...
[acme]
# ...
entryPoint = "https"
[acme.httpChallenge]
entryPoint = "http"
```
!!! note
`acme.httpChallenge.entryPoint` has to be reachable by Let's Encrypt through the port 80.
It's a Let's Encrypt limitation as described on the [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72).
### `acme.dnsChallenge`
Use `DNS-01` challenge to generate/renew ACME certificates.
```toml
[acme]
# ...
[acme.dnsChallenge]
provider = "digitalocean"
delayBeforeCheck = 0
# ...
```
Use a DNS based acme challenge rather than external HTTPS access, e.g. for a firewalled server.
#### `provider`
Select the provider that matches the DNS domain that will host the challenge TXT record, and provide environment variables to enable setting it:
@@ -135,7 +239,7 @@ Select the provider that matches the DNS domain that will host the challenge TXT
|--------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------|
| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` |
| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP` |
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CLOUDFLARE_EMAIL`, `CLOUDFLARE_API_KEY` |
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CLOUDFLARE_EMAIL`, `CLOUDFLARE_API_KEY` - The Cloudflare `Global API Key` needs to be used and not the `Origin CA Key` |
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` |
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` |
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` |
@@ -146,7 +250,7 @@ Select the provider that matches the DNS domain that will host the challenge TXT
| [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` |
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, `GCE_SERVICE_ACCOUNT_FILE` |
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` |
| manual | - | none, but run Traefik interactively & turn on `acmeLogging` to see instructions & press <kbd>Enter</kbd>. |
| manual | - | none, but run Træfik interactively & turn on `acmeLogging` to see instructions & press <kbd>Enter</kbd>. |
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` |
| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` |
| [Open Telekom Cloud](https://cloud.telekom.de/en/) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` |
@@ -157,21 +261,20 @@ Select the provider that matches the DNS domain that will host the challenge TXT
| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`, `AWS_HOSTED_ZONE_ID` or configured user/instance IAM profile. |
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` |
### `delayDontCheckDNS`
#### `delayBeforeCheck`
```toml
[acme]
# ...
delayDontCheckDNS = 0
# ...
```
By default, the dnsProvider will verify the TXT DNS challenge record before letting ACME verify.
If `delayDontCheckDNS` is greater than zero, avoid this & instead just wait so many seconds.
By default, the `provider` will verify the TXT DNS challenge record before letting ACME verify.
If `delayBeforeCheck` is greater than zero, avoid this & instead just wait so many seconds.
Useful if internal networks block external DNS queries.
### `onDemand`
!!! note
This field has no sense if a `provider` is not defined.
### `onDemand` (Deprecated)
!!! warning
This option is deprecated.
```toml
[acme]
@@ -188,7 +291,7 @@ This will request a certificate from Let's Encrypt during the first TLS handshak
TLS handshakes will be slow when requesting a hostname certificate for the first time, this can lead to DoS attacks.
!!! warning
Take note that Let's Encrypt have [rate limiting](https://letsencrypt.org/docs/rate-limits)
Take note that Let's Encrypt have [rate limiting](https://letsencrypt.org/docs/rate-limits).
### `onHostRule`
@@ -219,28 +322,40 @@ CA server to use.
- Uncomment the line to run on the staging Let's Encrypt server.
- Leave comment to go to prod.
### `domains`
### `acme.domains`
```toml
[acme]
# ...
[[acme.domains]]
main = "local1.com"
sans = ["test1.local1.com", "test2.local1.com"]
main = "local1.com"
sans = ["test1.local1.com", "test2.local1.com"]
[[acme.domains]]
main = "local2.com"
sans = ["test1.local2.com", "test2.local2.com"]
main = "local2.com"
sans = ["test1.local2.com", "test2.local2.com"]
[[acme.domains]]
main = "local3.com"
main = "local3.com"
[[acme.domains]]
main = "local4.com"
main = "local4.com"
# ...
```
You can provide SANs (alternative domains) to each main domain.
All domains must have A/AAAA records pointing to Traefik.
All domains must have A/AAAA records pointing to Træfik.
!!! warning
Take note that Let's Encrypt have [rate limiting](https://letsencrypt.org/docs/rate-limits).
Each domain & SANs will lead to a certificate request.
### `dnsProvider` (Deprecated)
!!! warning
This option is deprecated.
Please refer to [DNS challenge provider section](/configuration/acme/#provider)
### `delayDontCheckDNS` (Deprecated)
!!! warning
This option is deprecated.
Please refer to [DNS challenge delayBeforeCheck section](/configuration/acme/#delaybeforecheck)

View File

@@ -161,7 +161,7 @@ curl -s "http://localhost:8080/health" | jq .
// average response time in seconds
"average_response_time_sec": 0.8648016000000001,
// request statistics [requires --web.statistics to be set]
// request statistics [requires --statistics to be set]
// ten most recent requests with 4xx and 5xx status codes
"recent_errors": [
{

View File

@@ -1,6 +1,4 @@
# Consul Backend
## Consul Key-Value backend
# Consul Key-Value backend
Træfik can be configured to use Consul as a backend configuration.
@@ -61,76 +59,3 @@ prefix = "traefik"
To enable constraints see [backend-specific constraints section](/configuration/commons/#backend-specific).
Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on Traefik KV structure.
## Consul Catalog backend
Træfik can be configured to use service discovery catalog of Consul as a backend configuration.
```toml
################################################################
# Consul Catalog configuration backend
################################################################
# Enable Consul Catalog configuration backend.
[consulCatalog]
# Consul server endpoint.
#
# Required
# Default: "127.0.0.1:8500"
#
endpoint = "127.0.0.1:8500"
# Expose Consul catalog services by default in Traefik.
#
# Optional
# Default: true
#
exposedByDefault = false
# Prefix for Consul catalog tags.
#
# Optional
# Default: "traefik"
#
prefix = "traefik"
# Default frontEnd Rule for Consul services.
#
# The format is a Go Template with:
# - ".ServiceName", ".Domain" and ".Attributes" available
# - "getTag(name, tags, defaultValue)", "hasTag(name, tags)" and "getAttribute(name, tags, defaultValue)" functions are available
# - "getAttribute(...)" function uses prefixed tag names based on "prefix" value
#
# Optional
# Default: "Host:{{.ServiceName}}.{{.Domain}}"
#
#frontEndRule = "Host:{{.ServiceName}}.{{Domain}}"
```
This backend will create routes matching on hostname based on the service name used in Consul.
To enable constraints see [backend-specific constraints section](/configuration/commons/#backend-specific).
### Tags
Additional settings can be defined using Consul Catalog tags.
| Tag | Description |
|-----------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.enable=false` | Disable this container in Træfik |
| `traefik.protocol=https` | Override the default `http` protocol |
| `traefik.backend.weight=10` | Assign this weight to the container |
| `traefik.backend.circuitbreaker=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend, ex: `NetworkErrorRatio() > 0.` |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.rule=Host:test.traefik.io` | Override the default frontend rule (Default: `Host:{{.ServiceName}}.{{.Domain}}`). |
| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. |
| `traefik.frontend.priority=10` | Override default frontend priority |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` |
| `traefik.backend.loadbalancer=drr` | override the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | enable backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | enable backend sticky sessions (DEPRECATED) |

View File

@@ -0,0 +1,93 @@
# Consul Catalog backend
Træfik can be configured to use service discovery catalog of Consul as a backend configuration.
```toml
################################################################
# Consul Catalog configuration backend
################################################################
# Enable Consul Catalog configuration backend.
[consulCatalog]
# Consul server endpoint.
#
# Required
# Default: "127.0.0.1:8500"
#
endpoint = "127.0.0.1:8500"
# Expose Consul catalog services by default in Traefik.
#
# Optional
# Default: true
#
exposedByDefault = false
# Default domain used.
#
# Optional
#
domain = "consul.localhost"
# Prefix for Consul catalog tags.
#
# Optional
# Default: "traefik"
#
prefix = "traefik"
# Default frontEnd Rule for Consul services.
#
# The format is a Go Template with:
# - ".ServiceName", ".Domain" and ".Attributes" available
# - "getTag(name, tags, defaultValue)", "hasTag(name, tags)" and "getAttribute(name, tags, defaultValue)" functions are available
# - "getAttribute(...)" function uses prefixed tag names based on "prefix" value
#
# Optional
# Default: "Host:{{.ServiceName}}.{{.Domain}}"
#
#frontEndRule = "Host:{{.ServiceName}}.{{.Domain}}"
```
This backend will create routes matching on hostname based on the service name used in Consul.
To enable constraints see [backend-specific constraints section](/configuration/commons/#backend-specific).
### Tags
Additional settings can be defined using Consul Catalog tags.
| Tag | Description |
|-----------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.enable=false` | Disable this container in Træfik |
| `traefik.protocol=https` | Override the default `http` protocol |
| `traefik.backend.weight=10` | Assign this weight to the container |
| `traefik.backend.circuitbreaker=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend, ex: `NetworkErrorRatio() > 0.` |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. |
| `traefik.frontend.rule=Host:test.traefik.io` | Override the default frontend rule (Default: `Host:{{.ServiceName}}.{{.Domain}}`). |
| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. |
| `traefik.frontend.priority=10` | Override default frontend priority |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` |
| `traefik.backend.loadbalancer=drr` | override the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | enable backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | enable backend sticky sessions (DEPRECATED) |
### Examples
If you want that Træfik uses Consul tags correctly you need to defined them like that:
```json
traefik.enable=true
traefik.tags=api
traefik.tags=external
```
If the prefix defined in Træfik configuration is `bla`, tags need to be defined like that:
```json
bla.enable=true
bla.tags=api
bla.tags=external
```

View File

@@ -1,3 +1,4 @@
# Docker Backend
Træfik can be configured to use Docker as a backend configuration.
@@ -144,82 +145,106 @@ To enable constraints see [backend-specific constraints section](/configuration/
## Labels: overriding default behaviour
!!! note
If you use a compose file, labels should be defined in the `deploy` part of your service.
This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/#labels-1)).
```yaml
version: "3"
services:
whoami:
deploy:
labels:
traefik.docker.network: traefik
```
### On Containers
Labels can be used on containers to override default behaviour.
| Label | Description |
|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.backend=foo` | Give the name `foo` to the generated backend for this container. |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. |
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) |
| `traefik.backend.loadbalancer.swarm=true` | Use Swarm's inbuilt load balancer (only relevant under Swarm Mode). |
| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.port=80` | Register this port. Useful when the container exposes multiples ports. |
| `traefik.protocol=https` | Override the default `http` protocol |
| `traefik.weight=10` | Assign this weight to the container |
| `traefik.enable=false` | Disable this container in Træfik |
| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. |
| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. |
| `traefik.frontend.priority=10` | Override default frontend priority |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints` |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` |
| `traefik.frontend.whitelistSourceRange:RANGE` | List of IP-Ranges which are allowed to access. An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.docker.network` | Set the docker network to use for connections to this container. If a container is linked to several networks, be sure to set the proper network name (you can check with `docker inspect <container_id>`) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name. |
| `traefik.frontend.redirect=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) |
| Label | Description |
|------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.backend=foo` | Give the name `foo` to the generated backend for this container. |
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend. Must be used in conjunction with the below label to take effect. |
| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by. Must be used in conjunction with the above label to take effect. |
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) |
| `traefik.backend.loadbalancer.swarm=true` | Use Swarm's inbuilt load balancer (only relevant under Swarm Mode). |
| `traefik.backend.circuitbreaker.expression=EXPR` | Create a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.port=80` | Register this port. Useful when the container exposes multiples ports. |
| `traefik.protocol=https` | Override the default `http` protocol |
| `traefik.weight=10` | Assign this weight to the container |
| `traefik.enable=false` | Disable this container in Træfik |
| `traefik.frontend.rule=EXPR` | Override the default frontend rule. Default: `Host:{containerName}.{domain}` or `Host:{service}.{project_name}.{domain}` if you are using `docker-compose`. |
| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. |
| `traefik.frontend.priority=10` | Override default frontend priority |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints` |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash` |
| `traefik.frontend.whitelistSourceRange:RANGE` | List of IP-Ranges which are allowed to access. An unset or empty list allows all Source-IPs to access. If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access. |
| `traefik.docker.network` | Set the docker network to use for connections to this container. If a container is linked to several networks, be sure to set the proper network name (you can check with `docker inspect <container_id>`) otherwise it will randomly pick one (depending on how docker is returning them). For instance when deploying docker `stack` from compose files, the compose defined networks will be prefixed with the `stack` name. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex=^http://localhost/(.*)` | Redirect to another URL for that frontend. Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement=http://mydomain/$1` | Redirect to another URL for that frontend. Must be set with `traefik.frontend.redirect.regex`. |
#### Security Headers
| Label | Description |
|-----------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.frontend.headers.allowedHosts=EXPR` | Provides a list of allowed hosts that requests will be processed. Format: `Host1,Host2` |
|`traefik.frontend.headers.customrequestheaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container. Format: `HEADER:value,HEADER2:value2` |
| `traefik.frontend.headers.customresponseheaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client. Format: `HEADER:value,HEADER2:value2` |
|`traefik.frontend.headers.hostsProxyHeaders=EXPR ` | Provides a list of headers that the proxied hostname may be stored. Format: `HEADER1,HEADER2` |
| `traefik.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. |
| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as X-Forwarded-For:https). Format: `HEADER:value,HEADER2:value2` |
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the IncludeSubdomains section of the STS header. |
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |
| `traefik.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. |
| `traefik.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. |
| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. |
| `traefik.frontend.headers.contentTypeNosniff=true` | Adds the `X-Content-Type-Options` header with the value `nosniff`. |
| `traefik.frontend.headers.browserXSSFilter=true` | Adds the X-XSS-Protection header with the value `1; mode=block`. |
| `traefik.frontend.headers.contentSecurityPolicy=VALUE` | Adds CSP Header with the custom value. |
| `traefik.frontend.headers.publicKey=VALUE` | Adds pinned HTST public key header. |
| `traefik.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. |
| `traefik.frontend.headers.isDevelopment=false` | This will cause the AllowedHosts, SSLRedirect, and STSSeconds/STSIncludeSubdomains options to be ignored during development. When deploying to production, be sure to set this to false. |
| Label | Description |
|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `traefik.frontend.headers.allowedHosts=EXPR` | Provides a list of allowed hosts that requests will be processed. Format: `Host1,Host2` |
| `traefik.frontend.headers.customRequestHeaders=EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container. Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.customResponseHeaders=EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client. Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.hostsProxyHeaders=EXPR ` | Provides a list of headers that the proxied hostname may be stored. Format: `HEADER1,HEADER2` |
| `traefik.frontend.headers.SSLRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. |
| `traefik.frontend.headers.SSLTemporaryRedirect=true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `traefik.frontend.headers.SSLHost=HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `traefik.frontend.headers.SSLProxyHeaders=EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`). Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `traefik.frontend.headers.STSSeconds=315360000` | Sets the max-age of the STS header. |
| `traefik.frontend.headers.STSIncludeSubdomains=true` | Adds the `IncludeSubdomains` section of the STS header. |
| `traefik.frontend.headers.STSPreload=true` | Adds the preload flag to the STS header. |
| `traefik.frontend.headers.forceSTSHeader=false` | Adds the STS header to non-SSL requests. |
| `traefik.frontend.headers.frameDeny=false` | Adds the `X-Frame-Options` header with the value of `DENY`. |
| `traefik.frontend.headers.customFrameOptionsValue=VALUE` | Overrides the `X-Frame-Options` header with the custom value. |
| `traefik.frontend.headers.contentTypeNosniff=true` | Adds the `X-Content-Type-Options` header with the value `nosniff`. |
| `traefik.frontend.headers.browserXSSFilter=true` | Adds the X-XSS-Protection header with the value `1; mode=block`. |
| `traefik.frontend.headers.contentSecurityPolicy=VALUE` | Adds CSP Header with the custom value. |
| `traefik.frontend.headers.publicKey=VALUE` | Adds pinned HTST public key header. |
| `traefik.frontend.headers.referrerPolicy=VALUE` | Adds referrer policy header. |
| `traefik.frontend.headers.isDevelopment=false` | This will cause the `AllowedHosts`, `SSLRedirect`, and `STSSeconds`/`STSIncludeSubdomains` options to be ignored during development.<br>When deploying to production, be sure to set this to false. |
### On Service
Services labels can be used for overriding default behaviour
| Label | Description |
|---------------------------------------------------|--------------------------------------------------------------------------------------------------|
| `traefik.<service-name>.port=PORT` | Overrides `traefik.port`. If several ports need to be exposed, the service labels could be used. |
| `traefik.<service-name>.protocol` | Overrides `traefik.protocol`. |
| `traefik.<service-name>.weight` | Assign this service weight. Overrides `traefik.weight`. |
| `traefik.<service-name>.frontend.backend=BACKEND` | Assign this service frontend to `BACKEND`. Default is to assign to the service backend. |
| `traefik.<service-name>.frontend.entryPoints` | Overrides `traefik.frontend.entrypoints` |
| `traefik.<service-name>.frontend.auth.basic` | Sets a Basic Auth for that frontend |
| `traefik.<service-name>.frontend.passHostHeader` | Overrides `traefik.frontend.passHostHeader`. |
| `traefik.<service-name>.frontend.priority` | Overrides `traefik.frontend.priority`. |
| `traefik.<service-name>.frontend.rule` | Overrides `traefik.frontend.rule`. |
| `traefik.<service-name>.frontend.redirect` | Overrides `traefik.frontend.redirect`. |
| Label | Description |
|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|
| `traefik.<service-name>.port=PORT` | Overrides `traefik.port`. If several ports need to be exposed, the service labels could be used. |
| `traefik.<service-name>.protocol` | Overrides `traefik.protocol`. |
| `traefik.<service-name>.weight` | Assign this service weight. Overrides `traefik.weight`. |
| `traefik.<service-name>.frontend.backend=BACKEND` | Assign this service frontend to `BACKEND`. Default is to assign to the service backend. |
| `traefik.<service-name>.frontend.entryPoints` | Overrides `traefik.frontend.entrypoints` |
| `traefik.<service-name>.frontend.auth.basic` | Sets a Basic Auth for that frontend |
| `traefik.<service-name>.frontend.passHostHeader` | Overrides `traefik.frontend.passHostHeader`. |
| `traefik.<service-name>.frontend.priority` | Overrides `traefik.frontend.priority`. |
| `traefik.<service-name>.frontend.rule` | Overrides `traefik.frontend.rule`. |
| `traefik.<service-name>.frontend.redirect` | Overrides `traefik.frontend.redirect`. |
| `traefik.<service-name>.frontend.redirect.entryPoint=https` | Overrides `traefik.frontend.redirect.entryPoint`. |
| `traefik.<service-name>.frontend.redirect.regex=^http://localhost/(.*)` | Overrides `traefik.frontend.redirect.regex`. |
| `traefik.<service-name>.frontend.redirect.replacement=http://mydomain/$1` | Overrides `traefik.frontend.redirect.replacement`. |
!!! note
if a label is defined both as a `container label` and a `service label` (for example `traefik.<service-name>.port=PORT` and `traefik.port=PORT` ), the `service label` is used to defined the `<service-name>` property (`port` in the example).
If a label is defined both as a `container label` and a `service label` (for example `traefik.<service-name>.port=PORT` and `traefik.port=PORT` ), the `service label` is used to defined the `<service-name>` property (`port` in the example).
It's possible to mix `container labels` and `service labels`, in this case `container labels` are used as default value for missing `service labels` but no frontends are going to be created with the `container labels`.
More details in this [example](/user-guide/docker-and-lets-encrypt/#labels).
!!! warning
when running inside a container, Træfik will need network access through:
When running inside a container, Træfik will need network access through:
`docker network connect <network> <traefik-container>`

View File

@@ -8,6 +8,8 @@ You have three choices:
- [Rules in a Separate File](/configuration/backends/file/#rules-in-a-separate-file)
- [Multiple `.toml` Files](/configuration/backends/file/#multiple-toml-files)
To enable the file backend, you must either pass the `--file` option to the Træfik binary or put the `[file]` section (with or without inner settings) in the configuration file.
The configuration file allows managing both backends/frontends and HTTPS certificates (which are not [Let's Encrypt](https://letsencrypt.org) certificates generated through Træfik).
## Simple
@@ -25,8 +27,8 @@ defaultEntryPoints = ["http", "https"]
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
certFile = "integration/fixtures/https/snitest.org.cert"
[[entryPoints.https.tls.certificates]]
certFile = "integration/fixtures/https/snitest.org.cert"
keyFile = "integration/fixtures/https/snitest.org.key"
[file]
@@ -82,11 +84,17 @@ defaultEntryPoints = ["http", "https"]
rule = "Path:/test"
# HTTPS certificate
[[tlsConfiguration]]
entryPoints = ["https"]
[tlsConfiguration.certificate]
certFile = "integration/fixtures/https/snitest.com.cert"
keyFile = "integration/fixtures/https/snitest.com.key"
[[tls]]
entryPoints = ["https"]
[tls.certificate]
certFile = "path/to/my.cert"
keyFile = "path/to/my.key"
[[tls]]
entryPoints = ["https"]
[tls.certificate]
certFile = "path/to/my/other.cert"
keyFile = "path/to/my/other.key"
```
!!! note
@@ -153,19 +161,19 @@ filename = "rules.toml"
entrypoints = ["http", "https"] # overrides defaultEntryPoints
backend = "backend2"
rule = "Path:/test"
# HTTPS certificate
[[tlsConfiguration]]
entryPoints = ["https"]
[tlsConfiguration.certificate]
certFile = "integration/fixtures/https/snitest.com.cert"
keyFile = "integration/fixtures/https/snitest.com.key"
[[tlsConfiguration]]
entryPoints = ["https"]
[[tlsConfiguration.certificates]]
certFile = "integration/fixtures/https/snitest.org.cert"
keyFile = "integration/fixtures/https/snitest.org.key"
```
[[tls]]
entryPoints = ["https"]
[tls.certificate]
certFile = "path/to/my.cert"
keyFile = "path/to/my.key"
[[tls]]
entryPoints = ["https"]
[tls.certificate]
certFile = "path/to/my/other.cert"
keyFile = "path/to/my/other.key"
## Multiple `.toml` Files

View File

@@ -4,7 +4,6 @@ Træfik can be configured to use Kubernetes Ingress as a backend configuration.
See also [Kubernetes user guide](/user-guide/kubernetes).
## Configuration
```toml
@@ -44,7 +43,7 @@ See also [Kubernetes user guide](/user-guide/kubernetes).
#
# namespaces = ["default", "production"]
# Ingress label selector to identify Ingress objects that should be processed.
# Ingress label selector to filter Ingress objects that should be processed.
#
# Optional
# Default: empty (process all Ingresses)
@@ -75,77 +74,81 @@ See also [Kubernetes user guide](/user-guide/kubernetes).
### `endpoint`
The Kubernetes server endpoint.
The Kubernetes server endpoint as URL.
When deployed as a replication controller in Kubernetes, Traefik will use the environment variables `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` to construct the endpoint.
When deployed into Kubernetes, Traefik will read the environment variables `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` to construct the endpoint.
Secure token will be found in `/var/run/secrets/kubernetes.io/serviceaccount/token` and SSL CA cert in `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`
The access token will be looked up in `/var/run/secrets/kubernetes.io/serviceaccount/token` and the SSL CA certificate in `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`.
Both are provided mounted automatically when deployed inside Kubernetes.
The endpoint may be given to override the environment variable values.
The endpoint may be specified to override the environment variable values inside a cluster.
When the environment variables are not found, Traefik will try to connect to the Kubernetes API server with an external-cluster client.
In this case, the endpoint is required.
Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster from localhost.
Specifically, it may be set to the URL used by `kubectl proxy` to connect to a Kubernetes cluster using the granted autentication and authorization of the associated kubeconfig.
### `labelselector`
Ingress label selector to identify Ingress objects that should be processed.
By default, Traefik processes all Ingress objects in the configured namespaces.
A label selector can be defined to filter on specific Ingress objects only.
See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details.
## Annotations
Annotations can be used on containers to override default behaviour for the whole Ingress resource:
### General annotations
- `traefik.frontend.rule.type: PathPrefixStrip`
The following general annotations are applicable on the Ingress object:
- `traefik.frontend.rule.type: PathPrefixStrip`
Override the default frontend rule type. Default: `PathPrefix`.
- `traefik.frontend.priority: "3"`
Override the default frontend rule priority.
- `traefik.frontend.redirect: https`:
- `traefik.frontend.redirect.entryPoint: https`:
Enables Redirect to another entryPoint for that frontend (e.g. HTTPS).
- `traefik.frontend.entryPoints: http,https`
- `traefik.frontend.redirect.regex: ^http://localhost/(.*)`:
Redirect to another URL for that frontend. Must be set with `traefik.frontend.redirect.replacement`.
- `traefik.frontend.redirect.replacement: http://mydomain/$1`:
Redirect to another URL for that frontend. Must be set with `traefik.frontend.redirect.regex`.
- `traefik.frontend.entryPoints: http,https`
Override the default frontend endpoints.
- `traefik.frontend.passTLSCert: true`
- `traefik.frontend.passTLSCert: true`
Override the default frontend PassTLSCert value. Default: `false`.
Annotations can be used on the Kubernetes service to override default behaviour:
- `traefik.backend.loadbalancer.method=drr`
Override the default `wrr` load balancer algorithm
- `traefik.backend.loadbalancer.stickiness=true`
Enable backend sticky sessions
- `traefik.backend.loadbalancer.stickiness.cookieName=NAME`
Manually set the cookie name for sticky sessions
- `traefik.backend.loadbalancer.sticky=true`
Enable backend sticky sessions (DEPRECATED)
Additionally, an annotation can be used on Kubernetes services to set the [circuit breaker expression](/basics/#backends) for a backend.
- `traefik.backend.circuitbreaker: <expression>`
Set the circuit breaker expression for the backend. Default: `nil`.
As known from nginx when used as Kubernetes Ingress Controller, a list of IP-Ranges which are allowed to access can be configured by using an ingress annotation:
- `ingress.kubernetes.io/rewrite-target: /users`
Replaces each matched Ingress path with the specified one, and adds the old path to the `X-Replaced-Path` header.
- `ingress.kubernetes.io/whitelist-source-range: "1.2.3.0/24, fe80::/16"`
A comma-separated list of IP ranges permitted for access. all source IPs are permitted if the list is empty or a single range is ill-formatted.
An unset or empty list allows all Source-IPs to access.
If one of the Net-Specifications are invalid, the whole list is invalid and allows all Source-IPs to access.
!!! note
Please note that `traefik.frontend.redirect.regex` and `traefik.frontend.redirect.replacement` do not have to be set if `traefik.frontend.redirect.entryPoint` is defined for the redirection (they will not be used in this case).
#### Security annotations
The following annotations are applicable on the Service object associated with a particular Ingress object:
The following security annotations can be applied to the ingress object to add security features:
- `traefik.backend.loadbalancer.method=drr`
Override the default `wrr` load balancer algorithm.
- `traefik.backend.loadbalancer.stickiness=true`
Enable backend sticky sessions.
- `traefik.backend.loadbalancer.stickiness.cookieName=NAME`
Manually set the cookie name for sticky sessions.
- `traefik.backend.loadbalancer.sticky=true`
Enable backend sticky sessions (DEPRECATED).
- `traefik.backend.circuitbreaker: <expression>`
Set the circuit breaker expression for the backend.
| Annotation | Description |
|----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### Security annotations
The following security annotations are applicable on the Ingress object:
| Annotation | Description |
| -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ingress.kubernetes.io/allowed-hosts:EXPR` | Provides a list of allowed hosts that requests will be processed. Format: `Host1,Host2` |
| `ingress.kubernetes.io/custom-request-headers:EXPR ` | Provides the container with custom request headers that will be appended to each request forwarded to the container. Format: `HEADER:value,HEADER2:value2` |
| `ingress.kubernetes.io/custom-response-headers:EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client. Format: `HEADER:value,HEADER2:value2` |
| `ingress.kubernetes.io/proxy-headers:EXPR ` | Provides a list of headers that the proxied hostname may be stored. Format: `HEADER1,HEADER2` |
| `ingress.kubernetes.io/custom-request-headers:EXPR` | Provides the container with custom request headers that will be appended to each request forwarded to the container. Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `ingress.kubernetes.io/custom-response-headers:EXPR` | Appends the headers to each response returned by the container, before forwarding the response to the client. Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `ingress.kubernetes.io/proxy-headers:EXPR` | Provides a list of headers that the proxied hostname may be stored. Format: `HEADER1,HEADER2` |
| `ingress.kubernetes.io/ssl-redirect:true` | Forces the frontend to redirect to SSL if a non-SSL request is sent. |
| `ingress.kubernetes.io/ssl-temporary-redirect:true` | Forces the frontend to redirect to SSL if a non-SSL request is sent, but by sending a 302 instead of a 301. |
| `ingress.kubernetes.io/ssl-host:HOST` | This setting configures the hostname that redirects will be based on. Default is "", which is the same host as the request. |
| `ingress.kubernetes.io/ssl-proxy-headers:EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`). Format: `HEADER:value,HEADER2:value2` |
| `ingress.kubernetes.io/ssl-proxy-headers:EXPR` | Header combinations that would signify a proper SSL Request (Such as `X-Forwarded-For:https`). Format: <code>HEADER:value&vert;&vert;HEADER2:value2</code> |
| `ingress.kubernetes.io/hsts-max-age:315360000` | Sets the max-age of the HSTS header. |
| `ngress.kubernetes.io/hsts-include-subdomains:true` | Adds the IncludeSubdomains section of the STS header. |
| `ingress.kubernetes.io/hsts-preload:true` | Adds the preload flag to the HSTS header. |
@@ -161,17 +164,17 @@ The following security annotations can be applied to the ingress object to add s
### Authentication
Is possible to add additional authentication annotations in the Ingress rule.
The source of the authentication is a secret that contains usernames and passwords inside the key auth.
Is possible to add additional authentication annotations to the Ingress object.
The source of the authentication is a Secret object that contains the credentials.
- `ingress.kubernetes.io/auth-type`: `basic`
- `ingress.kubernetes.io/auth-secret`: `mysecret`
Contains the usernames and passwords with access to the paths defined in the Ingress Rule.
Contains the authentication type. The only permitted type is `basic`.
- `ingress.kubernetes.io/auth-secret`: `mysecret`
Contains the username and password with access to the paths defined in the Ingress object.
The secret must be created in the same namespace as the Ingress rule.
The secret must be created in the same namespace as the Ingress object.
Limitations:
The following limitations hold:
- Basic authentication only.
- Realm not configurable; only `traefik` default.
- Secret must contain only single file.
- The realm is not configurable; the only supported (and default) value is `traefik`.
- The Secret must contain a single file only.

View File

@@ -150,12 +150,15 @@ domain = "marathon.localhost"
To enable constraints see [backend-specific constraints section](/configuration/commons/#backend-specific).
## Labels: overriding default behaviour
### On Containers
Marathon labels may be used to dynamically change the routing and forwarding behaviour.
Labels can be used on containers to override default behaviour:
They may be specified on one of two levels: Application or service.
### Application Level
The following labels can be defined on Marathon applications. They adjust the behaviour for the entire application.
| Label | Description |
|-----------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -180,9 +183,9 @@ Labels can be used on containers to override default behaviour:
| `traefik.frontend.entryPoints=http,https` | assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash`. |
### On Services
### Service Level
If several ports need to be exposed from a container, the services labels can be used:
For applications that expose multiple ports, specific labels can be used to extract one frontend/backend configuration pair per port. Each such pair is called a _service_. The (freely choosable) name of the service is an integral part of the service label name.
| Label | Description |
|--------------------------------------------------------|------------------------------------------------------------------------------------------------------|

View File

@@ -120,19 +120,21 @@ secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Labels can be used on task containers to override default behaviour:
| Label | Description |
|-----------------------------------------------------------------------|------------------------------------------------------------------------------------------|
| `traefik.protocol=https` | Override the default `http` protocol |
| `traefik.weight=10` | Assign this weight to the container |
| `traefik.enable=false` | Disable this container in Træfik |
| `traefik.frontend.rule=Host:test.traefik.io` | Override the default frontend rule (Default: `Host:{containerName}.{domain}`). |
| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. |
| `traefik.frontend.priority=10` | Override default frontend priority |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.redirect=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) |
| `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5` | Create a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) |
| Label | Description |
|-----------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
| `traefik.protocol=https` | Override the default `http` protocol |
| `traefik.weight=10` | Assign this weight to the container |
| `traefik.enable=false` | Disable this container in Træfik |
| `traefik.frontend.rule=Host:test.traefik.io` | Override the default frontend rule (Default: `Host:{containerName}.{domain}`). |
| `traefik.frontend.passHostHeader=true` | Forward client `Host` header to the backend. |
| `traefik.frontend.priority=10` | Override default frontend priority |
| `traefik.frontend.entryPoints=http,https` | Assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. |
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication for that frontend in CSV format: `User:Hash,User:Hash`. |
| `traefik.frontend.redirect.entryPoint=https` | Enables Redirect to another entryPoint for that frontend (e.g. HTTPS) |
| `traefik.frontend.redirect.regex: ^http://localhost/(.*)` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.replacement`. |
| `traefik.frontend.redirect.replacement: http://mydomain/$1` | Redirect to another URL for that frontend.<br>Must be set with `traefik.frontend.redirect.regex`. |
| `traefik.backend.circuitbreaker.expression=NetworkErrorRatio() > 0.5` | Create a [circuit breaker](/basics/#backends) to be used against the backend |
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm |
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions |
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions |
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) |

View File

@@ -35,6 +35,15 @@ address = ":8080"
# Default: false
#
readOnly = true
# Set the root path for webui and API
#
# Deprecated
# Optional
#
# path = "/mypath"
#
```
## Web UI
@@ -80,7 +89,7 @@ Users can be specified directly in the toml file, or indirectly by referencing a
# To enable digest auth on the webui with 2 user/realm/pass: test:traefik:test and test2:traefik:test2
[web.auth.digest]
users = ["test:traefik:a2688e031edb4be6a3797f3882655c05 ", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"]
users = ["test:traefik:a2688e031edb4be6a3797f3882655c05", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"]
usersFile = "/path/to/.htdigest"
# ...
@@ -375,3 +384,35 @@ curl -s "http://localhost:8080/api" | jq .
}
}
```
## Path
As web is deprecated, you can handle the `Path` option like this
```toml
[entrypoints.http]
address=":80"
[entrypoints.dashboard]
address=":8080"
[entrypoints.api]
address=":8081"
#Activate API and Dashboard
[api]
entrypoint="api"
[file]
[backends]
[backends.backend1]
[backends.backend1.servers.server1]
url = "http://127.0.0.1:8081"
[frontends]
[frontends.frontend1]
entrypoints=["dashboard"]
backend = "backend1"
[frontends.frontend1.routes.test_1]
rule = "PathPrefixStrip:/yourprefix;PathPrefix:/yourprefix"
```

View File

@@ -27,9 +27,9 @@ watch = true
# Prefix used for KV store.
#
# Optional
# Default: "/traefik"
# Default: "traefik"
#
prefix = "/traefik"
prefix = "traefik"
# Override default configuration template.
# For advanced users :)

View File

@@ -277,6 +277,36 @@ Custom error pages are easiest to implement using the file provider.
For dynamic providers, the corresponding template file needs to be customized accordingly and referenced in the Traefik configuration.
## Rate limiting
Rate limiting can be configured per frontend.
Multiple sets of rates can be added to each frontend, but the time periods must be unique.
```toml
[frontends]
[frontends.frontend1]
passHostHeader = true
entrypoints = ["http"]
backend = "backend1"
[frontends.frontend1.routes.test_1]
rule = "Path:/"
[frontends.frontend1.ratelimit]
extractorfunc = "client.ip"
[frontends.frontend1.ratelimit.rateset.rateset1]
period = "10s"
average = 100
burst = 200
[frontends.frontend1.ratelimit.rateset.rateset2]
period = "3s"
average = 5
burst = 10
```
In the above example, frontend1 is configured to limit requests by the client's ip address.
An average of 5 requests every 3 seconds is allowed and an average of 100 requests every 10 seconds.
These can "burst" up to 10 and 200 in each period respectively.
## Retry Configuration
```toml

View File

@@ -55,6 +55,8 @@ To redirect an entrypoint rewriting the URL.
## TLS
### Static Certificates
Define an entrypoint with SNI support.
```toml
@@ -69,6 +71,12 @@ Define an entrypoint with SNI support.
!!! note
If an empty TLS configuration is done, default self-signed certificates are generated.
### Dynamic Certificates
If you need to add or remove TLS certificates while Traefik is started, Dynamic TLS certificates are supported using the [file provider](/configuration/backends/file).
## TLS Mutual Authentication
@@ -135,8 +143,8 @@ Users can be specified directly in the toml file, or indirectly by referencing a
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.auth.basic]
users = ["test:traefik:a2688e031edb4be6a3797f3882655c05 ", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"]
[entryPoints.http.auth.digest]
users = ["test:traefik:a2688e031edb4be6a3797f3882655c05", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"]
usersFile = "/path/to/.htdigest"
```

View File

@@ -22,7 +22,7 @@ If you want your users to access some of your microservices from the Internet, y
- path `domain.com/web` will point the microservice `web` in your private network
- domain `backoffice.domain.com` will point the microservices `backoffice` in your private network, load-balancing between your multiple instances
But a microservices architecture is dynamic... Services are added, removed, killed or upgraded often, eventually several times a day.
Microservices are often deployed in dynamic environments where services are added, removed, killed, upgraded or scaled many times a day.
Traditional reverse-proxies are not natively dynamic. You can't change their configuration and hot-reload easily.
@@ -108,7 +108,7 @@ version: '2'
services:
proxy:
image: traefik
command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG
command: --api --docker --docker.domain=docker.localhost --logLevel=DEBUG
networks:
- webgateway
ports:
@@ -129,7 +129,7 @@ Start it from within the `traefik` folder:
docker-compose up -d
```
In a browser you may open [http://localhost:8080](http://localhost:8080) to access Træfik's dashboard and observe the following magic.
In a browser, you may open [http://localhost:8080](http://localhost:8080) to access Træfik's dashboard and observe the following magic.
Now, create a folder named `test` and create a `docker-compose.yml` in it with this content:

View File

@@ -20,7 +20,7 @@
IN THE SOFTWARE.
-->
{% import "partials/language.html" as lang %}
{% import "partials/language.html" as lang with context %}
<!-- Application footer -->
<footer class="md-footer">
@@ -97,7 +97,7 @@
<!-- Social links -->
{% block social %}
{% include "partials/social.html" %}
{% include "partials/social.html" %}
{% endblock %}
</div>
</div>

View File

@@ -0,0 +1,294 @@
# Clustering / High Availability on Docker Swarm with Consul
This guide explains how to use Træfik in high availability mode in a Docker Swarm and with Let's Encrypt.
Why do we need Træfik in cluster mode? Running multiple instances should work out of the box?
If you want to use Let's Encrypt with Træfik, sharing configuration or TLS certificates between many Træfik instances, you need Træfik cluster/HA.
Ok, could we mount a shared volume used by all my instances? Yes, you can, but it will not work.
When you use Let's Encrypt, you need to store certificates, but not only.
When Træfik generates a new certificate, it configures a challenge and once Let's Encrypt will verify the ownership of the domain, it will ping back the challenge.
If the challenge is not knowing by other Træfik instances, the validation will fail.
For more information about challenge: [Automatic Certificate Management Environment (ACME)](https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#tls-with-server-name-indication-tls-sni)
## Prerequisites
You will need a working Docker Swarm cluster.
## Træfik configuration
In this guide, we will not use a TOML configuration file, but only command line flag.
With that, we can use the base image without mounting configuration file or building custom image.
What Træfik should do:
- Listen to 80 and 443
- Redirect HTTP traffic to HTTPS
- Generate SSL certificate when a domain is added
- Listen to Docker Swarm event
### EntryPoints configuration
TL;DR:
```shell
$ traefik \
--entrypoints=Name:http Address::80 Redirect.EntryPoint:https \
--entrypoints=Name:https Address::443 TLS \
--defaultentrypoints=http,https
```
To listen to different ports, we need to create an entry point for each.
The CLI syntax is `--entrypoints=Name:a_name Address:an_ip_or_empty:a_port options`.
If you want to redirect traffic from one entry point to another, it's the option `Redirect.EntryPoint:entrypoint_name`.
By default, we don't want to configure all our services to listen on http and https, we add a default entry point configuration: `--defaultentrypoints=http,https`.
### Let's Encrypt configuration
TL;DR:
```shell
$ traefik \
--acme \
--acme.storage=/etc/traefik/acme/acme.json \
--acme.entryPoint=https \
--acme.httpChallenge.entryPoint=http \
--acme.email=contact@mydomain.ca
```
Let's Encrypt needs 4 parameters: an TLS entry point to listen to, a non-TLS entry point to allow HTTP challenges, a storage for certificates, and an email for the registration.
To enable Let's Encrypt support, you need to add `--acme` flag.
Now, Træfik needs to know where to store the certificates, we can choose between a key in a Key-Value store, or a file path: `--acme.storage=my/key` or `--acme.storage=/path/to/acme.json`.
The `acme.httpChallenge.entryPoint` flag enables the `HTTP-01` challenge and specifies the entryPoint to use during the challenges.
For your email and the entry point, it's `--acme.entryPoint` and `--acme.email` flags.
### Docker configuration
TL;DR:
```shell
$ traefik \
--docker \
--docker.swarmmode \
--docker.domain=mydomain.ca \
--docker.watch
```
To enable docker and swarm-mode support, you need to add `--docker` and `--docker.swarmmode` flags.
To watch docker events, add `--docker.watch`.
### Full docker-compose file
```yaml
version: "3"
services:
traefik:
image: traefik:1.5
command:
- "--api"
- "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https"
- "--entrypoints=Name:https Address::443 TLS"
- "--defaultentrypoints=http,https"
- "--acme"
- "--acme.storage=/etc/traefik/acme/acme.json"
- "--acme.entryPoint=https"
- "--acme.httpChallenge.entryPoint=http"
- "--acme.OnHostRule=true"
- "--acme.onDemand=false"
- "--acme.email=contact@mydomain.ca"
- "--docker"
- "--docker.swarmmode"
- "--docker.domain=mydomain.ca"
- "--docker.watch"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- webgateway
- traefik
ports:
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
- target: 8080
published: 8080
mode: host
deploy:
mode: global
placement:
constraints:
- node.role == manager
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
networks:
webgateway:
driver: overlay
external: true
traefik:
driver: overlay
```
## Migrate configuration to Consul
We created a special Træfik command to help configuring your Key Value store from a Træfik TOML configuration file and/or CLI flags.
## Deploy a Træfik cluster
The best way we found is to have an initializer service.
This service will push the config to Consul via the `storeconfig` sub-command.
This service will retry until finishing without error because Consul may not be ready when the service tries to push the configuration.
The initializer in a docker-compose file will be:
```yaml
traefik_init:
image: traefik:1.5
command:
- "storeconfig"
- "--api"
[...]
- "--consul"
- "--consul.endpoint=consul:8500"
- "--consul.prefix=traefik"
networks:
- traefik
deploy:
restart_policy:
condition: on-failure
depends_on:
- consul
```
And now, the Træfik part will only have the Consul configuration.
```yaml
traefik:
image: traefik:1.5
depends_on:
- traefik_init
- consul
command:
- "--consul"
- "--consul.endpoint=consul:8500"
- "--consul.prefix=traefik"
[...]
```
!!! note
For Træfik <1.5.0 add `acme.storage=traefik/acme/account` because Træfik is not reading it from Consul.
If you have some update to do, update the initializer service and re-deploy it.
The new configuration will be stored in Consul, and you need to restart the Træfik node: `docker service update --force traefik_traefik`.
## Full docker-compose file
```yaml
version: "3.4"
services:
traefik_init:
image: traefik:1.5
command:
- "storeconfig"
- "--api"
- "--entrypoints=Name:http Address::80 Redirect.EntryPoint:https"
- "--entrypoints=Name:https Address::443 TLS"
- "--defaultentrypoints=http,https"
- "--acme"
- "--acme.storage=traefik/acme/account"
- "--acme.entryPoint=https"
- "--acme.httpChallenge.entryPoint=http"
- "--acme.OnHostRule=true"
- "--acme.onDemand=false"
- "--acme.email=foobar@example.com"
- "--docker"
- "--docker.swarmmode"
- "--docker.domain=example.com"
- "--docker.watch"
- "--consul"
- "--consul.endpoint=consul:8500"
- "--consul.prefix=traefik"
networks:
- traefik
deploy:
restart_policy:
condition: on-failure
depends_on:
- consul
traefik:
image: traefik:1.5
depends_on:
- traefik_init
- consul
command:
- "--consul"
- "--consul.endpoint=consul:8500"
- "--consul.prefix=traefik"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- webgateway
- traefik
ports:
- target: 80
published: 80
mode: host
- target: 443
published: 443
mode: host
- target: 8080
published: 8080
mode: host
deploy:
mode: global
placement:
constraints:
- node.role == manager
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
consul:
image: consul
command: agent -server -bootstrap-expect=1
volumes:
- consul-data:/consul/data
environment:
- CONSUL_LOCAL_CONFIG={"datacenter":"us_east2","server":true}
- CONSUL_BIND_INTERFACE=eth0
- CONSUL_CLIENT_INTERFACE=eth0
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
restart_policy:
condition: on-failure
networks:
- traefik
networks:
webgateway:
driver: overlay
external: true
traefik:
driver: overlay
volumes:
consul-data:
driver: [not local]
```

View File

@@ -104,6 +104,8 @@ email = "your-email-here@my-awesome-app.org"
storage = "acme.json"
entryPoint = "https"
OnHostRule = true
[acme.httpChallenge]
entryPoint = "http"
```
This is the minimum configuration required to do the following:

View File

@@ -6,6 +6,7 @@ You will find here some configuration examples of Træfik.
```toml
defaultEntryPoints = ["http"]
[entryPoints]
[entryPoints.http]
address = ":80"
@@ -15,6 +16,7 @@ defaultEntryPoints = ["http"]
```toml
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
@@ -34,6 +36,7 @@ Note that we can either give path to certificate file or directly the file conte
```toml
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
@@ -52,10 +55,16 @@ defaultEntryPoints = ["http", "https"]
## Let's Encrypt support
### Basic example
!!! note
Even if `TLS-SNI-01` challenge is [disabled](https://community.letsencrypt.org/t/2018-01-11-update-regarding-acme-tls-sni-and-shared-hosting-infrastructure/50188), for the moment, it stays the _by default_ ACME Challenge in Træfik but all the examples use the `HTTP-01` challenge (except DNS challenge examples).
If `TLS-SNI-01` challenge is not re-enabled in the future, it we will be removed from Træfik.
### Basic example with HTTP challenge
```toml
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
@@ -65,6 +74,8 @@ email = "test@traefik.io"
storage = "acme.json"
caServer = "http://172.18.0.1:4000/directory"
entryPoint = "https"
[acme.httpChallenge]
entryPoint = "http"
[[acme.domains]]
main = "local1.com"
@@ -78,14 +89,16 @@ entryPoint = "https"
main = "local4.com"
```
This configuration allows generating Let's Encrypt certificates for the four domains `local[1-4].com` with described SANs.
This configuration allows generating Let's Encrypt certificates (thanks to `HTTP-01` challenge) for the four domains `local[1-4].com` with described SANs.
Traefik generates these certificates when it starts and it needs to be restart if new domains are added.
### OnHostRule option
### OnHostRule option (with HTTP challenge)
```toml
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
@@ -96,6 +109,8 @@ storage = "acme.json"
onHostRule = true
caServer = "http://172.18.0.1:4000/directory"
entryPoint = "https"
[acme.httpChallenge]
entryPoint = "http"
[[acme.domains]]
main = "local1.com"
@@ -109,16 +124,18 @@ entryPoint = "https"
main = "local4.com"
```
This configuration allows generating Let's Encrypt certificates for the four domains `local[1-4].com`.
This configuration allows generating Let's Encrypt certificates (thanks to `HTTP-01` challenge) for the four domains `local[1-4].com`.
Traefik generates these certificates when it starts.
If a backend is added with a `onHost` rule, Traefik will automatically generate the Let's Encrypt certificate for the new domain.
### OnDemand option
### OnDemand option (with HTTP challenge)
```toml
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
@@ -129,9 +146,11 @@ storage = "acme.json"
onDemand = true
caServer = "http://172.18.0.1:4000/directory"
entryPoint = "https"
[acme.httpChallenge]
entryPoint = "http"
```
This configuration allows generating a Let's Encrypt certificate during the first HTTPS request on a new domain.
This configuration allows generating a Let's Encrypt certificate (thanks to `HTTP-01` challenge) during the first HTTPS request on a new domain.
!!! note
@@ -153,10 +172,11 @@ This configuration allows generating a Let's Encrypt certificate during the firs
[acme]
email = "test@traefik.io"
storage = "acme.json"
dnsProvider = "digitalocean" # DNS Provider name (cloudflare, OVH, gandi...)
delayDontCheckDNS = 0
caServer = "http://172.18.0.1:4000/directory"
entryPoint = "https"
[acme.dnsChallenge]
provider = "digitalocean" # DNS Provider name (cloudflare, OVH, gandi...)
delayBeforeCheck = 0
[[acme.domains]]
main = "local1.com"
@@ -173,12 +193,14 @@ entryPoint = "https"
DNS challenge needs environment variables to be executed.
This variables have to be set on the machine/container which host Traefik.
These variables are described [in this section](/configuration/acme/#dnsprovider).
These variables are described [in this section](/configuration/acme/#provider).
### OnHostRule option and provided certificates
### OnHostRule option and provided certificates (with HTTP challenge)
```toml
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
@@ -192,10 +214,11 @@ storage = "acme.json"
onHostRule = true
caServer = "http://172.18.0.1:4000/directory"
entryPoint = "https"
[acme.httpChallenge]
entryPoint = "http"
```
Traefik will only try to generate a Let's encrypt certificate if the domain cannot be checked by the provided certificates.
Traefik will only try to generate a Let's encrypt certificate (thanks to `HTTP-01` challenge) if the domain cannot be checked by the provided certificates.
### Cluster mode
@@ -207,6 +230,8 @@ Before you use Let's Encrypt in a Traefik cluster, take a look to [the key-value
```toml
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
@@ -217,6 +242,9 @@ storage = "traefik/acme/account"
caServer = "http://172.18.0.1:4000/directory"
entryPoint = "https"
[acme.httpChallenge]
entryPoint = "http"
[[acme.domains]]
main = "local1.com"
sans = ["test1.local1.com", "test2.local1.com"]
@@ -244,10 +272,12 @@ The `consul` provider contains the configuration.
```toml
[frontends]
[frontends.frontend1]
backend = "backend2"
[frontends.frontend1.routes.test_1]
rule = "Host:test.localhost"
[frontends.frontend2]
backend = "backend1"
passHostHeader = true
@@ -255,10 +285,11 @@ The `consul` provider contains the configuration.
entrypoints = ["https"] # overrides defaultEntryPoints
[frontends.frontend2.routes.test_1]
rule = "Host:{subdomain:[a-z]+}.localhost"
[frontends.frontend3]
entrypoints = ["http", "https"] # overrides defaultEntryPoints
backend = "backend2"
rule = "Path:/test"
rule = "Path:/test"
```
## Enable Basic authentication in an entrypoint
@@ -272,6 +303,7 @@ Passwords are encoded in MD5: you can use htpasswd to generate those ones.
```toml
defaultEntryPoints = ["http"]
[entryPoints]
[entryPoints.http]
address = ":80"
@@ -286,6 +318,7 @@ via a configurable header value.
```toml
defaultEntryPoints = ["http"]
[entryPoints]
[entryPoints.http]
address = ":80"
@@ -306,7 +339,7 @@ idleTimeout = "360s"
## Securing Ping Health Check
The `/ping` health-check URL is enabled together with the web admin panel, enabled with the command-line `--web` or config file option `[web]`.
The `/ping` health-check URL is enabled with the command-line `--ping` or config file option `[ping]`.
Thus, if you have a regular path for `/foo` and an entrypoint on `:80`, you would access them as follows:
* Regular path: `http://hostname:80/foo`

View File

@@ -57,8 +57,7 @@ RootCAs = [ "./backend.cert" ]
keyFile = "./frontend.key"
[web]
address = ":8080"
[api]
[file]

View File

@@ -1,6 +1,6 @@
# Kubernetes Ingress Controller
This guide explains how to use Træfik as an Ingress controller in a Kubernetes cluster.
This guide explains how to use Træfik as an Ingress controller for a Kubernetes cluster.
If you are not familiar with Ingresses in Kubernetes you might want to read the [Kubernetes user guide](https://kubernetes.io/docs/concepts/services-networking/ingress/)
@@ -8,8 +8,10 @@ The config files used in this guide can be found in the [examples directory](htt
## Prerequisites
1. A working Kubernetes cluster. If you want to follow along with this guide, you should setup [minikube](https://kubernetes.io/docs/getting-started-guides/minikube/)
on your machine, as it is the quickest way to get a local Kubernetes cluster setup for experimentation and development.
1. A working Kubernetes cluster. If you want to follow along with this guide, you should setup [minikube](https://kubernetes.io/docs/getting-started-guides/minikube/) on your machine, as it is the quickest way to get a local Kubernetes cluster setup for experimentation and development.
!!! note
The guide is likely not fully adequate for a production-ready setup.
2. The `kubectl` binary should be [installed on your workstation](https://kubernetes.io/docs/getting-started-guides/minikube/#download-kubectl).
@@ -21,6 +23,9 @@ If your cluster is configured with RBAC, you will need to authorize Træfik to u
RoleBindings per namespace enable to restrict granted permissions to the very namespaces only that Træfik is watching over, thereby following the least-privileges principle. This is the preferred approach if Træfik is not supposed to watch all namespaces, and the set of namespaces does not change dynamically. Otherwise, a single ClusterRoleBinding must be employed.
!!! note
RoleBindings per namespace are available in Træfik 1.5 and later. Please use ClusterRoleBindings for older versions.
For the sake of simplicity, this guide will use a ClusterRoleBinding:
```yaml
@@ -75,9 +80,9 @@ For namespaced restrictions, one RoleBinding is required per watched namespace a
It is possible to use Træfik with a [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) or a [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) object,
whereas both options have their own pros and cons:
- The scalability is much better when using a Deployment, because you will have a Single-Pod-per-Node model when using the DeaemonSet.
- It is possible to exclusively run a Service on a dedicated set of machines using taints and tolerations with a DaemonSet.
- The scalability is much better when using a Deployment, because you will have a Single-Pod-per-Node model when using the DeaemonSet.
- It is possible to exclusively run a Service on a dedicated set of machines using taints and tolerations with a DaemonSet.
- On the other hand the DaemonSet allows you to access any Node directly on Port 80 and 443, where you have to setup a [Service](https://kubernetes.io/docs/concepts/services-networking/service/) object with a Deployment.
The Deployment objects looks like this:
@@ -114,7 +119,7 @@ spec:
- image: traefik
name: traefik-ingress-lb
args:
- --web
- --api
- --kubernetes
---
kind: Service
@@ -134,6 +139,7 @@ spec:
name: admin
type: NodePort
```
[examples/k8s/traefik-deployment.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/traefik-deployment.yaml)
!!! note
@@ -179,7 +185,7 @@ spec:
privileged: true
args:
- -d
- --web
- --api
- --kubernetes
---
kind: Service
@@ -230,7 +236,7 @@ Start by listing the pods in the `kube-system` namespace:
kubectl --namespace=kube-system get pods
```
```
```shell
NAME READY STATUS RESTARTS AGE
kube-addon-manager-minikubevm 1/1 Running 0 4h
kubernetes-dashboard-s8krj 1/1 Running 0 4h
@@ -247,40 +253,45 @@ _It might take a few moments for kubernetes to pull the Træfik image and start
You should now be able to access Træfik on port 80 of your Minikube instance when using the DaemonSet:
```sh
```shell
curl $(minikube ip)
```
```
```shell
404 page not found
```
If you decided to use the deployment, then you need to target the correct NodePort, which can be seen then you execute `kubectl get services --namespace=kube-system`.
If you decided to use the deployment, then you need to target the correct NodePort, which can be seen when you execute `kubectl get services --namespace=kube-system`.
```sh
```shell
curl $(minikube ip):<NODEPORT>
```
```
```shell
404 page not found
```
!!! note
We expect to see a 404 response here as we haven't yet given Træfik any configuration.
All further examples below assume a DaemonSet installation. Deployment users will need to append the NodePort when constructing requests.
## Deploy Træfik using Helm Chart
Instead of installing Træfik via an own object, you can also use the Træfik Helm chart.
!!! note
The Helm Chart is maintained by the community, not the Traefik project maintainers.
This allows more complex configuration via Kubernetes [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configmap/) and enabled TLS certificates.
Instead of installing Træfik via Kubernetes object directly, you can also use the Træfik Helm chart.
Install Træfik chart by:
Install the Træfik chart by:
```shell
helm install stable/traefik
```
For more information, check out [the doc](https://github.com/kubernetes/charts/tree/master/stable/traefik).
For more information, check out [the documentation](https://github.com/kubernetes/charts/tree/master/stable/traefik).
## Submitting An Ingress to the cluster.
## Submitting an Ingress to the Cluster
Lets start by creating a Service and an Ingress that will expose the [Træfik Web UI](https://github.com/containous/traefik#web-ui).
@@ -313,30 +324,29 @@ spec:
serviceName: traefik-web-ui
servicePort: 80
```
[examples/k8s/ui.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/ui.yaml)
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/ui.yaml
```
Now lets setup an entry in our /etc/hosts file to route `traefik-ui.minikube` to our cluster.
Now lets setup an entry in our `/etc/hosts` file to route `traefik-ui.minikube` to our cluster.
In production you would want to set up real dns entries.
You can get the ip address of your minikube instance by running `minikube ip`
In production you would want to set up real DNS entries.
You can get the IP address of your minikube instance by running `minikube ip`:
```shell
echo "$(minikube ip) traefik-ui.minikube" | sudo tee -a /etc/hosts
```
We should now be able to visit [traefik-ui.minikube](http://traefik-ui.minikube) in the browser and view the Træfik Web UI.
We should now be able to visit [traefik-ui.minikube](http://traefik-ui.minikube) in the browser and view the Træfik web UI.
## Basic Authentication
It's possible to add additional authentication annotations in the Ingress rule.
The source of the authentication is a secret that contains usernames and passwords inside the key auth.
To read about basic auth limitations see the [Kubernetes Ingress](/configuration/backends/kubernetes) configuration page.
It's possible to protect access to Traefik through basic authentication. (See the [Kubernetes Ingress](/configuration/backends/kubernetes) configuration page for syntactical details and restrictions.)
#### Creating the Secret
### Creating the Secret
A. Use `htpasswd` to create a file containing the username and the base64-encoded password:
@@ -350,25 +360,28 @@ You will be prompted for a password which you will have to enter twice.
```shell
cat auth
```
```
```shell
myusername:$apr1$78Jyn/1K$ERHKVRPPlzAX8eBtLuvRZ0
```
B. Now use `kubectl` to create a secret in the monitoring namespace using the file created by `htpasswd`.
B. Now use `kubectl` to create a secret in the `monitoring` namespace using the file created by `htpasswd`.
```shell
kubectl create secret generic mysecret --from-file auth --namespace=monitoring
```
!!! note
Secret must be in same namespace as the ingress rule.
Secret must be in same namespace as the Ingress object.
C. Create the ingress using the following annotations to specify basic auth and that the username and password is stored in `mysecret`.
C. Attach the following annotations to the Ingress object:
- `ingress.kubernetes.io/auth-type: "basic"`
- `ingress.kubernetes.io/auth-secret: "mysecret"`
Following is a full ingress example based on Prometheus:
They specify basic authentication and reference the Secret `mysecret` containing the credentials.
Following is a full Ingress example based on Prometheus:
```yaml
apiVersion: extensions/v1beta1
@@ -390,17 +403,17 @@ spec:
servicePort: 9090
```
You can apply the example ingress as following:
You can apply the example as following:
```shell
kubectl create -f prometheus-ingress.yaml -n monitoring
```
## Name based routing
## Name-based Routing
In this example we are going to setup websites for 3 of the United Kingdoms best loved cheeses, Cheddar, Stilton and Wensleydale.
In this example we are going to setup websites for three of the United Kingdoms best loved cheeses: Cheddar, Stilton, and Wensleydale.
First lets start by launching the 3 pods for the cheese websites.
First lets start by launching the pods for the cheese websites.
```yaml
---
@@ -482,13 +495,14 @@ spec:
ports:
- containerPort: 80
```
[examples/k8s/cheese-deployments.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-deployments.yaml)
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheese-deployments.yaml
```
Next we need to setup a service for each of the cheese pods.
Next we need to setup a Service for each of the cheese pods.
```yaml
---
@@ -537,7 +551,6 @@ spec:
!!! note
We also set a [circuit breaker expression](/basics/#backends) for one of the backends by setting the `traefik.backend.circuitbreaker` annotation on the service.
[examples/k8s/cheese-services.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-services.yaml)
```shell
@@ -577,6 +590,7 @@ spec:
serviceName: wensleydale
servicePort: http
```
[examples/k8s/cheese-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheese-ingress.yaml)
!!! note
@@ -587,7 +601,7 @@ kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/exa
```
Now visit the [Træfik dashboard](http://traefik-ui.minikube/) and you should see a frontend for each host.
Along with a backend listing for each service with a Server set up for each pod.
Along with a backend listing for each service with a server set up for each pod.
If you edit your `/etc/hosts` again you should be able to access the cheese websites in your browser.
@@ -595,11 +609,11 @@ If you edit your `/etc/hosts` again you should be able to access the cheese webs
echo "$(minikube ip) stilton.minikube cheddar.minikube wensleydale.minikube" | sudo tee -a /etc/hosts
```
* [Stilton](http://stilton.minikube/)
* [Cheddar](http://cheddar.minikube/)
* [Wensleydale](http://wensleydale.minikube/)
- [Stilton](http://stilton.minikube/)
- [Cheddar](http://cheddar.minikube/)
- [Wensleydale](http://wensleydale.minikube/)
## Path based routing
## Path-based Routing
Now lets suppose that our fictional client has decided that while they are super happy about our cheesy web design, when they asked for 3 websites they had not really bargained on having to buy 3 domain names.
@@ -631,10 +645,11 @@ spec:
serviceName: wensleydale
servicePort: http
```
[examples/k8s/cheeses-ingress.yaml](https://github.com/containous/traefik/tree/master/examples/k8s/cheeses-ingress.yaml)
!!! note
we are configuring Træfik to strip the prefix from the url path with the `traefik.frontend.rule.type` annotation so that we can use the containers from the previous example without modification.
We are configuring Træfik to strip the prefix from the url path with the `traefik.frontend.rule.type` annotation so that we can use the containers from the previous example without modification.
```shell
kubectl apply -f https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/cheeses-ingress.yaml
@@ -646,14 +661,14 @@ echo "$(minikube ip) cheeses.minikube" | sudo tee -a /etc/hosts
You should now be able to visit the websites in your browser.
* [cheeses.minikube/stilton](http://cheeses.minikube/stilton/)
* [cheeses.minikube/cheddar](http://cheeses.minikube/cheddar/)
* [cheeses.minikube/wensleydale](http://cheeses.minikube/wensleydale/)
- [cheeses.minikube/stilton](http://cheeses.minikube/stilton/)
- [cheeses.minikube/cheddar](http://cheeses.minikube/cheddar/)
- [cheeses.minikube/wensleydale](http://cheeses.minikube/wensleydale/)
## Specifying priority for routing
## Specifying Routing Priorities
Sometimes you need to specify priority for ingress route, especially when handling wildcard routes.
This can be done by adding annotation `traefik.frontend.priority`, i.e.:
Sometimes you need to specify priority for ingress routes, especially when handling wildcard routes.
This can be done by adding the `traefik.frontend.priority` annotation, i.e.:
```yaml
apiVersion: extensions/v1beta1
@@ -688,34 +703,33 @@ spec:
servicePort: http
```
Note that priority values must be quoted to avoid them being interpreted as numbers (which are illegal for annotations).
Note that priority values must be quoted to avoid numeric interpretation (which are illegal for annotations).
## Forwarding to ExternalNames
When specifying an [ExternalName](https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors),
Træfik will forward requests to the given host accordingly and use HTTPS when the Service port matches 443.
Træfik will forward requests to the given host accordingly and use HTTPS when the Service port matches 443.
This still requires setting up a proper port mapping on the Service from the Ingress port to the (external) Service port.
## Disable passing the Host header
## Disable passing the Host Header
By default Træfik will pass the incoming Host header on to the upstream resource.
By default Træfik will pass the incoming Host header to the upstream resource.
There are times however where you may not want this to be the case.
For example if your service is of the ExternalName type.
However, there are times when you may not want this to be the case. For example, if your service is of the ExternalName type.
### Disable entirely
### Disable globally
Add the following to your toml config:
Add the following to your TOML configuration file:
```toml
disablePassHostHeaders = true
```
### Disable per ingress
### Disable per Ingress
To disable passing the Host header per ingress resource set the `traefik.frontend.passHostHeader` annotation on your ingress to `false`.
To disable passing the Host header per ingress resource set the `traefik.frontend.passHostHeader` annotation on your ingress to `"false"`.
Here is an example ingress definition:
Here is an example definition:
```yaml
apiVersion: extensions/v1beta1
@@ -751,12 +765,11 @@ spec:
externalName: static.otherdomain.com
```
If you were to visit `example.com/static` the request would then be passed onto `static.otherdomain.com/static` and s`tatic.otherdomain.com` would receive the request with the Host header being `static.otherdomain.com`.
If you were to visit `example.com/static` the request would then be passed on to `static.otherdomain.com/static`, and `static.otherdomain.com` would receive the request with the Host header being `static.otherdomain.com`.
!!! note
The per ingress annotation overides whatever the global value is set to.
So you could set `disablePassHostHeaders` to `true` in your toml file and then enable passing
the host header per ingress if you wanted.
The per-ingress annotation overrides whatever the global value is set to.
So you could set `disablePassHostHeaders` to `true` in your TOML configuration file and then enable passing the host header per ingress if you wanted.
## Partitioning the Ingress object space

View File

@@ -70,10 +70,13 @@ logLevel = "DEBUG"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.api]
address = ":8081"
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
certFile = "integration/fixtures/https/snitest.com.cert"
@@ -94,8 +97,8 @@ defaultEntryPoints = ["http", "https"]
watch = true
prefix = "traefik"
[web]
address = ":8081"
[api]
entrypoint = "api"
```
And there, the same global configuration in the Key-value Store (using `prefix = "traefik"`):
@@ -105,17 +108,18 @@ And there, the same global configuration in the Key-value Store (using `prefix =
| `/traefik/loglevel` | `DEBUG` |
| `/traefik/defaultentrypoints/0` | `http` |
| `/traefik/defaultentrypoints/1` | `https` |
| `/traefik/entrypoints/api/address` | `:8081` |
| `/traefik/entrypoints/http/address` | `:80` |
| `/traefik/entrypoints/https/address` | `:443` |
| `/traefik/entrypoints/https/tls/certificates/0/certfile` | `integration/fixtures/https/snitest.com.cert` |
| `/traefik/entrypoints/https/tls/certificates/0/keyfile` | `integration/fixtures/https/snitest.com.key` |
| `/traefik/entrypoints/https/tls/certificates/1/certfile` | `--BEGIN CERTIFICATE--<cert file content>--END CERTIFICATE--` |
| `/traefik/entrypoints/https/tls/certificates/1/keyfile` | `--BEGIN CERTIFICATE--<key file content>--END CERTIFICATE--` |
| `/traefik/entrypoints/other-https/address` | `:4443`
| `/traefik/entrypoints/other-https/address` | `:4443` |
| `/traefik/consul/endpoint` | `127.0.0.1:8500` |
| `/traefik/consul/watch` | `true` |
| `/traefik/consul/prefix` | `traefik` |
| `/traefik/web/address` | `:8081` |
| `/traefik/api/entrypoint` | `api` |
In case you are setting key values manually:
@@ -270,14 +274,14 @@ Here is the toml configuration we would like to store in the store :
backend = "backend2"
rule = "Path:/test"
[[tlsConfiguration]]
[[tls]]
entryPoints = ["https"]
[tlsConfiguration.certificate]
[tls.certificate]
certFile = "path/to/your.cert"
keyFile = "path/to/your.key"
[[tlsConfiguration]]
[[tls]]
entryPoints = ["https","other-https"]
[tlsConfiguration.certificate]
[tls.certificate]
certFile = """-----BEGIN CERTIFICATE-----
<cert file content>
-----END CERTIFICATE-----"""
@@ -331,19 +335,20 @@ And there, the same dynamic configuration in a KV Store (using `prefix = "traefi
- certificate 1
| Key | Value |
|----------------------------------------------------|--------------------|
| `/traefik/tlsconfiguration/1/entrypoints` | `https` |
| `/traefik/tlsconfiguration/1/certificate/certfile` | `path/to/your.cert`|
| `/traefik/tlsconfiguration/1/certificate/keyfile` | `path/to/your.key` |
| Key | Value |
|---------------------------------------|--------------------|
| `/traefik/tls/1/entrypoints` | `https` |
| `/traefik/tls/1/certificate/certfile` | `path/to/your.cert`|
| `/traefik/tls/1/certificate/keyfile` | `path/to/your.key` |
- certificate 2
| Key | Value |
|----------------------------------------------------|-----------------------|
| `/traefik/tlsconfiguration/2/entrypoints` | `https,other-https` |
| `/traefik/tlsconfiguration/2/certificate/certfile` | `<cert file content>` |
| `/traefik/tlsconfiguration/2/certificate/certfile` | `<key file content>` |
| Key | Value |
|---------------------------------------|-----------------------|
| `/traefik/tls/2/entrypoints` | `https,other-https` |
| `/traefik/tls/2/certificate/certfile` | `<cert file content>` |
| `/traefik/tls/2/certificate/certfile` | `<key file content>` |
### Atomic configuration changes
Træfik can watch the backends/frontends configuration changes and generate its configuration automatically.
@@ -378,9 +383,9 @@ Here, although the `/traefik_configurations/2/...` keys have been set, the old c
| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` |
| `/traefik_configurations/2/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` |
| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` |
| `/traefik_configurations/2/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` |
| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` |
Once the `/traefik/alias` key is updated, the new `/traefik_configurations/2` configuration becomes active atomically.
@@ -392,9 +397,9 @@ Here, we have a 50% balance between the `http://172.17.0.3:80` and the `http://1
| `/traefik_configurations/1/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
| `/traefik_configurations/1/backends/backend1/servers/server1/weight` | `10` |
| `/traefik_configurations/2/backends/backend1/servers/server1/url` | `http://172.17.0.3:80` |
| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` |
| `/traefik_configurations/2/backends/backend1/servers/server1/weight` | `5` |
| `/traefik_configurations/2/backends/backend1/servers/server2/url` | `http://172.17.0.4:80` |
| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` |
| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` |
!!! note
Træfik *will not watch for key changes in the `/traefik_configurations` prefix*. It will only watch for changes in the `/traefik/alias`.
@@ -403,7 +408,7 @@ Here, we have a 50% balance between the `http://172.17.0.3:80` and the `http://1
## Store configuration in Key-value store
!!! note
Don't forget to [setup the connection between Træfik and Key-value store](/user-guide/kv-config/#launch-trfk).
Don't forget to [setup the connection between Træfik and Key-value store](/user-guide/kv-config/#launch-trfik).
The static Træfik configuration in a key-value store can be automatically created and updated, using the [`storeconfig` subcommand](/basics/#commands).
@@ -411,7 +416,7 @@ The static Træfik configuration in a key-value store can be automatically creat
traefik storeconfig [flags] ...
```
This command is here only to automate the [process which upload the configuration into the Key-value store](/user-guide/kv-config/#upload-the-configuration-in-the-key-value-store).
Træfik will not start but the [static configuration](/basics/#static-trfk-configuration) will be uploaded into the Key-value store.
Træfik will not start but the [static configuration](/basics/#static-trfik-configuration) will be uploaded into the Key-value store.
If you configured ACME (Let's Encrypt), your registration account and your certificates will also be uploaded.

View File

@@ -28,6 +28,24 @@ Following is the order by which Traefik tries to identify the port (the first on
1. The port from the application's `portDefinitions` field (possibly indexed through the `traefik.portIndex` label, otherwise the first one).
1. The port from the application's `ipAddressPerTask` field (possibly indexed through the `traefik.portIndex` label, otherwise the first one).
## Applications with multiple ports
Some Marathon applications may expose multiple ports. Traefik supports creating one so-called _service_ per port using [specific labels](/configuration/backends/marathon#service-level).
For instance, assume that a Marathon application exposes a web API on port 80 and an admin interface on port 8080. It would then be possible to make each service available by specifying the following Marathon labels:
```
traefik.web.port=80
```
```
traefik.admin.port=8080
```
(Note that the service names `web` and `admin` can be chosen arbitrarily.)
Technically, Traefik will create one pair of frontend and backend configurations for each service.
## Achieving high availability
### Scenarios

View File

@@ -90,7 +90,7 @@ docker-machine ssh manager "docker service create \
--docker.swarmmode \
--docker.domain=traefik \
--docker.watch \
--web"
--api"
```
Let's explain this command:
@@ -102,7 +102,7 @@ Let's explain this command:
| `--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock` | we bind mount the docker socket where Træfik is scheduled to be able to speak to the daemon. |
| `--network traefik-net` | we attach the Træfik service (and thus the underlying container) to the `traefik-net` network. |
| `--docker` | enable docker backend, and `--docker.swarmmode` to enable the swarm mode on Træfik. |
| `--web` | activate the webUI on port 8080 |
| `--api | activate the webUI on port 8080 |
## Deploy your apps

View File

@@ -86,14 +86,14 @@ docker $(docker-machine config mhs-demo0) run \
-c /dev/null \
--docker \
--docker.domain=traefik \
--docker.endpoint=tcp://$(docker-machine ip mhs-demo0):3376 \
--docker.endpoint=tcp://$(docker-machine ip mhs-demo0):2376 \
--docker.tls \
--docker.tls.ca=/ssl/ca.pem \
--docker.tls.cert=/ssl/server.pem \
--docker.tls.key=/ssl/server-key.pem \
--docker.tls.insecureSkipVerify \
--docker.watch \
--web
--api
```
Let's explain this command:
@@ -105,9 +105,9 @@ Let's explain this command:
| `-v /var/lib/boot2docker/:/ssl` | mount the ssl keys generated by docker-machine |
| `-c /dev/null` | empty config file |
| `--docker` | enable docker backend |
| `--docker.endpoint=tcp://172.18.0.1:3376` | connect to the swarm master using the docker_gwbridge network |
| `--docker.endpoint=tcp://172.18.0.1:2376` | connect to the swarm master using the docker_gwbridge network |
| `--docker.tls` | enable TLS using the docker-machine keys |
| `--web` | activate the webUI on port 8080 |
| `--api` | activate the webUI on port 8080 |
## Deploy your apps

View File

@@ -19,6 +19,8 @@ entryPoint = "https"
onDemand = false
OnHostRule = true
caServer = "http://traefik.localhost.com:4000/directory"
[acme.httpChallenge]
entryPoint="http"
[web]

View File

@@ -78,6 +78,7 @@ services :
- "80:80"
- "443:443"
- "5001:443" # Needed for SNI challenge
- "5002:80" # Needed for HTTP challenge
expose:
- "8080"
labels:

View File

@@ -38,16 +38,7 @@ services:
etcdctl-ping:
image: tenstartups/etcdctl
command: --endpoints=[10.0.1.12:2379] get "traefik/acme/storagefile"
environment:
ETCDCTL_DIAL_: "TIMEOUT 10s"
ETCDCTL_API : "3"
networks:
- net
etcdctl-rm:
image: tenstartups/etcdctl
command: --endpoints=[10.0.1.12:2379] del "/traefik/acme/storagefile"
command: --endpoints=[10.0.1.12:2379] get "traefik/acme/storage"
environment:
ETCDCTL_DIAL_: "TIMEOUT 10s"
ETCDCTL_API : "3"
@@ -129,7 +120,6 @@ services:
image: containous/traefik
volumes:
- "./traefik.toml:/traefik.toml:ro"
- "./acme.json:/acme.json:ro"
command: storeconfig --debug
networks:
- net
@@ -146,11 +136,13 @@ services:
expose:
- "443"
- "5001"
- "5002"
ports:
- "80:80"
- "8080:8080"
- "443:443"
- "5001:443" # Needed for SNI challenge
- "5002:80" # Needed for HTTP challenge
networks:
net:
ipv4_address: 10.0.1.8
@@ -167,6 +159,7 @@ services:
expose:
- "443"
- "5001"
- "5002"
ports:
- "88:80"
- "8888:8080"

View File

@@ -32,15 +32,6 @@ delete_services() {
return 0
}
# Init the environment : get IP address and create needed files
init_acme_json() {
echo "CREATE empty acme.json file"
rm -f $basedir/acme.json && \
touch $basedir/acme.json && \
echo "{}" > $basedir/acme.json && \
chmod 600 $basedir/acme.json # Needed for ACME
}
start_consul() {
up_environment consul
waiting_counter=12
@@ -76,7 +67,6 @@ start_etcd3() {
}
start_storeconfig_consul() {
init_acme_json
# Create traefik.toml with consul provider
cp $basedir/traefik.toml.tmpl $basedir/traefik.toml
echo '
@@ -85,29 +75,13 @@ start_storeconfig_consul() {
watch = true
prefix = "traefik"' >> $basedir/traefik.toml
up_environment traefik-storeconfig
rm -f $basedir/traefik.toml && rm -f $basedir/acme.json
# Delete acme-storage-file key
rm -f $basedir/traefik.toml
waiting_counter=5
# Not start Traefik store config if consul is not started
echo "Delete storage file key..."
while [[ -z $(curl -s http://10.0.1.2:8500/v1/kv/traefik/acme/storagefile) && $waiting_counter -gt 0 ]]; do
sleep 5
let waiting_counter-=1
done
if [[ $waiting_counter -eq 0 ]]; then
echo "[WARN] Unable to get storagefile key in consul"
else
curl -s --request DELETE http://10.0.1.2:8500/v1/kv/traefik/acme/storagefile
ret=$1
if [[ $ret -ne 0 ]]; then
echo "[ERROR] Unable to delete storagefile key from consul kv."
fi
fi
delete_services traefik-storeconfig
}
start_storeconfig_etcd3() {
init_acme_json
# Create traefik.toml with consul provider
cp $basedir/traefik.toml.tmpl $basedir/traefik.toml
echo '
@@ -117,20 +91,15 @@ start_storeconfig_etcd3() {
prefix = "/traefik"
useAPIV3 = true' >> $basedir/traefik.toml
up_environment traefik-storeconfig
rm -f $basedir/traefik.toml && rm -f $basedir/acme.json
# Delete acme-storage-file key
rm -f $basedir/traefik.toml
waiting_counter=5
# Not start Traefik store config if consul is not started
# Don't start Traefik store config if ETCD3 is not started
echo "Delete storage file key..."
while [[ $(docker-compose -f $doc_file up --exit-code-from etcdctl-ping etcdctl-ping &>/dev/null) -ne 0 && $waiting_counter -gt 0 ]]; do
sleep 5
let waiting_counter-=1
done
# Not start Traefik store config if consul is not started
echo "Delete storage file key from ETCD3..."
up_environment etcdctl-rm && \
delete_services etcdctl-rm traefik-storeconfig etcdctl-ping
delete_services traefik-storeconfig etcdctl-ping
}
start_traefik() {

View File

@@ -12,10 +12,11 @@ defaultEntryPoints = ["http", "https"]
[acme]
email = "test@traefik.io"
storage = "traefik/acme/account"
storageFile = "/acme.json"
entryPoint = "https"
OnHostRule = true
caServer = "http://traefik.boulder.com:4000/directory"
[acme.httpChallenge]
entryPoint="http"
[web]

View File

@@ -26,11 +26,11 @@ curl -i -H "Accept: application/json" -X PUT -d "Path:/test" ht
# certificate 1
curl -i -H "Accept: application/json" -X PUT -d "https" http://localhost:8500/v1/kv/traefik/tlsconfiguration/pair1/entrypoints
curl -i -H "Accept: application/json" -X PUT -d "/tmp/test1.crt" http://localhost:8500/v1/kv/traefik/tlsconfiguration/pair1/certificate/certfile
curl -i -H "Accept: application/json" -X PUT -d "/tmp/test1.key" http://localhost:8500/v1/kv/traefik/tlsconfiguration/pair1/certificate/keyfile
curl -i -H "Accept: application/json" -X PUT -d "https" http://localhost:8500/v1/kv/traefik/tls/pair1/entrypoints
curl -i -H "Accept: application/json" -X PUT -d "/tmp/test1.crt" http://localhost:8500/v1/kv/traefik/tls/pair1/certificate/certfile
curl -i -H "Accept: application/json" -X PUT -d "/tmp/test1.key" http://localhost:8500/v1/kv/traefik/tls/pair1/certificate/keyfile
# certificate 2
curl -i -H "Accept: application/json" -X PUT -d "http,https" http://localhost:8500/v1/kv/traefik/tlsconfiguration/pair2/entrypoints
curl -i -H "Accept: application/json" -X PUT -d "/tmp/test2.crt" http://localhost:8500/v1/kv/traefik/tlsconfiguration/pair2/certificate/certfile
curl -i -H "Accept: application/json" -X PUT -d "/tmp/test2.key" http://localhost:8500/v1/kv/traefik/tlsconfiguration/pair2/certificate/keyfile
curl -i -H "Accept: application/json" -X PUT -d "http,https" http://localhost:8500/v1/kv/traefik/tls/pair2/entrypoints
curl -i -H "Accept: application/json" -X PUT -d "/tmp/test2.crt" http://localhost:8500/v1/kv/traefik/tls/pair2/certificate/certfile
curl -i -H "Accept: application/json" -X PUT -d "/tmp/test2.key" http://localhost:8500/v1/kv/traefik/tls/pair2/certificate/keyfile

View File

@@ -28,14 +28,14 @@ function insert_etcd2_data() {
curl -i -H "Accept: application/json" -X PUT -d value="Path:/test" http://localhost:2379/v2/keys/traefik/frontends/frontend2/routes/test_2/rule
# certificate 1
curl -i -H "Accept: application/json" -X PUT -d value="https" http://localhost:2379/v2/keys/traefik/tlsconfiguration/pair1/entrypoints
curl -i -H "Accept: application/json" -X PUT -d value="/tmp/test1.crt" http://localhost:2379/v2/keys/traefik/tlsconfiguration/pair1/certificate/certfile
curl -i -H "Accept: application/json" -X PUT -d value="/tmp/test1.key" http://localhost:2379/v2/keys/traefik/tlsconfiguration/pair1/certificate/keyfile
curl -i -H "Accept: application/json" -X PUT -d value="https" http://localhost:2379/v2/keys/traefik/tls/pair1/entrypoints
curl -i -H "Accept: application/json" -X PUT -d value="/tmp/test1.crt" http://localhost:2379/v2/keys/traefik/tls/pair1/certificate/certfile
curl -i -H "Accept: application/json" -X PUT -d value="/tmp/test1.key" http://localhost:2379/v2/keys/traefik/tls/pair1/certificate/keyfile
# certificate 2
curl -i -H "Accept: application/json" -X PUT -d value="http,https" http://localhost:2379/v2/keys/traefik/tlsconfiguration/pair2/entrypoints
curl -i -H "Accept: application/json" -X PUT -d value="/tmp/test2.crt" http://localhost:2379/v2/keys/traefik/tlsconfiguration/pair2/certificate/certfile
curl -i -H "Accept: application/json" -X PUT -d value="/tmp/test2.key" http://localhost:2379/v2/keys/traefik/tlsconfiguration/pair2/certificate/keyfile
curl -i -H "Accept: application/json" -X PUT -d value="http,https" http://localhost:2379/v2/keys/traefik/tls/pair2/entrypoints
curl -i -H "Accept: application/json" -X PUT -d value="/tmp/test2.crt" http://localhost:2379/v2/keys/traefik/tls/pair2/certificate/certfile
curl -i -H "Accept: application/json" -X PUT -d value="/tmp/test2.key" http://localhost:2379/v2/keys/traefik/tls/pair2/certificate/keyfile
}
#
@@ -71,14 +71,14 @@ function insert_etcd3_data() {
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/frontends/frontend2/routes/test_2/rule" "Path:/test"
# certificate 1
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tlsconfiguration/pair1/entrypoints" "https"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tlsconfiguration/pair1/certificate/certfile" "/tmp/test1.crt"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tlsconfiguration/pair1/certificate/keyfile" "/tmp/test1.key"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tls/pair1/entrypoints" "https"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tls/pair1/certificate/certfile" "/tmp/test1.crt"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tls/pair1/certificate/keyfile" "/tmp/test1.key"
# certificate 2
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tlsconfiguration/pair2/entrypoints" "https"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tlsconfiguration/pair2/certificate/certfile" "/tmp/test2.crt"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tlsconfiguration/pair2/certificate/keyfile" "/tmp/test2.key"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tls/pair2/entrypoints" "https"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tls/pair2/certificate/certfile" "/tmp/test2.crt"
docker container run --rm -ti -e ETCDCTL_DIAL_="TIMEOUT 10s" -e ETCDCTL_API="3" tenstartups/etcdctl --endpoints=[$etcd_ip:2379] put "/traefik/tls/pair2/certificate/keyfile" "/tmp/test2.key"
}
function show_usage() {

View File

@@ -2,7 +2,7 @@
//go:generate rm -vf autogen/genstatic/gen.go
//go:generate mkdir -p static
//go:generate go-bindata -pkg gentemplates -nometadata -nocompress -o autogen/gentemplates/gen.go ./templates/...
//go:generate gofmt -w autogen/gentemplates/gen.go
//go:generate gofmt -s -w autogen/gentemplates/gen.go
//go:generate go-bindata -pkg genstatic -nocompress -o autogen/genstatic/gen.go ./static/...
package main

859
glide.lock generated
View File

@@ -1,859 +0,0 @@
hash: 03f8c75c2523eaea36cd61abc4d335ce68115c80404de7a10d8d4f0225957fc9
updated: 2017-11-28T15:59:09.002650953+01:00
imports:
- name: cloud.google.com/go
version: 2e6a95edb1071d750f6d7db777bf66cd2997af6c
subpackages:
- compute/metadata
- internal
- name: github.com/abbot/go-http-auth
version: 0ddd408d5d60ea76e320503cc7dd091992dee608
- name: github.com/aokoli/goutils
version: 3391d3790d23d03408670993e957e8f408993c34
- name: github.com/armon/go-proxyproto
version: 48572f11356f1843b694f21a290d4f1006bc5e47
- name: github.com/ArthurHlt/go-eureka-client
version: 9d0a49cbd39aa3634ae1977e9f519a262b10adaf
subpackages:
- eureka
- name: github.com/ArthurHlt/gominlog
version: 72eebf980f467d3ab3a8b4ddf660f664911ce519
- name: github.com/aws/aws-sdk-go
version: 3f8f870ec9939e32b3372abf74d24e468bcd285d
subpackages:
- aws
- aws/awserr
- aws/awsutil
- aws/client
- aws/client/metadata
- aws/corehandlers
- aws/credentials
- aws/credentials/ec2rolecreds
- aws/credentials/endpointcreds
- aws/credentials/stscreds
- aws/defaults
- aws/ec2metadata
- aws/endpoints
- aws/request
- aws/session
- aws/signer/v4
- private/protocol
- private/protocol/ec2query
- private/protocol/json/jsonutil
- private/protocol/jsonrpc
- private/protocol/query
- private/protocol/query/queryutil
- private/protocol/rest
- private/protocol/restxml
- private/protocol/xml/xmlutil
- private/waiter
- service/dynamodb
- service/dynamodb/dynamodbattribute
- service/dynamodb/dynamodbiface
- service/dynamodbattribute
- service/ec2
- service/ecs
- service/route53
- service/sts
- name: github.com/Azure/azure-sdk-for-go
version: f7bb4db3ea4c73dc58bd284c38ea644a79324be0
subpackages:
- arm/dns
- name: github.com/Azure/go-autorest
version: f6be1abbb5abd0517522f850dd785990d373da7e
subpackages:
- autorest
- autorest/adal
- autorest/azure
- autorest/date
- autorest/to
- name: github.com/beorn7/perks
version: 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
subpackages:
- quantile
- name: github.com/blang/semver
version: 31b736133b98f26d5e078ec9eb591666edfd091f
- name: github.com/boltdb/bolt
version: e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
- name: github.com/BurntSushi/toml
version: b26d9c308763d68093482582cea63d69be07a0f0
- name: github.com/BurntSushi/ty
version: 6add9cd6ad42d389d6ead1dde60b4ad71e46fd74
subpackages:
- fun
- name: github.com/cenk/backoff
version: 5d150e7eec023ce7a124856b37c68e54b4050ac7
- name: github.com/codahale/hdrhistogram
version: 9208b142303c12d8899bae836fd524ac9338b4fd
- name: github.com/codegangsta/cli
version: bf4a526f48af7badd25d2cb02d587e1b01be3b50
- name: github.com/containous/flaeg
version: b5d2dc5878df07c2d74413348186982e7b865871
- name: github.com/containous/mux
version: 06ccd3e75091eb659b1d720cda0e16bc7057954c
- name: github.com/containous/staert
version: af517d5b70db9c4b0505e0144fcc62b054057d2a
- name: github.com/containous/traefik-extra-service-fabric
version: 8076098dbfe814cba9e895ecbd896f1896b6b2d5
- name: github.com/coreos/bbolt
version: 3c6cbfb299c11444eb2f8c9d48f0d2ce09157423
- name: github.com/coreos/etcd
version: f1d7dd87da3e8feab4aaf675b8e29c6a5ed5f58b
subpackages:
- auth/authpb
- client
- clientv3
- clientv3/concurrency
- etcdserver/api/v3rpc/rpctypes
- etcdserver/etcdserverpb
- mvcc/mvccpb
- pkg/pathutil
- pkg/srv
- pkg/types
- version
- name: github.com/coreos/go-semver
version: 8ab6407b697782a06568d4b7f1db25550ec2e4c6
subpackages:
- semver
- name: github.com/coreos/go-oidc
version: 5644a2f50e2d2d5ba0b474bc5bc55fea1925936d
subpackages:
- http
- jose
- key
- oauth2
- oidc
- name: github.com/coreos/go-systemd
version: 48702e0da86bd25e76cfef347e2adeb434a0d0a6
subpackages:
- daemon
- name: github.com/coreos/pkg
version: fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8
subpackages:
- health
- httputil
- timeutil
- name: github.com/davecgh/go-spew
version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9
subpackages:
- spew
- name: github.com/decker502/dnspod-go
version: f33a2c6040fc2550a631de7b3a53bddccdcd73fb
- name: github.com/dgrijalva/jwt-go
version: d2709f9f1f31ebcda9651b03077758c1f3a0018c
- name: github.com/dnsimple/dnsimple-go
version: f2d9b723cc9547d182e24ac2e527ae25d25fc93f
subpackages:
- dnsimple
- name: github.com/docker/distribution
version: b38e5838b7b2f2ad48e06ec4b500011976080621
subpackages:
- context
- digestset
- reference
- registry/api/errcode
- registry/api/v2
- registry/client
- registry/client/auth
- registry/client/auth/challenge
- registry/client/transport
- registry/storage/cache
- registry/storage/cache/memory
- uuid
- name: github.com/docker/docker
version: 75c7536d2e2e328b644bf69153de879d1d197988
subpackages:
- api
- api/types
- api/types/blkiodev
- api/types/container
- api/types/events
- api/types/filters
- api/types/image
- api/types/mount
- api/types/network
- api/types/registry
- api/types/strslice
- api/types/swarm
- api/types/time
- api/types/versions
- api/types/volume
- builder/dockerignore
- client
- opts
- pkg/archive
- pkg/fileutils
- pkg/gitutils
- pkg/homedir
- pkg/httputils
- pkg/idtools
- pkg/ioutils
- pkg/jsonlog
- pkg/jsonmessage
- pkg/longpath
- pkg/mount
- pkg/namesgenerator
- pkg/pools
- pkg/progress
- pkg/promise
- pkg/random
- pkg/stdcopy
- pkg/streamformatter
- pkg/stringid
- pkg/symlink
- pkg/system
- pkg/tarsum
- pkg/term
- pkg/term/windows
- pkg/tlsconfig
- pkg/urlutil
- registry
- runconfig/opts
- name: github.com/docker/go-connections
version: e15c02316c12de00874640cd76311849de2aeed5
subpackages:
- nat
- sockets
- tlsconfig
- name: github.com/docker/go-units
version: 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
- name: github.com/docker/leadership
version: af20da7d3e62be9259835e93261acf931b5adecf
repo: https://github.com/containous/leadership.git
vcs: git
- name: github.com/docker/libkv
version: 5e4bb288a9a74320bb03f5c18d6bdbab0d8049de
repo: https://github.com/abronan/libkv.git
vcs: git
subpackages:
- store
- store/boltdb
- store/consul
- store/etcd
- store/etcd/v2
- store/etcd/v3
- store/zookeeper
- name: github.com/docker/libtrust
version: 9cbd2a1374f46905c68a4eb3694a130610adc62a
- name: github.com/donovanhide/eventsource
version: b8f31a59085e69dd2678cf51840db2ac625cb741
- name: github.com/eapache/channels
version: 47238d5aae8c0fefd518ef2bee46290909cf8263
- name: github.com/eapache/queue
version: 44cc805cf13205b55f69e14bcb69867d1ae92f98
- name: github.com/edeckers/auroradnsclient
version: 398f53855ba258191157e20fabfaccca5e13cea9
subpackages:
- records
- requests
- requests/errors
- tokens
- zones
- name: github.com/elazarl/go-bindata-assetfs
version: 30f82fa23fd844bd5bb1e5f216db87fd77b5eb43
- name: github.com/emicklei/go-restful
version: 89ef8af493ab468a45a42bb0d89a06fccdd2fb22
subpackages:
- log
- swagger
- name: github.com/exoscale/egoscale
version: 325740036187ddae3a5b74be00fbbc70011c4d96
- name: github.com/fatih/color
version: 62e9147c64a1ed519147b62a56a14e83e2be02c1
- name: github.com/gambol99/go-marathon
version: dd6cbd4c2d71294a19fb89158f2a00d427f174ab
- name: github.com/ghodss/yaml
version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee
- name: github.com/go-ini/ini
version: f384f410798cbe7cdce40eec40b79ed32bb4f1ad
- name: github.com/go-kit/kit
version: f66b0e13579bfc5a48b9e2a94b1209c107ea1f41
subpackages:
- log
- metrics
- metrics/dogstatsd
- metrics/generic
- metrics/influx
- metrics/internal/lv
- metrics/internal/ratemap
- metrics/multi
- metrics/prometheus
- metrics/statsd
- util/conn
- name: github.com/go-logfmt/logfmt
version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5
- name: github.com/go-openapi/jsonpointer
version: 46af16f9f7b149af66e5d1bd010e3574dc06de98
- name: github.com/go-openapi/jsonreference
version: 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272
- name: github.com/go-openapi/spec
version: 6aced65f8501fe1217321abf0749d354824ba2ff
- name: github.com/go-openapi/swag
version: 1d0bd113de87027671077d3c71eb3ac5d7dbba72
- name: github.com/go-stack/stack
version: 54be5f394ed2c3e19dac9134a40a95ba5a017f7b
- name: github.com/gogo/protobuf
version: 909568be09de550ed094403c2bf8a261b5bb730a
subpackages:
- proto
- sortkeys
- name: github.com/golang/glog
version: 44145f04b68cf362d9c4df2182967c2275eaefed
- name: github.com/golang/protobuf
version: 4bd1920723d7b7c925de087aa32e2187708897f7
subpackages:
- jsonpb
- proto
- ptypes/any
- name: github.com/google/go-github
version: fe7d11f8add400587b6718d9f39a62e42cb04c28
subpackages:
- github
- name: github.com/google/go-querystring
version: 53e6ce116135b80d037921a7fdd5138cf32d7a8a
subpackages:
- query
- name: github.com/google/gofuzz
version: bbcb9da2d746f8bdbd6a936686a0a6067ada0ec5
- name: github.com/googleapis/gax-go
version: 9af46dd5a1713e8b5cd71106287eba3cefdde50b
- name: github.com/gorilla/context
version: 215affda49addc4c8ef7e2534915df2c8c35c6cd
- name: github.com/gorilla/websocket
version: a69d9f6de432e2c6b296a947d8a5ee88f68522cf
- name: github.com/hashicorp/consul
version: 3f92cc70e8163df866873c16c6d89889b5c95fc4
subpackages:
- api
- name: github.com/hashicorp/go-cleanhttp
version: 3573b8b52aa7b37b9358d966a898feb387f62437
- name: github.com/hashicorp/go-version
version: 03c5bf6be031b6dd45afec16b1cf94fc8938bc77
- name: github.com/hashicorp/serf
version: 19f2c401e122352c047a84d6584dd51e2fb8fcc4
subpackages:
- coordinate
- name: github.com/huandu/xstrings
version: 3959339b333561bf62a38b424fd41517c2c90f40
- name: github.com/imdario/mergo
version: 7fe0c75c13abdee74b09fcacef5ea1c6bba6a874
- name: github.com/influxdata/influxdb
version: 2d474a3089bcfce6b472779be9470a1f0ef3d5e4
subpackages:
- client/v2
- models
- pkg/escape
- name: github.com/JamesClonk/vultr
version: 2fd0705ce648e602e6c9c57329a174270a4f6688
subpackages:
- lib
- name: github.com/jjcollinge/servicefabric
version: 93a44e59fc887cda489913c6fc5bda834989f3bd
- name: github.com/jmespath/go-jmespath
version: bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d
- name: github.com/jonboulle/clockwork
version: 72f9bd7c4e0c2a40055ab3d0f09654f730cce982
- name: github.com/juju/ratelimit
version: 77ed1c8a01217656d2080ad51981f6e99adaa177
- name: github.com/kr/logfmt
version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
- name: github.com/mailgun/minheap
version: 7c28d80e2ada649fc8ab1a37b86d30a2633bd47c
- name: github.com/mailgun/timetools
version: 7e6055773c5137efbeb3bd2410d705fe10ab6bfd
- name: github.com/mailgun/ttlmap
version: c1c17f74874f2a5ea48bfb06b5459d4ef2689749
- name: github.com/mailru/easyjson
version: d5b7844b561a7bc640052f1b935f7b800330d7e0
subpackages:
- buffer
- jlexer
- jwriter
- name: github.com/Masterminds/semver
version: 59c29afe1a994eacb71c833025ca7acf874bb1da
- name: github.com/Masterminds/sprig
version: e039e20e500c2c025d9145be375e27cf42a94174
- name: github.com/mattn/go-colorable
version: 5411d3eea5978e6cdc258b30de592b60df6aba96
repo: https://github.com/mattn/go-colorable
- name: github.com/mattn/go-isatty
version: 57fdcb988a5c543893cc61bce354a6e24ab70022
repo: https://github.com/mattn/go-isatty
- name: github.com/mattn/go-shellwords
version: 02e3cf038dcea8290e44424da473dd12be796a8a
- name: github.com/matttproud/golang_protobuf_extensions
version: c12348ce28de40eed0136aa2b644d0ee0650e56c
subpackages:
- pbutil
- name: github.com/mesos/mesos-go
version: 068d5470506e3780189fe607af40892814197c5e
subpackages:
- detector
- detector/zoo
- mesos
- mesosproto
- mesosutil
- upid
- name: github.com/mesosphere/mesos-dns
version: b47dc4c19f215e98da687b15b4c64e70f629bea5
repo: https://github.com/containous/mesos-dns.git
vcs: git
subpackages:
- detect
- errorutil
- logging
- models
- records
- records/labels
- records/state
- util
- name: github.com/Microsoft/go-winio
version: f533f7a102197536779ea3a8cb881d639e21ec5a
- name: github.com/miekg/dns
version: 8060d9f51305bbe024b99679454e62f552cd0b0b
- name: github.com/mitchellh/copystructure
version: d23ffcb85de31694d6ccaa23ccb4a03e55c1303f
- name: github.com/mitchellh/hashstructure
version: 2bca23e0e452137f789efbc8610126fd8b94f73b
- name: github.com/mitchellh/mapstructure
version: d0303fe809921458f417bcf828397a65db30a7e4
- name: github.com/mitchellh/reflectwalk
version: 63d60e9d0dbc60cf9164e6510889b0db6683d98c
- name: github.com/mvdan/xurls
version: db96455566f05ffe42bd6ac671f05eeb1152b45d
- name: github.com/Nvveen/Gotty
version: 6018b68f96b839edfbe3fb48668853f5dbad88a3
repo: https://github.com/ijc25/Gotty.git
vcs: git
- name: github.com/NYTimes/gziphandler
version: d6f46609c7629af3a02d791a4666866eed3cbd3e
- name: github.com/ogier/pflag
version: 45c278ab3607870051a2ea9040bb85fcb8557481
- name: github.com/opencontainers/go-digest
version: a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb
- name: github.com/opencontainers/image-spec
version: f03dbe35d449c54915d235f1a3cf8f585a24babe
subpackages:
- specs-go
- specs-go/v1
- name: github.com/ovh/go-ovh
version: 4b1fea467323b74c5f462f0947f402b428ca0626
subpackages:
- ovh
- name: github.com/pborman/uuid
version: ca53cad383cad2479bbba7f7a1a05797ec1386e4
- name: github.com/pkg/errors
version: c605e284fe17294bda444b34710735b29d1a9d90
- name: github.com/pmezard/go-difflib
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
subpackages:
- difflib
- name: github.com/prometheus/client_golang
version: 08fd2e12372a66e68e30523c7642e0cbc3e4fbde
subpackages:
- prometheus
- prometheus/promhttp
- name: github.com/prometheus/client_model
version: 6f3806018612930941127f2a7c6c453ba2c527d2
subpackages:
- go
- name: github.com/prometheus/common
version: 49fee292b27bfff7f354ee0f64e1bc4850462edf
subpackages:
- expfmt
- internal/bitbucket.org/ww/goautoneg
- model
- name: github.com/prometheus/procfs
version: a1dba9ce8baed984a2495b658c82687f8157b98f
subpackages:
- xfs
- name: github.com/PuerkitoBio/purell
version: 8a290539e2e8629dbc4e6bad948158f790ec31f4
- name: github.com/PuerkitoBio/urlesc
version: 5bd2802263f21d8788851d5305584c82a5c75d7e
- name: github.com/rancher/go-rancher
version: 52e2f489534007ae843065468c5a1920d542afa4
subpackages:
- v2
- name: github.com/rancher/go-rancher-metadata
version: d2103caca5873119ff423d29cba09b4d03cd69b8
subpackages:
- metadata
- name: github.com/ryanuber/go-glob
version: 256dc444b735e061061cf46c809487313d5b0065
- name: github.com/samuel/go-zookeeper
version: 1d7be4effb13d2d908342d349d71a284a7542693
subpackages:
- zk
- name: github.com/satori/go.uuid
version: 879c5887cd475cd7864858769793b2ceb0d44feb
- name: github.com/Sirupsen/logrus
version: 10f801ebc38b33738c9d17d50860f484a0988ff5
- name: github.com/spf13/pflag
version: cb88ea77998c3f024757528e3305022ab50b43be
- name: github.com/stretchr/objx
version: cbeaeb16a013161a98496fad62933b1d21786672
- name: github.com/stretchr/testify
version: 4d4bfba8f1d1027c4fdbe371823030df51419987
subpackages:
- assert
- mock
- require
- name: github.com/thoas/stats
version: 152b5d051953fdb6e45f14b6826962aadc032324
- name: github.com/timewasted/linode
version: 37e84520dcf74488f67654f9c775b9752c232dc1
subpackages:
- dns
- name: github.com/tv42/zbase32
version: 03389da7e0bf9844767f82690f4d68fc097a1306
- name: github.com/ugorji/go
version: ea9cd21fa0bc41ee4bdd50ac7ed8cbc7ea2ed960
subpackages:
- codec
- name: github.com/unrolled/render
version: 50716a0a853771bb36bfce61a45cdefdb98c2e6e
- name: github.com/unrolled/secure
version: 824e85271811af89640ea25620c67f6c2eed987e
- name: github.com/urfave/negroni
version: 490e6a555d47ca891a89a150d0c1ef3922dfffe9
- name: github.com/VividCortex/gohistogram
version: 51564d9861991fb0ad0f531c99ef602d0f9866e6
- name: github.com/vulcand/oxy
version: 7b6e758ab449705195df638765c4ca472248908a
repo: https://github.com/containous/oxy.git
vcs: git
subpackages:
- cbreaker
- connlimit
- forward
- memmetrics
- ratelimit
- roundrobin
- stream
- utils
- name: github.com/vulcand/predicate
version: 19b9dde14240d94c804ae5736ad0e1de10bf8fe6
- name: github.com/vulcand/route
version: cb89d787ddbb1c5849a7ac9f79004c1fd12a4a32
- name: github.com/vulcand/vulcand
version: 42492a3a85e294bdbdd1bcabb8c12769a81ea284
subpackages:
- conntracker
- plugin
- plugin/rewrite
- router
- name: github.com/xenolf/lego
version: 67c86d860a797ce2483f50d9174d4ed24984bef2
subpackages:
- acme
- providers/dns
- providers/dns/auroradns
- providers/dns/azure
- providers/dns/cloudflare
- providers/dns/digitalocean
- providers/dns/dnsimple
- providers/dns/dnsmadeeasy
- providers/dns/dnspod
- providers/dns/dyn
- providers/dns/exoscale
- providers/dns/gandi
- providers/dns/googlecloud
- providers/dns/linode
- providers/dns/namecheap
- providers/dns/ns1
- providers/dns/otc
- providers/dns/ovh
- providers/dns/pdns
- providers/dns/rackspace
- providers/dns/rfc2136
- providers/dns/route53
- providers/dns/vultr
- name: golang.org/x/crypto
version: 4ed45ec682102c643324fae5dff8dab085b6c300
subpackages:
- bcrypt
- blowfish
- ocsp
- pbkdf2
- scrypt
- name: golang.org/x/net
version: c8c74377599bd978aee1cf3b9b63a8634051cec2
subpackages:
- context
- context/ctxhttp
- http2
- http2/hpack
- idna
- internal/timeseries
- lex/httplex
- proxy
- publicsuffix
- trace
- websocket
- name: golang.org/x/oauth2
version: 7fdf09982454086d5570c7db3e11f360194830ca
subpackages:
- google
- internal
- jws
- jwt
- name: golang.org/x/sys
version: 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9
subpackages:
- unix
- windows
- name: golang.org/x/text
version: 4ee4af566555f5fbe026368b75596286a312663a
subpackages:
- cases
- internal
- internal/tag
- language
- runes
- secure/bidirule
- secure/precis
- transform
- unicode/bidi
- unicode/norm
- width
- name: golang.org/x/time
version: 8be79e1e0910c292df4e79c241bb7e8f7e725959
subpackages:
- rate
- name: google.golang.org/api
version: 1575df15c1bb8b18ad4d9bc5ca495cc85b0764fe
subpackages:
- dns/v1
- gensupport
- googleapi
- googleapi/internal/uritemplates
- name: google.golang.org/appengine
version: 4f7eeb5305a4ba1966344836ba4af9996b7b4e05
subpackages:
- internal
- internal/app_identity
- internal/base
- internal/datastore
- internal/log
- internal/modules
- internal/remote_api
- internal/urlfetch
- urlfetch
- name: google.golang.org/genproto
version: 09f6ed296fc66555a25fe4ce95173148778dfa85
subpackages:
- googleapis/rpc/status
- name: google.golang.org/grpc
version: b8669c35455183da6d5c474ea6e72fbf55183274
subpackages:
- codes
- credentials
- grpclb/grpc_lb_v1
- grpclog
- internal
- keepalive
- metadata
- naming
- peer
- stats
- status
- tap
- transport
- name: gopkg.in/fsnotify.v1
version: 629574ca2a5df945712d3079857300b5e4da0236
- name: gopkg.in/inf.v0
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
- name: gopkg.in/ini.v1
version: 5b3e00af70a9484542169a976dcab8d03e601a17
- name: gopkg.in/ns1/ns1-go.v2
version: c563826f4cbef9c11bebeb9f20a3f7afe9c1e2f4
subpackages:
- rest
- rest/model/account
- rest/model/data
- rest/model/dns
- rest/model/filter
- rest/model/monitor
- name: gopkg.in/square/go-jose.v1
version: aa2e30fdd1fe9dd3394119af66451ae790d50e0d
subpackages:
- cipher
- json
- name: gopkg.in/yaml.v2
version: 53feefa2559fb8dfa8d81baad31be332c97d6c77
- name: k8s.io/client-go
version: e121606b0d09b2e1c467183ee46217fa85a6b672
subpackages:
- discovery
- kubernetes
- kubernetes/typed/apps/v1beta1
- kubernetes/typed/authentication/v1beta1
- kubernetes/typed/authorization/v1beta1
- kubernetes/typed/autoscaling/v1
- kubernetes/typed/batch/v1
- kubernetes/typed/batch/v2alpha1
- kubernetes/typed/certificates/v1alpha1
- kubernetes/typed/core/v1
- kubernetes/typed/extensions/v1beta1
- kubernetes/typed/policy/v1beta1
- kubernetes/typed/rbac/v1alpha1
- kubernetes/typed/storage/v1beta1
- pkg/api
- pkg/api/errors
- pkg/api/install
- pkg/api/meta
- pkg/api/meta/metatypes
- pkg/api/resource
- pkg/api/unversioned
- pkg/api/v1
- pkg/api/validation/path
- pkg/apimachinery
- pkg/apimachinery/announced
- pkg/apimachinery/registered
- pkg/apis/apps
- pkg/apis/apps/install
- pkg/apis/apps/v1beta1
- pkg/apis/authentication
- pkg/apis/authentication/install
- pkg/apis/authentication/v1beta1
- pkg/apis/authorization
- pkg/apis/authorization/install
- pkg/apis/authorization/v1beta1
- pkg/apis/autoscaling
- pkg/apis/autoscaling/install
- pkg/apis/autoscaling/v1
- pkg/apis/batch
- pkg/apis/batch/install
- pkg/apis/batch/v1
- pkg/apis/batch/v2alpha1
- pkg/apis/certificates
- pkg/apis/certificates/install
- pkg/apis/certificates/v1alpha1
- pkg/apis/extensions
- pkg/apis/extensions/install
- pkg/apis/extensions/v1beta1
- pkg/apis/policy
- pkg/apis/policy/install
- pkg/apis/policy/v1beta1
- pkg/apis/rbac
- pkg/apis/rbac/install
- pkg/apis/rbac/v1alpha1
- pkg/apis/storage
- pkg/apis/storage/install
- pkg/apis/storage/v1beta1
- pkg/auth/user
- pkg/conversion
- pkg/conversion/queryparams
- pkg/fields
- pkg/genericapiserver/openapi/common
- pkg/labels
- pkg/runtime
- pkg/runtime/serializer
- pkg/runtime/serializer/json
- pkg/runtime/serializer/protobuf
- pkg/runtime/serializer/recognizer
- pkg/runtime/serializer/streaming
- pkg/runtime/serializer/versioning
- pkg/selection
- pkg/third_party/forked/golang/reflect
- pkg/third_party/forked/golang/template
- pkg/types
- pkg/util
- pkg/util/cert
- pkg/util/clock
- pkg/util/diff
- pkg/util/errors
- pkg/util/flowcontrol
- pkg/util/framer
- pkg/util/integer
- pkg/util/intstr
- pkg/util/json
- pkg/util/jsonpath
- pkg/util/labels
- pkg/util/net
- pkg/util/parsers
- pkg/util/rand
- pkg/util/runtime
- pkg/util/sets
- pkg/util/uuid
- pkg/util/validation
- pkg/util/validation/field
- pkg/util/wait
- pkg/util/yaml
- pkg/version
- pkg/watch
- pkg/watch/versioned
- plugin/pkg/client/auth
- plugin/pkg/client/auth/gcp
- plugin/pkg/client/auth/oidc
- rest
- tools/cache
- tools/clientcmd/api
- tools/metrics
- transport
testImports:
- name: github.com/Azure/go-ansiterm
version: d6e3b3328b783f23731bc4d058875b0371ff8109
subpackages:
- winterm
- name: github.com/docker/cli
version: d95fd2f38cfc23e077530c6181330727d561b6a0
subpackages:
- cli/command/image/build
- cli/config
- cli/config/configfile
- name: github.com/docker/libcompose
version: 1b708aac26a4fc6f9bff31728a8e3a252ef57dbd
subpackages:
- config
- docker
- docker/auth
- docker/builder
- docker/client
- docker/container
- docker/ctx
- docker/image
- docker/network
- docker/service
- docker/volume
- labels
- logger
- lookup
- project
- project/events
- project/options
- utils
- version
- yaml
- name: github.com/flynn/go-shlex
version: 3f9db97f856818214da2e1057f8ad84803971cff
- name: github.com/go-check/check
version: ca0bf163426aa183d03fd4949101785c0347f273
repo: https://github.com/containous/check.git
vcs: git
- name: github.com/gorilla/mux
version: e444e69cbd2e2e3e0749a2f3c717cec491552bbf
- name: github.com/libkermit/compose
version: 4a33a16f1446ba205c4da7b09105d5bdc293b432
subpackages:
- check
- name: github.com/libkermit/docker
version: ddede409294e8c5ae66d68ac09edb6b27e8f3e4a
- name: github.com/libkermit/docker-check
version: e0695005d6819191cf8969b479c94c40c8d22aa4
- name: github.com/opencontainers/runc
version: b6b70e53451794e8333e9b602cc096b47a20bd0f
subpackages:
- libcontainer/system
- libcontainer/user
- name: github.com/stvp/go-udp-testing
version: c4434f09ec131ecf30f986d5dcb1636508bfa49a
- name: github.com/vdemeester/shakers
version: 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
- name: github.com/xeipuuv/gojsonpointer
version: 6fe8760cad3569743d51ddbb243b26f8456742dc
- name: github.com/xeipuuv/gojsonreference
version: e02fc20de94c78484cd5ffb007f8af96be030a45
- name: github.com/xeipuuv/gojsonschema
version: 0c8571ac0ce161a5feb57375a9cdf148c98c0f70

View File

@@ -1,240 +0,0 @@
package: github.com/containous/traefik
ignore:
- github.com/sirupsen/logrus
import:
- package: github.com/BurntSushi/toml
version: v0.3.0
- package: github.com/BurntSushi/ty
subpackages:
- fun
- package: github.com/Sirupsen/logrus
version: 10f801ebc38b33738c9d17d50860f484a0988ff5
- package: github.com/cenk/backoff
- package: github.com/containous/flaeg
- package: github.com/containous/traefik-extra-service-fabric
version: ^v1.0.1
- package: github.com/vulcand/oxy
version: 7b6e758ab449705195df638765c4ca472248908a
repo: https://github.com/containous/oxy.git
vcs: git
subpackages:
- cbreaker
- connlimit
- forward
- roundrobin
- stream
- utils
- ratelimit
- package: github.com/urfave/negroni
version: 490e6a555d47ca891a89a150d0c1ef3922dfffe9
- package: github.com/containous/staert
version: ^v2.0.0
- package: github.com/docker/docker
version: 75c7536d2e2e328b644bf69153de879d1d197988
- package: github.com/docker/go-connections
version: e15c02316c12de00874640cd76311849de2aeed5
subpackages:
- sockets
- tlsconfig
- package: github.com/docker/go-units
version: 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
- package: github.com/coreos/etcd
version: v3.2.9
- package: github.com/docker/libkv
repo: https://github.com/abronan/libkv.git
vcs: git
subpackages:
- store
- store/boltdb
- store/consul
- store/etcd/v2
- store/etcd/v3
- store/zookeeper
- package: github.com/elazarl/go-bindata-assetfs
- package: github.com/containous/mux
- package: github.com/hashicorp/consul
subpackages:
- api
- package: github.com/thoas/stats
version: 152b5d051953fdb6e45f14b6826962aadc032324
- package: github.com/unrolled/render
- package: github.com/vulcand/vulcand
version: 42492a3a85e294bdbdd1bcabb8c12769a81ea284
subpackages:
- plugin/rewrite
- package: github.com/vulcand/predicate
version: 19b9dde14240d94c804ae5736ad0e1de10bf8fe6
- package: github.com/xenolf/lego
version: 67c86d860a797ce2483f50d9174d4ed24984bef2
subpackages:
- acme
- package: gopkg.in/fsnotify.v1
- package: github.com/mattn/go-shellwords
- package: github.com/ryanuber/go-glob
- package: github.com/mesos/mesos-go
subpackages:
- mesosproto
- mesos
- upid
- mesosutil
- detector
- package: github.com/miekg/dns
version: 8060d9f51305bbe024b99679454e62f552cd0b0b
- package: github.com/mesosphere/mesos-dns
version: b47dc4c19f215e98da687b15b4c64e70f629bea5
repo: https://github.com/containous/mesos-dns.git
vcs: git
- package: github.com/abbot/go-http-auth
- package: github.com/NYTimes/gziphandler
- package: github.com/docker/leadership
repo: https://github.com/containous/leadership.git
vcs: git
- package: github.com/satori/go.uuid
version: ^1.1.0
- package: k8s.io/client-go
version: v2.0.0
- package: github.com/influxdata/influxdb
version: v1.3.7
subpackages:
- client/v2
- package: github.com/gambol99/go-marathon
version: dd6cbd4c2d71294a19fb89158f2a00d427f174ab
- package: github.com/ArthurHlt/go-eureka-client
subpackages:
- eureka
- package: github.com/coreos/go-systemd
version: v14
subpackages:
- daemon
- package: github.com/google/go-github
- package: github.com/hashicorp/go-version
- package: github.com/mvdan/xurls
- package: github.com/go-kit/kit
version: v0.3.0
subpackages:
- log
- metrics
- metrics/dogstatsd
- metrics/internal/lv
- metrics/internal/ratemap
- metrics/multi
- metrics/prometheus
- metrics/statsd
- util/conn
- metrics/influx
- package: github.com/prometheus/client_golang
version: 08fd2e12372a66e68e30523c7642e0cbc3e4fbde
subpackages:
- prometheus
- package: github.com/prometheus/common
version: 49fee292b27bfff7f354ee0f64e1bc4850462edf
- package: github.com/prometheus/client_model
version: 6f3806018612930941127f2a7c6c453ba2c527d2
- package: github.com/prometheus/procfs
version: a1dba9ce8baed984a2495b658c82687f8157b98f
- package: github.com/matttproud/golang_protobuf_extensions
version: c12348ce28de40eed0136aa2b644d0ee0650e56c
- package: github.com/eapache/channels
version: v1.1.0
- package: golang.org/x/sys
version: 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9
- package: golang.org/x/net
version: 242b6b35177ec3909636b6cf6a47e8c2c6324b5d
subpackages:
- http2
- context
- websocket
- package: github.com/docker/distribution
version: b38e5838b7b2f2ad48e06ec4b500011976080621
- package: github.com/opencontainers/go-digest
version: a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb
- package: github.com/opencontainers/image-spec
version: f03dbe35d449c54915d235f1a3cf8f585a24babe
subpackages:
- specs-go
- specs-go/v1
- package: github.com/docker/libtrust
version: 9cbd2a1374f46905c68a4eb3694a130610adc62a
- package: github.com/aws/aws-sdk-go
version: v1.6.18
subpackages:
- aws
- aws/credentials
- aws/defaults
- aws/ec2metadata
- aws/endpoints
- aws/request
- aws/session
- service/dynamodb
- service/dynamodb/dynamodbiface
- service/dynamodbattribute
- service/ec2
- service/ecs
- package: cloud.google.com/go
version: v0.7.0
subpackages:
- compute/metadata
- package: github.com/gogo/protobuf
version: v0.3
subpackages:
- proto
- package: github.com/golang/protobuf
version: 2bba0603135d7d7f5cb73b2125beeda19c09f4ef
- package: github.com/rancher/go-rancher
version: 52e2f489534007ae843065468c5a1920d542afa4
- package: golang.org/x/oauth2
version: 7fdf09982454086d5570c7db3e11f360194830ca
subpackages:
- google
- package: golang.org/x/time
version: 8be79e1e0910c292df4e79c241bb7e8f7e725959
- package: github.com/rancher/go-rancher-metadata
version: d2103caca5873119ff423d29cba09b4d03cd69b8
- package: github.com/googleapis/gax-go
version: 9af46dd5a1713e8b5cd71106287eba3cefdde50b
- package: google.golang.org/grpc
version: v1.5.2
- package: github.com/unrolled/secure
version: 824e85271811af89640ea25620c67f6c2eed987e
- package: github.com/Nvveen/Gotty
version: 6018b68f96b839edfbe3fb48668853f5dbad88a3
repo: https://github.com/ijc25/Gotty.git
vcs: git
- package: github.com/spf13/pflag
version: cb88ea77998c3f024757528e3305022ab50b43be
- package: github.com/stretchr/testify
version: 4d4bfba8f1d1027c4fdbe371823030df51419987
subpackages:
- assert
- mock
- require
- package: github.com/davecgh/go-spew
version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9
subpackages:
- spew
- package: github.com/Masterminds/sprig
version: e039e20e500c2c025d9145be375e27cf42a94174
- package: github.com/armon/go-proxyproto
version: 48572f11356f1843b694f21a290d4f1006bc5e47
- package: github.com/mitchellh/copystructure
- package: github.com/mitchellh/hashstructure
testImport:
- package: github.com/stvp/go-udp-testing
- package: github.com/docker/libcompose
version: 1b708aac26a4fc6f9bff31728a8e3a252ef57dbd
- package: github.com/go-check/check
version: fork-containous
repo: https://github.com/containous/check.git
vcs: git
- package: github.com/libkermit/compose
version: 4a33a16f1446ba205c4da7b09105d5bdc293b432
subpackages:
- check
- package: github.com/libkermit/docker
version: ddede409294e8c5ae66d68ac09edb6b27e8f3e4a
- package: github.com/libkermit/docker-check
version: e0695005d6819191cf8969b479c94c40c8d22aa4
- package: github.com/mattn/go-shellwords
- package: github.com/vdemeester/shakers
- package: github.com/docker/cli
version: d95fd2f38cfc23e077530c6181330727d561b6a0

View File

@@ -48,6 +48,7 @@ type BackendHealthCheck struct {
//HealthCheck struct
type HealthCheck struct {
mutex sync.Mutex
Backends map[string]*BackendHealthCheck
cancel context.CancelFunc
}
@@ -75,14 +76,16 @@ func NewBackendHealthCheck(options Options) *BackendHealthCheck {
//SetBackendsConfiguration set backends configuration
func (hc *HealthCheck) SetBackendsConfiguration(parentCtx context.Context, backends map[string]*BackendHealthCheck) {
hc.mutex.Lock()
hc.Backends = backends
if hc.cancel != nil {
hc.cancel()
}
ctx, cancel := context.WithCancel(parentCtx)
hc.cancel = cancel
hc.mutex.Unlock()
for backendID, backend := range hc.Backends {
for backendID, backend := range backends {
currentBackendID := backendID
currentBackend := backend
safe.Go(func() {

View File

@@ -72,6 +72,36 @@ func (s *AcmeSuite) TestOnHostRuleRetrieveAcmeCertificate(c *check.C) {
s.retrieveAcmeCertificate(c, testCase)
}
// Test OnDemand option with none provided certificate and challenge HTTP-01
func (s *AcmeSuite) TestOnDemandRetrieveAcmeCertificateHTTP01(c *check.C) {
testCase := AcmeTestCase{
traefikConfFilePath: "fixtures/acme/acme_http01.toml",
onDemand: true,
domainToCheck: acmeDomain}
s.retrieveAcmeCertificate(c, testCase)
}
// Test OnHostRule option with none provided certificate and challenge HTTP-01
func (s *AcmeSuite) TestOnHostRuleRetrieveAcmeCertificateHTTP01(c *check.C) {
testCase := AcmeTestCase{
traefikConfFilePath: "fixtures/acme/acme_http01.toml",
onDemand: false,
domainToCheck: acmeDomain}
s.retrieveAcmeCertificate(c, testCase)
}
// Test OnHostRule option with none provided certificate and challenge HTTP-01 and web path
func (s *AcmeSuite) TestOnHostRuleRetrieveAcmeCertificateHTTP01WithPath(c *check.C) {
testCase := AcmeTestCase{
traefikConfFilePath: "fixtures/acme/acme_http01_web.toml",
onDemand: false,
domainToCheck: acmeDomain}
s.retrieveAcmeCertificate(c, testCase)
}
// Test OnDemand option with a wildcard provided certificate
func (s *AcmeSuite) TestOnDemandRetrieveAcmeCertificateWithWildcard(c *check.C) {
testCase := AcmeTestCase{

View File

@@ -189,6 +189,41 @@ func (s *SimpleSuite) TestApiOnSameEntryPoint(c *check.C) {
c.Assert(err, checker.IsNil)
}
func (s *SimpleSuite) TestStatsWithMultipleEntryPoint(c *check.C) {
s.createComposeProject(c, "stats")
s.composeProject.Start(c)
whoami1 := "http://" + s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress + ":80"
whoami2 := "http://" + s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress + ":80"
file := s.adaptFile(c, "fixtures/simple_stats.toml", struct {
Server1 string
Server2 string
}{whoami1, whoami2})
cmd, output := s.traefikCmd(withConfigFile(file))
defer output(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
err = try.GetRequest("http://127.0.0.1:8080/api", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1*time.Second, try.BodyContains("PathPrefix"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8080/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8080/health", 1*time.Second, try.BodyContains(`"total_status_code_count":{"200":2}`))
c.Assert(err, checker.IsNil)
}
func (s *SimpleSuite) TestNoAuthOnPing(c *check.C) {
s.createComposeProject(c, "base")
s.composeProject.Start(c)
@@ -263,3 +298,63 @@ func (s *SimpleSuite) TestWebCompatibilityWithPath(c *check.C) {
err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
}
func (s *SimpleSuite) TestDefaultEntrypointHTTP(c *check.C) {
s.createComposeProject(c, "base")
s.composeProject.Start(c)
cmd, output := s.traefikCmd("--entryPoints=Name:http Address::8000", "--debug", "--docker", "--api")
defer output(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1*time.Second, try.BodyContains("PathPrefix"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
}
func (s *SimpleSuite) TestWithUnexistingEntrypoint(c *check.C) {
s.createComposeProject(c, "base")
s.composeProject.Start(c)
cmd, output := s.traefikCmd("--defaultEntryPoints=https,http", "--entryPoints=Name:http Address::8000", "--debug", "--docker", "--api")
defer output(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1*time.Second, try.BodyContains("PathPrefix"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
}
func (s *SimpleSuite) TestMetricsPrometheusDefaultEntrypoint(c *check.C) {
s.createComposeProject(c, "base")
s.composeProject.Start(c)
cmd, output := s.traefikCmd("--defaultEntryPoints=http", "--entryPoints=Name:http Address::8000", "--web", "--web.metrics.prometheus.buckets=0.1,0.3,1.2,5.0", "--docker", "--debug")
defer output(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1*time.Second, try.BodyContains("PathPrefix"))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8080/metrics", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
}

View File

@@ -419,6 +419,46 @@ func (s *ConsulCatalogSuite) TestCircuitBreaker(c *check.C) {
c.Assert(err, checker.IsNil)
}
func (s *ConsulCatalogSuite) TestRefreshConfigPortChange(c *check.C) {
cmd, display := s.traefikCmd(
withConfigFile("fixtures/consul_catalog/simple.toml"),
"--consulCatalog",
"--consulCatalog.exposedByDefault=false",
"--consulCatalog.watch=true",
"--consulCatalog.endpoint="+s.consulIP+":8500",
"--consulCatalog.domain=consul.localhost")
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
nginx := s.composeProject.Container(c, "nginx1")
err = s.registerService("test", nginx.NetworkSettings.IPAddress, 81, []string{"name=nginx1", "traefik.enable=true"})
c.Assert(err, checker.IsNil, check.Commentf("Error registering service"))
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
c.Assert(err, checker.IsNil)
req.Host = "test.consul.localhost"
err = try.Request(req, 20*time.Second, try.StatusCodeIs(http.StatusBadGateway))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8080/api/providers/consul_catalog/backends", 5*time.Second, try.BodyContains("nginx1"))
c.Assert(err, checker.IsNil)
err = s.registerService("test", nginx.NetworkSettings.IPAddress, 80, []string{"name=nginx1", "traefik.enable=true"})
c.Assert(err, checker.IsNil, check.Commentf("Error registering service"))
defer s.deregisterService("test", nginx.NetworkSettings.IPAddress)
err = try.GetRequest("http://127.0.0.1:8080/api/providers/consul_catalog/backends", 60*time.Second, try.BodyContains("nginx1"))
c.Assert(err, checker.IsNil)
err = try.Request(req, 20*time.Second, try.StatusCodeIs(http.StatusOK), try.HasBody())
c.Assert(err, checker.IsNil)
}
func (s *ConsulCatalogSuite) TestRetryWithConsulServer(c *check.C) {
//Scale consul to 0 to be able to start traefik before and test retry
s.composeProject.Scale(c, "consul", 0)

View File

@@ -294,7 +294,10 @@ func (s *ConsulSuite) skipTestGlobalConfigurationWithClientTLS(c *check.C) {
s.setupConsulTLS(c)
consulHost := s.composeProject.Container(c, "consul").NetworkSettings.IPAddress
err := s.kv.Put("traefik/web/address", []byte(":8081"), nil)
err := s.kv.Put("traefik/api/entrypoint", []byte("api"), nil)
c.Assert(err, checker.IsNil)
err = s.kv.Put("traefik/entrypoints/api/address", []byte(":8081"), nil)
c.Assert(err, checker.IsNil)
// wait for consul
@@ -341,7 +344,7 @@ func (s *ConsulSuite) TestCommandStoreConfig(c *check.C) {
"/traefik/loglevel": "DEBUG",
"/traefik/defaultentrypoints/0": "http",
"/traefik/entrypoints/http/address": ":8000",
"/traefik/web/address": ":8080",
"/traefik/api/entrypoint": "traefik",
"/traefik/consul/endpoint": consulHost + ":8500",
}
@@ -561,15 +564,15 @@ func (s *ConsulSuite) TestSNIDynamicTlsConfig(c *check.C) {
}
tlsconfigure1 := map[string]string{
"traefik/tlsconfiguration/snitestcom/entrypoints": "https",
"traefik/tlsconfiguration/snitestcom/certificate/keyfile": string(snitestComKey),
"traefik/tlsconfiguration/snitestcom/certificate/certfile": string(snitestComCert),
"traefik/tls/snitestcom/entrypoints": "https",
"traefik/tls/snitestcom/certificate/keyfile": string(snitestComKey),
"traefik/tls/snitestcom/certificate/certfile": string(snitestComCert),
}
tlsconfigure2 := map[string]string{
"traefik/tlsconfiguration/snitestorg/entrypoints": "https",
"traefik/tlsconfiguration/snitestorg/certificate/keyfile": string(snitestOrgKey),
"traefik/tlsconfiguration/snitestorg/certificate/certfile": string(snitestOrgCert),
"traefik/tls/snitestorg/entrypoints": "https",
"traefik/tls/snitestorg/certificate/keyfile": string(snitestOrgKey),
"traefik/tls/snitestorg/certificate/certfile": string(snitestOrgCert),
}
// config backends,frontends and first tls keypair
@@ -610,7 +613,7 @@ func (s *ConsulSuite) TestSNIDynamicTlsConfig(c *check.C) {
// wait for consul
err = try.Do(60*time.Second, func() error {
_, err := s.kv.Get("traefik/tlsconfiguration/snitestcom/certificate/keyfile", nil)
_, err := s.kv.Get("traefik/tls/snitestcom/certificate/keyfile", nil)
return err
})
c.Assert(err, checker.IsNil)
@@ -639,7 +642,7 @@ func (s *ConsulSuite) TestSNIDynamicTlsConfig(c *check.C) {
// wait for consul
err = try.Do(60*time.Second, func() error {
_, err := s.kv.Get("traefik/tlsconfiguration/snitestorg/certificate/keyfile", nil)
_, err := s.kv.Get("traefik/tls/snitestorg/certificate/keyfile", nil)
return err
})
c.Assert(err, checker.IsNil)

View File

@@ -411,7 +411,7 @@ func (s *Etcd3Suite) TestCommandStoreConfig(c *check.C) {
"/traefik/loglevel": "DEBUG",
"/traefik/defaultentrypoints/0": "http",
"/traefik/entrypoints/http/address": ":8000",
"/traefik/web/address": ":8080",
"/traefik/api/entrypoint": "traefik",
"/traefik/etcd/endpoint": ipEtcd + ":4001",
}
@@ -474,15 +474,15 @@ func (s *Etcd3Suite) TestSNIDynamicTlsConfig(c *check.C) {
}
tlsconfigure1 := map[string]string{
"/traefik/tlsconfiguration/snitestcom/entrypoints": "https",
"/traefik/tlsconfiguration/snitestcom/certificate/keyfile": string(snitestComKey),
"/traefik/tlsconfiguration/snitestcom/certificate/certfile": string(snitestComCert),
"/traefik/tls/snitestcom/entrypoints": "https",
"/traefik/tls/snitestcom/certificate/keyfile": string(snitestComKey),
"/traefik/tls/snitestcom/certificate/certfile": string(snitestComCert),
}
tlsconfigure2 := map[string]string{
"/traefik/tlsconfiguration/snitestorg/entrypoints": "https",
"/traefik/tlsconfiguration/snitestorg/certificate/keyfile": string(snitestOrgKey),
"/traefik/tlsconfiguration/snitestorg/certificate/certfile": string(snitestOrgCert),
"/traefik/tls/snitestorg/entrypoints": "https",
"/traefik/tls/snitestorg/certificate/keyfile": string(snitestOrgKey),
"/traefik/tls/snitestorg/certificate/certfile": string(snitestOrgCert),
}
// config backends,frontends and first tls keypair
@@ -523,7 +523,7 @@ func (s *Etcd3Suite) TestSNIDynamicTlsConfig(c *check.C) {
// wait for etcd
err = try.Do(60*time.Second, func() error {
_, err := s.kv.Get("/traefik/tlsconfiguration/snitestcom/certificate/keyfile", nil)
_, err := s.kv.Get("/traefik/tls/snitestcom/certificate/keyfile", nil)
return err
})
c.Assert(err, checker.IsNil)
@@ -557,7 +557,7 @@ func (s *Etcd3Suite) TestSNIDynamicTlsConfig(c *check.C) {
// wait for etcd
err = try.Do(60*time.Second, func() error {
_, err := s.kv.Get("/traefik/tlsconfiguration/snitestorg/certificate/keyfile", nil)
_, err := s.kv.Get("/traefik/tls/snitestorg/certificate/keyfile", nil)
return err
})
c.Assert(err, checker.IsNil)
@@ -573,6 +573,113 @@ func (s *Etcd3Suite) TestSNIDynamicTlsConfig(c *check.C) {
req.Header.Set("Host", tr2.TLSClientConfig.ServerName)
req.Header.Set("Accept", "*/*")
resp, err = client.Do(req)
c.Assert(err, checker.IsNil)
cn = resp.TLS.PeerCertificates[0].Subject.CommonName
c.Assert(cn, checker.Equals, "snitest.org")
}
func (s *Etcd3Suite) TestDeleteSNIDynamicTlsConfig(c *check.C) {
// start Træfik
cmd, display := s.traefikCmd(
withConfigFile("fixtures/etcd/simple_https.toml"),
"--etcd",
"--etcd.endpoint="+ipEtcd+":4001",
"--etcd.useAPIV3=true")
defer display(c)
// prepare to config
snitestComCert, err := ioutil.ReadFile("fixtures/https/snitest.com.cert")
c.Assert(err, checker.IsNil)
snitestComKey, err := ioutil.ReadFile("fixtures/https/snitest.com.key")
c.Assert(err, checker.IsNil)
backend1 := map[string]string{
"/traefik/backends/backend1/circuitbreaker/expression": "NetworkErrorRatio() > 0.5",
"/traefik/backends/backend1/servers/server1/url": "http://" + ipWhoami01 + ":80",
"/traefik/backends/backend1/servers/server1/weight": "1",
"/traefik/backends/backend1/servers/server2/url": "http://" + ipWhoami02 + ":80",
"/traefik/backends/backend1/servers/server2/weight": "1",
}
frontend1 := map[string]string{
"/traefik/frontends/frontend1/backend": "backend1",
"/traefik/frontends/frontend1/entrypoints": "https",
"/traefik/frontends/frontend1/priority": "1",
"/traefik/frontends/frontend1/routes/test_1/rule": "Host:snitest.com",
}
tlsconfigure1 := map[string]string{
"/traefik/tls/snitestcom/entrypoints": "https",
"/traefik/tls/snitestcom/certificate/keyfile": string(snitestComKey),
"/traefik/tls/snitestcom/certificate/certfile": string(snitestComCert),
}
// config backends,frontends and first tls keypair
for key, value := range backend1 {
err := s.kv.Put(key, []byte(value), nil)
c.Assert(err, checker.IsNil)
}
for key, value := range frontend1 {
err := s.kv.Put(key, []byte(value), nil)
c.Assert(err, checker.IsNil)
}
for key, value := range tlsconfigure1 {
err := s.kv.Put(key, []byte(value), nil)
c.Assert(err, checker.IsNil)
}
tr1 := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
ServerName: "snitest.com",
},
}
// wait for etcd
err = try.Do(60*time.Second, func() error {
_, err := s.kv.Get("/traefik/tls/snitestcom/certificate/keyfile", nil)
return err
})
c.Assert(err, checker.IsNil)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
// wait for Træfik
err = try.GetRequest(traefikWebEtcdURL+"api/providers", 60*time.Second, try.BodyContains(string("MIIEpQIBAAKCAQEA1RducBK6EiFDv3TYB8ZcrfKWRVaSfHzWicO3J5WdST9oS7h")))
c.Assert(err, checker.IsNil)
req, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:4443/", nil)
c.Assert(err, checker.IsNil)
client := &http.Client{Transport: tr1}
req.Host = tr1.TLSClientConfig.ServerName
req.Header.Set("Host", tr1.TLSClientConfig.ServerName)
req.Header.Set("Accept", "*/*")
var resp *http.Response
resp, err = client.Do(req)
c.Assert(err, checker.IsNil)
cn := resp.TLS.PeerCertificates[0].Subject.CommonName
c.Assert(cn, checker.Equals, "snitest.com")
// now we delete the tls cert/key pairs,so the endpoint show use default cert/key pair
for key := range tlsconfigure1 {
err := s.kv.Delete(key)
c.Assert(err, checker.IsNil)
}
// waiting for Træfik to pull configuration
err = try.GetRequest(traefikWebEtcdURL+"api/providers", 30*time.Second, try.BodyNotContains("MIIEpQIBAAKCAQEA1RducBK6EiFDv3TYB8ZcrfKWRVaSfHzWicO3J5WdST9oS7h"))
c.Assert(err, checker.IsNil)
req, err = http.NewRequest(http.MethodGet, "https://127.0.0.1:4443/", nil)
c.Assert(err, checker.IsNil)
client = &http.Client{Transport: tr1}
req.Host = tr1.TLSClientConfig.ServerName
req.Header.Set("Host", tr1.TLSClientConfig.ServerName)
req.Header.Set("Accept", "*/*")
resp, err = client.Do(req)
c.Assert(err, checker.IsNil)
cn = resp.TLS.PeerCertificates[0].Subject.CommonName
c.Assert(cn, checker.Equals, "TRAEFIK DEFAULT CERT")
}

View File

@@ -419,7 +419,7 @@ func (s *EtcdSuite) TestCommandStoreConfig(c *check.C) {
"/traefik/loglevel": "DEBUG",
"/traefik/defaultentrypoints/0": "http",
"/traefik/entrypoints/http/address": ":8000",
"/traefik/web/address": ":8080",
"/traefik/api/entrypoint": "traefik",
"/traefik/etcd/endpoint": etcdHost + ":4001",
}
@@ -490,15 +490,15 @@ func (s *EtcdSuite) TestSNIDynamicTlsConfig(c *check.C) {
}
tlsconfigure1 := map[string]string{
"/traefik/tlsconfiguration/snitestcom/entrypoints": "https",
"/traefik/tlsconfiguration/snitestcom/certificate/keyfile": string(snitestComKey),
"/traefik/tlsconfiguration/snitestcom/certificate/certfile": string(snitestComCert),
"/traefik/tls/snitestcom/entrypoints": "https",
"/traefik/tls/snitestcom/certificate/keyfile": string(snitestComKey),
"/traefik/tls/snitestcom/certificate/certfile": string(snitestComCert),
}
tlsconfigure2 := map[string]string{
"/traefik/tlsconfiguration/snitestorg/entrypoints": "https",
"/traefik/tlsconfiguration/snitestorg/certificate/keyfile": string(snitestOrgKey),
"/traefik/tlsconfiguration/snitestorg/certificate/certfile": string(snitestOrgCert),
"/traefik/tls/snitestorg/entrypoints": "https",
"/traefik/tls/snitestorg/certificate/keyfile": string(snitestOrgKey),
"/traefik/tls/snitestorg/certificate/certfile": string(snitestOrgCert),
}
// config backends,frontends and first tls keypair
@@ -539,7 +539,7 @@ func (s *EtcdSuite) TestSNIDynamicTlsConfig(c *check.C) {
// wait for etcd
err = try.Do(60*time.Second, func() error {
_, err := s.kv.Get("/traefik/tlsconfiguration/snitestcom/certificate/keyfile", nil)
_, err := s.kv.Get("/traefik/tls/snitestcom/certificate/keyfile", nil)
return err
})
c.Assert(err, checker.IsNil)
@@ -573,7 +573,7 @@ func (s *EtcdSuite) TestSNIDynamicTlsConfig(c *check.C) {
// wait for etcd
err = try.Do(60*time.Second, func() error {
_, err := s.kv.Get("/traefik/tlsconfiguration/snitestorg/certificate/keyfile", nil)
_, err := s.kv.Get("/traefik/tls/snitestorg/certificate/keyfile", nil)
return err
})
c.Assert(err, checker.IsNil)

View File

@@ -8,14 +8,16 @@ defaultEntryPoints = ["http"]
[entryPoints]
[entryPoints.http]
address = ":8000"
[entryPoints.api]
address = ":7888"
checkNewVersion = false
################################################################
# Web configuration backend
# Api configuration
################################################################
[web]
address = ":7888"
[api]
entryPoint = "api"
################################################################
# File configuration backend

View File

@@ -0,0 +1,35 @@
logLevel = "DEBUG"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":5002"
[entryPoints.https]
address = ":5001"
[entryPoints.https.tls]
[acme]
email = "test@traefik.io"
storage = "/dev/null"
entryPoint = "https"
onDemand = {{.OnDemand}}
OnHostRule = {{.OnHostRule}}
caServer = "http://{{.BoulderHost}}:4000/directory"
[acme.httpchallenge]
entrypoint="http"
[file]
[backends]
[backends.backend]
[backends.backend.servers.server1]
url = "http://127.0.0.1:9010"
[frontends]
[frontends.frontend]
backend = "backend"
[frontends.frontend.routes.test]
rule = "Host:traefik.acme.wtf"

View File

@@ -0,0 +1,38 @@
logLevel = "DEBUG"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":5002"
[entryPoints.https]
address = ":5001"
[entryPoints.https.tls]
[web]
path="/traefik"
[acme]
email = "test@traefik.io"
storage = "/dev/null"
entryPoint = "https"
onDemand = {{.OnDemand}}
OnHostRule = {{.OnHostRule}}
caServer = "http://{{.BoulderHost}}:4000/directory"
[acme.httpchallenge]
entrypoint="http"
[file]
[backends]
[backends.backend]
[backends.backend.servers.server1]
url = "http://127.0.0.1:9010"
[frontends]
[frontends.frontend]
backend = "backend"
[frontends.frontend.routes.test]
rule = "Host:traefik.acme.wtf"

View File

@@ -9,8 +9,8 @@
[frontends.frontend.routes.test]
rule = "Host:traefik.acme.wtf"
[[tlsConfiguration]]
[[tls]]
entryPoints = ["https"]
[tlsConfiguration.certificate]
[tls.certificate]
certFile = "fixtures/acme/ssl/wildcard.crt"
keyFile = "fixtures/acme/ssl/wildcard.key"

View File

@@ -5,6 +5,8 @@ logLevel = "DEBUG"
[entryPoints]
[entryPoints.http]
address = ":8000"
[entryPoints.api]
address = ":8081"
[consul]
@@ -12,5 +14,5 @@ logLevel = "DEBUG"
watch = true
prefix = "traefik"
[web]
address = ":8081"
[api]
entryPoint = "api"

View File

@@ -3,6 +3,8 @@ defaultEntryPoints = ["http","https"]
logLevel = "DEBUG"
[entryPoints]
[entryPoints.api]
address = ":8081"
[entryPoints.http]
address = ":8000"
[entryPoints.https]
@@ -16,5 +18,5 @@ logLevel = "DEBUG"
prefix = "traefik"
watch = true
[web]
address = ":8081"
[api]
entryPoint = "api"

View File

@@ -1,8 +1,7 @@
defaultEntryPoints = ["http"]
logLevel = "DEBUG"
[web]
address = ":8080"
[api]
[entryPoints]
[entryPoints.http]

View File

@@ -6,7 +6,7 @@ logLevel = "DEBUG"
[entryPoints.http]
address = ":8000"
[web]
[api]
[docker]

View File

@@ -5,6 +5,8 @@ logLevel = "DEBUG"
[entryPoints]
[entryPoints.http]
address = ":8080"
[entryPoints.api]
address = ":8081"
[dynamodb]
AccessKeyID = "key"
@@ -12,5 +14,5 @@ logLevel = "DEBUG"
Endpoint = "{{.DynamoURL}}"
Region = "us-east-1"
[web]
address = ":8081"
[api]
entryPoint = "api"

View File

@@ -5,6 +5,8 @@ logLevel = "DEBUG"
[entryPoints]
[entryPoints.http]
address = ":8000"
[entryPoints.api]
address = ":8081"
[etcd]
@@ -13,5 +15,5 @@ logLevel = "DEBUG"
watch = true
useAPIV3 = {{.UseAPIV3}}
[web]
address = ":8081"
[api]
entryPoint = "api"

View File

@@ -3,6 +3,8 @@ defaultEntryPoints = ["http","https"]
logLevel = "DEBUG"
[entryPoints]
[entryPoints.api]
address = ":8081"
[entryPoints.http]
address = ":8000"
[entryPoints.https]
@@ -16,5 +18,6 @@ logLevel = "DEBUG"
# prefix = "/traefik"
# watch = true
[web]
address = ":8081"
[api]
entryPoint = "api"

View File

@@ -10,5 +10,4 @@ logLevel = "DEBUG"
[eureka]
endpoint = "http://{{.EurekaHost}}:8761/eureka"
delay = "1s"
[web]
address = ":8080"
[api]

View File

@@ -11,8 +11,7 @@ RootCAs = [ """{{ .CertContent }}""" ]
keyFile = """{{ .KeyContent }}"""
[web]
address = ":8080"
[api]
[file]

View File

@@ -11,8 +11,7 @@ InsecureSkipVerify = true
keyFile = """{{ .KeyContent }}"""
[web]
address = ":8080"
[api]
[file]

View File

@@ -8,8 +8,7 @@ logLevel = "DEBUG"
[entryPoints.http2]
address = ":9000"
[web]
address = ":8080"
[api]
[file]
[backends]

View File

@@ -8,8 +8,7 @@ logLevel = "DEBUG"
[entryPoints.http2]
address = ":9000"
[web]
address = ":8080"
[api]
[file]
[backends]

View File

@@ -6,8 +6,7 @@ logLevel = "DEBUG"
[entryPoints.http]
address = ":8000"
[web]
address = ":8080"
[api]
[file]
[backends]

View File

@@ -6,8 +6,7 @@ logLevel = "DEBUG"
[entryPoints.http]
address = ":8000"
[web]
address = ":8080"
[api]
[file]
[backends]

View File

@@ -16,8 +16,7 @@ defaultEntryPoints = ["https"]
certFile = "fixtures/https/snitest.org.cert"
keyFile = "fixtures/https/snitest.org.key"
[web]
address = ":8080"
[api]
[file]

View File

@@ -15,8 +15,7 @@ defaultEntryPoints = ["https"]
certFile = "fixtures/https/snitest.org.cert"
keyFile = "fixtures/https/snitest.org.key"
[web]
address = ":8080"
[api]
[file]

View File

@@ -16,8 +16,7 @@ defaultEntryPoints = ["https"]
certFile = "fixtures/https/snitest.org.cert"
keyFile = "fixtures/https/snitest.org.key"
[web]
address = ":8080"
[api]
[file]

View File

@@ -16,9 +16,9 @@
[frontends.frontend2.routes.test_2]
rule = "Host:snitest.org"
[[tlsConfiguration]]
[[tls]]
entryPoints = ["https"]
[tlsConfiguration.certificate]
[tls.certificate]
certFile = """-----BEGIN CERTIFICATE-----
MIIC/zCCAeegAwIBAgIJALAYHG/vGqWEMA0GCSqGSIb3DQEBBQUAMBYxFDASBgNV
BAMMC3NuaXRlc3Qub3JnMB4XDTE1MTEyMzIyMDU0NFoXDTI1MTEyMDIyMDU0NFow

View File

@@ -6,9 +6,11 @@ defaultEntryPoints = ["https"]
[entryPoints.https]
address = ":4443"
[entryPoints.https.tls]
[entryPoints.https02]
address = ":8443"
[entryPoints.https02.tls]
[web]
address = ":8080"
[api]
[file]

View File

@@ -13,8 +13,7 @@ defaultEntryPoints = ["https"]
certFile = "fixtures/https/snitest.org.cert"
keyFile = "fixtures/https/snitest.org.key"
[web]
address = ":8080"
[api]
[file]

View File

@@ -24,8 +24,7 @@ fblo6RBxUQ==
[entryPoints.http]
address = ":8081"
[web]
address = ":8080"
[api]
[file]

View File

@@ -9,8 +9,7 @@ RootCAs = [ "fixtures/https/rootcas/local.crt"]
[entryPoints.http]
address = ":8081"
[web]
address = ":8080"
[api]
[file]

View File

@@ -8,14 +8,16 @@ defaultEntryPoints = ["http"]
[entryPoints]
[entryPoints.http]
address = ":8000"
[entryPoints.api]
address = ":7888"
checkNewVersion = false
################################################################
# Web configuration backend
# Api configuration backend
################################################################
[web]
address = ":7888"
[api]
entryPoint = "api"
################################################################
# File configuration backend

Some files were not shown because too many files have changed in this diff Show More