Skip to content

Commit bb263bb

Browse files
committed
2 parents 92d9cd3 + f4a0ea5 commit bb263bb

29 files changed

Lines changed: 661 additions & 302 deletions

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ RUN go test --cover ./... --run UnitTest
66
RUN go build -v -o docker-flow-proxy
77

88

9-
10-
FROM haproxy:1.7-alpine
9+
FROM haproxy:1.8-alpine
1110
MAINTAINER Viktor Farcic <viktor@farcic.com>
1211

1312
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
@@ -22,6 +21,7 @@ ENV CERTS="" \
2221
DEFAULT_PORTS="80,443:ssl" \
2322
DEFAULT_REQ_MODE="http" \
2423
DO_NOT_RESOLVE_ADDR="false" \
24+
ENABLE_H2="true" \
2525
HEALTHCHECK="true" \
2626
HTTPS_ONLY="false" \
2727
EXTRA_FRONTEND="" \

Jenkinsfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pipeline {
4242
sh "docker image push vfarcic/docker-flow-proxy:${currentBuild.displayName}-packet-beat"
4343
dockerLogout()
4444
dfRelease("docker-flow-proxy")
45+
dfReleaseGithub("docker-flow-proxy")
4546
}
4647
}
4748
stage("deploy") {

actions/reconfigure.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package actions
22

33
import (
4-
"../proxy"
54
"bytes"
65
"fmt"
76
"html/template"
87
"os"
98
"strconv"
109
"strings"
1110
"sync"
11+
12+
"../proxy"
1213
)
1314

1415
const serviceTemplateFeFilename = "service-formatted-fe.ctmpl"

actions/reconfigure_test.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -398,19 +398,26 @@ backend myService-be5555_2
398398
s.Equal(expectedBack, actualBack)
399399
}
400400

401-
func (s ReconfigureTestSuite) Test_GetTemplates_AddsHttpRequestSetPath_WhenReqPathSearchAndReqPathReplaceArePresent() {
402-
s.reconfigure.ReqPathSearch = "this"
403-
s.reconfigure.ReqPathReplace = "that"
404-
s.reconfigure.ServiceDest = []proxy.ServiceDest{{Port: "1234", Index: 0}}
405-
expected := fmt.Sprintf(`
401+
func (s ReconfigureTestSuite) Test_GetTemplates_AddsHttpRequestSetPath_WhenReqPathSearchReplaceFormattedIsPresent() {
402+
s.reconfigure.HttpsPort = 1234
403+
s.reconfigure.ServiceDest = []proxy.ServiceDest{{
404+
Port: "1234",
405+
Index: 0,
406+
ReqPathSearchReplaceFormatted: []string{"this,that", "foo,bar"},
407+
}}
408+
expected := `
406409
backend myService-be1234_0
407410
mode http
408411
http-request add-header X-Forwarded-Proto https if { ssl_fc }
409-
http-request set-path %%[path,regsub(%s,%s)]
410-
server myService myService:1234`,
411-
s.reconfigure.ReqPathSearch,
412-
s.reconfigure.ReqPathReplace,
413-
)
412+
http-request set-path %[path,regsub(this,that)]
413+
http-request set-path %[path,regsub(foo,bar)]
414+
server myService myService:1234
415+
backend https-myService-be1234_0
416+
mode http
417+
http-request add-header X-Forwarded-Proto https if { ssl_fc }
418+
http-request set-path %[path,regsub(this,that)]
419+
http-request set-path %[path,regsub(foo,bar)]
420+
server myService myService:1234`
414421

415422
_, backend, _ := s.reconfigure.GetTemplates()
416423

docs/certs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ The relevant part of the output is as follows.
178178
```
179179
frontend services
180180
bind *:80
181-
bind *:443 ssl crt-list /cfg/crt-list.txt
181+
bind *:443 ssl crt-list /cfg/crt-list.txt alpn h2,http/1.1
182182
mode http
183183
184184
acl url_go-demo path_beg /demo

docs/config.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ The following environment variables can be used to configure the *Docker Flow Pr
2121
|COMPRESSION_TYPE |The type of files that will be compressed.<br>**Example:** text/css text/html text/javascript application/javascript text/plain text/xml application/json|
2222
|CONNECTION_MODE |HAProxy supports 5 connection modes.<br><br>`http-keep-alive`: all requests and responses are processed.<br>`http-tunnel`: only the first request and response are processed, everything else is forwarded with no analysis.<br>`httpclose`: tunnel with "Connection: close" added in both directions.<br>`http-server-close`: the server-facing connection is closed after the response.<br>`forceclose`: the connection is actively closed after end of response.<br><br>In general, it is preferred to use `http-server-close` with application servers, and some static servers might benefit from `http-keep-alive`.<br>**Example:** `http-server-close`<br>**Default value:** `http-keep-alive`|
2323
|DEBUG |Enables logging of each request sent through the proxy. Please consult [Debug Format](#debug-format) for info about the log entries. This feature should be used with caution. **Do not enable debugging in production unless necessary.**<br>**Example:** true<br>**Default value:** `false`|
24-
|DEBUG_ERRORS_ONLY |If set to `true`, only requests that resulted in an error, timeout, retry, and redispatch will be logged. If a request is HTTP, responses with a status 5xx will be logged too. This variable will take effect only if `DEBUG` is set to `true`.<br>**Example:** true<br>**Default value:** `false`|
24+
|DEBUG_ERRORS_ONLY |If set to `true`, only requests that resulted in an error, timeout, retry, and redispatch will be logged. If a request is HTTP, responses with a status 5xx will be logged too. This variable will take effect only if `DEBUG` is set to `true`.<br>**Example:** `true`<br>**Default value:** `false`|
2525
|DEBUG_HTTP_FORMAT |Logging format that will be used with HTTP requests. Please consult [Custom log format](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#8.2.4) for more info about the available options.|
2626
|DEBUG_TCP_FORMAT |Logging format that will be used with TCP requests. Please consult [Custom log format](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#8.2.4) for more info about the available options.|
2727
|DEFAULT_PORTS     |The default ports used by the proxy. Multiple values can be separated with comma (`,`). If a port should be for SSL connections, append it with `:ssl`. Additional binding options can be added after a port. For example, `80 accept-proxy,443 accept-proxy:ssl` adds `accept-proxy` to the defalt binding options.<br>**Default value:** `80,443:ssl`|
2828
|DEFAULT_REQ_MODE |The default request mode used by the proxy.<br>**Default value:** `http`|
2929
|DO_NOT_RESOLVE_ADDR|Whether not to resolve addresses. If set to `true`, the proxy will NOT fail if the service is not available.<br>**Default value:** `false`|
30+
|ENABLE_H2 |Whether to enable http/2<br>**Example:** `false`<br>**Default:** `true`|
3031
|EXTRA_FRONTEND |Value will be added to the default `frontend` configuration. Multiple lines should be separated with comma (*,*).|
3132
|EXTRA_GLOBAL |Value will be added to the default `global` configuration. Multiple lines should be separated with comma (*,*).|
3233
|HTTPS_ONLY |If set to true, all requests to all services will be redirected to HTTPS.<br>**Example:** `true`<br>**Default Value:** `false`|

docs/sni-routing.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ services:
6363
replicas: 1
6464
labels:
6565
com.df.notify: 'true'
66-
com.df.distribute: 'true'
6766
com.df.pathType: "req_ssl_sni -i -m reg"
6867
com.df.servicePath: "^(api\\.)"
6968
com.df.srcPort: 443
@@ -87,7 +86,6 @@ services:
8786
replicas: 1
8887
labels:
8988
com.df.notify: 'true'
90-
com.df.distribute: 'true'
9189
com.df.pathType: "req_ssl_sni -i -m beg"
9290
com.df.servicePath: "test."
9391
com.df.srcPort: 443

docs/swarm-mode-auto.md

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ docker service create --name go-demo \
102102
--network go-demo \
103103
--network proxy \
104104
--label com.df.notify=true \
105-
--label com.df.distribute=true \
106105
--label com.df.servicePath=/demo \
107106
--label com.df.port=8080 \
108107
vfarcic/go-demo
@@ -139,7 +138,7 @@ We sent a request to the proxy (the only service listening to the port 80) and g
139138

140139
The way the process works is as follows.
141140

142-
[Docker Flow: Swarm Listener](https://github.com/vfarcic/docker-flow-swarm-listener) is running inside one of the Swarm manager nodes and queries Docker API in search for newly created services. Once it finds a new service, it looks for its labels. If the service contains the `com.df.notify` (it can hold any value), the rest of the labels with keys starting with `com.df.` are retrieved. All those labels are used to form request parameters. Those parameters are appended to the address specified as the `DF_NOTIFY_CREATE_SERVICE_URL` environment variable defined in the `swarm-listener` service. Finally, a request is sent. In this particular case, the request was made to reconfigure the proxy with the service `go-demo` (the name of the service), using `/demo` as the path, and running on the port `8080`. The `distribute` label is not necessary in this example since we're running only a single instance of the proxy. However, in production we should run at least two proxy instances (for fault tolerance) and the `distribute` argument means that reconfiguration should be applied to all.
141+
[Docker Flow: Swarm Listener](https://github.com/vfarcic/docker-flow-swarm-listener) is running inside one of the Swarm manager nodes and queries Docker API in search for newly created services. Once it finds a new service, it looks for its labels. If the service contains the `com.df.notify` (it can hold any value), the rest of the labels with keys starting with `com.df.` are retrieved. All those labels are used to form request parameters. Those parameters are appended to the address specified as the `DF_NOTIFY_CREATE_SERVICE_URL` environment variable defined in the `swarm-listener` service. Finally, a request is sent. In this particular case, the request was made to reconfigure the proxy with the service `go-demo` (the name of the service), using `/demo` as the path, and running on the port `8080`.
143142

144143
Please see the [Reconfigure](usage.md#reconfigure) section for the list of all the arguments that can be used with the proxy.
145144

@@ -231,7 +230,6 @@ docker service create --name go-demo \
231230
--network go-demo \
232231
--network proxy \
233232
--label com.df.notify=true \
234-
--label com.df.distribute=true \
235233
--label com.df.servicePath=/demo \
236234
--label com.df.port=8080 \
237235
--replicas 3 \
@@ -336,9 +334,9 @@ From now on, the username and password are `secret-user` and `secret-pass`. Unli
336334

337335
## Rewriting Paths
338336

339-
In some cases, you might want to rewrite the path of the incoming request before forwarding it to the destination service. We can do that using request parameters `reqPathSearch` and `reqPathReplace`.
337+
In some cases, you might want to rewrite the path of the incoming request before forwarding it to the destination service. We can do that using request parameter `reqPathSearchReplace`.
340338

341-
As an example, we'll create the `go-demo` service that will be configured in the proxy to accept requests with the path starting with `/something`. Since the `go-demo` service allows only requests that start with `/demo`, we'll use `reqPathSearch` and `reqPathReplace` to rewrite the path.
339+
As an example, we'll create the `go-demo` service that will be configured in the proxy to accept requests with the path starting with `/something`. Since the `go-demo` service allows only requests that start with `/demo`, we'll use `reqPathSearchReplace` to rewrite the path.
342340

343341
The command is as follows.
344342

@@ -350,16 +348,14 @@ docker service create --name go-demo \
350348
--network go-demo \
351349
--network proxy \
352350
--label com.df.notify=true \
353-
--label com.df.distribute=true \
354351
--label com.df.servicePath=/something \
355352
--label com.df.port=8080 \
356-
--label com.df.reqPathSearch='/something/' \
357-
--label com.df.reqPathReplace='/demo/' \
353+
--label com.df.reqPathSearchReplace='/something/,/demo/' \
358354
--replicas 3 \
359355
vfarcic/go-demo
360356
```
361357

362-
Please notice that, this time, the `servicePath` is `/something`. The `reqPathSearch` specifies the regular expression that will be used to search for part of the address and the `reqPathReplace` will replace it. In this case, `/something/` will be replaced with `/demo/`. The proxy uses the *regsub* function within the *http-request set-path* directive to apply a regex-based substitution which operates as the well-known *sed* utility with `"s/<regex>/<subst>/"`. For more information, please consult [Configuration: 4.2 http-request](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4.2-http-request) and [Configuration: 7.3.1 regsub](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#7.3.1-regsub).
358+
The `reqPathSearchReplace` specifies the regular expression that will be used to search for part of the address and replace it. In this case, `/something/` will be replaced with `/demo/`. The proxy uses the *regsub* function within the *http-request set-path* directive to apply a regex-based substitution which operates as the well-known *sed* utility with `"s/<regex>/<subst>/"`. For more information, please consult [Configuration: 4.2 http-request](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4.2-http-request) and [Configuration: 7.3.1 regsub](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#7.3.1-regsub).
363359

364360
Please wait a few moments until the `go-demo` service is running. You can see the status of the service by executing `docker service ps go-demo`.
365361

@@ -382,12 +378,11 @@ hello, world!
382378

383379
We sent a request to `/something/hello`. The proxy accepted the request, rewrote the path to `/demo/hello`, and forwarded it to the `go-demo` service.
384380

385-
The `reqPathSearch` label accepts regular expressions. We can, for example, rewrite any path that starts with `/something/` to `/demo/hello`.
381+
The `reqPathSearchReplace` label accepts regular expressions. We can, for example, rewrite any path that starts with `/something/` to `/demo/hello`.
386382

387383
```bash
388384
docker service update \
389-
--label-add com.df.reqPathSearch='/something/.*' \
390-
--label-add com.df.reqPathReplace='/demo/hello' \
385+
--label-add com.df.reqPathSearchReplace='/something/.*,/demo/hello' \
391386
go-demo
392387
```
393388

@@ -423,7 +418,6 @@ docker service create --name go-demo \
423418
--network go-demo \
424419
--network proxy \
425420
--label com.df.notify=true \
426-
--label com.df.distribute=true \
427421
--label com.df.servicePath=/demo \
428422
--label com.df.port=8080 \
429423
--replicas 3 \
@@ -527,7 +521,6 @@ docker service create --name go-demo \
527521
--network go-demo \
528522
--network proxy \
529523
--label com.df.notify=true \
530-
--label com.df.distribute=true \
531524
--label com.df.servicePath=/demo \
532525
--label com.df.port=8080 \
533526
--label com.df.users=admin:password \
@@ -640,7 +633,6 @@ docker service create --name go-demo \
640633
--network go-demo \
641634
--network proxy \
642635
--label com.df.notify=true \
643-
--label com.df.distribute=true \
644636
--label com.df.servicePath=/demo \
645637
--label com.df.port=8080 \
646638
vfarcic/go-demo
@@ -666,7 +658,6 @@ Let us create a service that will allow us to test whether `tcp` protocol works.
666658
docker service create --name redis \
667659
--network proxy \
668660
--label com.df.notify=true \
669-
--label com.df.distribute=true \
670661
--label com.df.port=6379 \
671662
--label com.df.srcPort=6379 \
672663
--label com.df.reqMode=tcp \

docs/swarm-mode-stack.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ services:
141141
replicas: 3
142142
labels:
143143
- com.df.notify=true
144-
- com.df.distribute=true
145144
- com.df.servicePath=/demo
146145
- com.df.port=8080
147146
@@ -190,6 +189,8 @@ Since Mongo database is much bigger than the `main` service, it takes more time
190189
After a few moments, the `swarm-listener` service will detect the `main` service from the `go-demo` stack and send the `proxy` a request to reconfigure itself. We can see the result by sending an HTTP request to the proxy.
191190

192191
```bash
192+
exit
193+
193194
curl -i "$(docker-machine ip node-1)/demo/hello"
194195
```
195196

0 commit comments

Comments
 (0)