diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 99f4b78f49d9b5967da6eaaf0904521a5d22377c..59c4b2abaa0f85f4a21ce2c17286863acee8f435 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,15 +1,14 @@
+image: registry.hedenstroem.com/gitlab/gitlab-builder-erlang:19.1
+
+variables:
+  IMAGE_NAME: "${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}"
+
 cache:
   paths:
-  - .rebar3
+    - .rebar3
 
 before_script:
-  - export GOROOT=${GO_HOME}
-  - export GOPATH=${CI_PROJECT_DIR}/_build/go
-  - export PATH=${ERL_HOME}/bin:${GOPATH}/bin:${GOROOT}/bin:$PATH
-  - export DOCKER_HOST="tcp://127.0.0.1:2375"
-  - mkdir -p ${GOPATH}
-  - socat tcp-listen:2375,reuseaddr,bind=127.0.0.1,fork unix-connect:/var/run/docker.sock &
-  - sleep 2
+  - export PATH=${ERL_HOME}/bin:$PATH
 
 stages:
   - test
@@ -20,10 +19,7 @@ stages:
 test:
   stage: test
   script:
-    - rebar3 update
-    - git pull origin master
-    - docker pull hedenstroem/consul:latest
-    - FORMAT="compact" ERL_AFLAGS="-args_file config/test-vm.args -config config/test-sys.config" rebar3 as test do eunit --cover --application=consul_proxy --dir=apps/consul_proxy/test, cover --verbose
+    - rebar3 test
     - coverage.escript _build/test/cover/eunit.coverdata
 
 build:
@@ -32,50 +28,32 @@ build:
     - master
     - production
   script:
-    - rebar3 update
     - rebar3 edoc
-    - rebar3 as production do tar
-    - relinfo.escript -vsn _build/production/rel/consul_proxy/releases/RELEASES > _build/VERSION
+    - rebar3 as prod do tar
+    - relinfo.escript -vsn _build/prod/rel/${CI_PROJECT_NAME}/releases/RELEASES > _build/VERSION
   artifacts:
     paths:
       - _build/edoc
+      - _build/prod/rel/${CI_PROJECT_NAME}/Dockerfile
+      - _build/prod/rel/${CI_PROJECT_NAME}/${CI_PROJECT_NAME}-*.tar.gz
       - _build/VERSION
-      - _build/production/rel/consul_proxy/consul_proxy-*.tar.gz
-
-scripts:
-  stage: build
-  only:
-    - master
-    - production
-  script:
-    - make genpasswd
-    - make consul-backup
-  artifacts:
-    paths:
-      - _build/consul-backup
-      - _build/genpasswd
 
-aws_s3:
+upload to aws:
   stage: deploy
   only:
     - production
   script:
-    - aws s3 cp _build/consul-backup s3://s3.erlang.ninja/consul_proxy/extras/consul-backup
-    - aws s3 cp _build/genpasswd s3://s3.erlang.ninja/consul_proxy/extras/genpasswd
-    - aws s3 cp _build/edoc s3://s3.erlang.ninja/consul_proxy/$(cat _build/VERSION)/ --recursive
-    - aws s3 cp _build/production/rel/consul_proxy/consul_proxy-$(cat _build/VERSION).tar.gz s3://s3.erlang.ninja/consul_proxy/
+    - aws s3 cp _build/edoc s3://s3.erlang.ninja/${CI_PROJECT_NAME}/$(cat _build/VERSION)/ --recursive
+    - aws s3 cp _build/prod/rel/${CI_PROJECT_NAME}/${CI_PROJECT_NAME}-$(cat _build/VERSION).tar.gz s3://s3.erlang.ninja/${CI_PROJECT_NAME}/
 
 docker:
   stage: deploy
   only:
     - production
   script:
-    - export REL_VSN=$(cat _build/VERSION)
-    - envsubst '$REL_VSN' < apps/consul_proxy/priv/Dockerfile > _build/production/Dockerfile
-    - docker build -t ${DOCKER_HUB_REPO} -f _build/production/Dockerfile _build/production
-    - docker tag ${DOCKER_HUB_REPO} ${DOCKER_HUB_REPO}:${REL_VSN}
-    - docker login --username=${DOCKER_HUB_USERNAME} --password=${DOCKER_HUB_PASSWORD}
-    - docker push ${DOCKER_HUB_REPO}
+    - docker build -t ${IMAGE_NAME}:$(cat _build/VERSION) _build/prod/rel/${CI_PROJECT_NAME}
+    - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY}
+    - docker push ${IMAGE_NAME}:$(cat _build/VERSION)
 
 trigger:
   stage: trigger
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 5435eb9bfd3c11c60e8d3f2dfadce0da8e828338..0000000000000000000000000000000000000000
--- a/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-REBAR_VERSION := $(shell rebar3 --version 2>/dev/null)
-ifdef REBAR_VERSION
-REBAR := rebar3
-else
-REBAR := $(CURDIR)/rebar3
-$(shell if ! [ -e "$(REBAR)" ]; then curl -jksSL -o $(REBAR) https://s3.amazonaws.com/rebar3/rebar3; chmod +x $(REBAR); fi)
-endif
-
-all: eunit
-
-compile:
-	@$(REBAR) compile
-
-eunit:
-	@FORMAT="compact" ERL_AFLAGS="-args_file config/test-vm.args -config config/test-sys.config" $(REBAR) as test do eunit --cover --application=consul_proxy --dir=apps/consul_proxy/test, cover --verbose
-
-dialyzer:
-	@$(REBAR) dialyzer
-
-release:
-	@$(REBAR) release
-
-image:
-	@$(REBAR) release -d false
-	PLATFORM=x86 envsubst '$$PLATFORM' < apps/consul_proxy/priv/Dockerfile > _build/default/Dockerfile
-	docker build --no-cache=true -t ehedenst/consul_proxy:x86 -f _build/default/Dockerfile _build/default
-
-edoc:
-	@$(REBAR) edoc
-
-clean:
-	@$(REBAR) clean
-
-distclean:
-	@rm -rf _build rebar.lock log $(REBAR)
-
-shell:
-	@$(REBAR) shell --config=config/test-sys.config
-
-genpasswd:
-	@go get golang.org/x/crypto/pbkdf2
-	@go build -o _build/genpasswd scripts/genpasswd.go
-
-consul-backup:
-	@go get github.com/hashicorp/consul/api
-	@go get github.com/docopt/docopt-go
-	@go build -o _build/consul-backup scripts/consul-backup.go
diff --git a/README.md b/README.md
index 2e50a5dcf2fdd5eec60c84fc0a98a226aaf135dd..bcc66fefb939c3267b9cde5586ae7e1b1288f790 100644
--- a/README.md
+++ b/README.md
@@ -155,3 +155,19 @@ Load Balancing
 
 Logging
 -------
+
+Tools
+-----
+
+### Hijack
+
+See the [project page](https://gitlab.hedenstroem.com/erlang-ninja/hijack) on details of how to use and where to [download](http://s3.erlang.ninja/consul_proxy/extras/hijack) from.
+
+
+### Consul Backup
+
+Used to backup the KEY/VALUE data from consul to a file. It can also restore KEY/VALUE data from a file. Download it [here](http://s3.erlang.ninja/consul_proxy/extras/consul-backup).
+
+### Password generator
+
+Use the password generator to create username:password values for the Auth middleware. It must also be used to generate passwords for the hijack configuration. Download it [here](http://s3.erlang.ninja/consul_proxy/extras/genpasswd).
diff --git a/apps/consul_proxy/priv/Dockerfile b/apps/consul_proxy/priv/Dockerfile
index 4f71a61cb85c9fb5bc5c36afa641fd87ab0d6c32..b312bc9818b71e467fd4252839383aee233499bd 100644
--- a/apps/consul_proxy/priv/Dockerfile
+++ b/apps/consul_proxy/priv/Dockerfile
@@ -1,20 +1,12 @@
-FROM        hedenstroem/erlang
+FROM        hedenstroem/otp:19.1
 MAINTAINER  Erik Hedenström <erik@erlang.ninja>
 
-ENV NAME_PREFIX consul_proxy
+ENV NAME_PREFIX {{release_name}}
 ENV COOKIE Nax7jEj7bay6ril
 
-RUN apk --update add \
-    erlang-inets=$ERLANG_VERSION \
-    erlang-ssl=$ERLANG_VERSION \
-    erlang-asn1=$ERLANG_VERSION \
-    erlang-observer=$ERLANG_VERSION \
-    erlang-public-key=$ERLANG_VERSION && \
-    rm -rf /var/cache/apk/*
-
-ADD rel/consul_proxy/consul_proxy-${REL_VSN}.tar.gz /opt/consul_proxy
+ADD {{release_name}}-{{rel_vsn}}.tar.gz /opt/{{release_name}}
 
 EXPOSE 8080-8083
 
-ENTRYPOINT [ "/opt/consul_proxy/bin/consul_proxy-wrapper" ]
+ENTRYPOINT [ "/opt/{{release_name}}/bin/wrapper" ]
 CMD [ "foreground" ]
diff --git a/apps/consul_proxy/priv/consul_proxy-wrapper b/apps/consul_proxy/priv/wrapper
similarity index 84%
rename from apps/consul_proxy/priv/consul_proxy-wrapper
rename to apps/consul_proxy/priv/wrapper
index 7de6a3eb7f0a21926a45966f348a2c1418ebdde7..a4c26e902b0f8e57d438db8b1c876c48151365a9 100755
--- a/apps/consul_proxy/priv/consul_proxy-wrapper
+++ b/apps/consul_proxy/priv/wrapper
@@ -9,7 +9,7 @@ fi;
 SCRIPT_DIR="$(cd `dirname "$SCRIPT"` && pwd -P)"
 
 if [ -z "$NAME_PREFIX" ]; then
-    NAME_PREFIX="consul_proxy-$(openssl rand -hex 4)"
+    NAME_PREFIX="{{release_name}}-$(openssl rand -hex 4)"
 fi
 
 if [ -z "$COOKIE" ]; then
@@ -25,4 +25,4 @@ export NODE_NAME=${NAME_PREFIX}@${HOST_IP}
 
 echo "Starting ${NODE_NAME} with cookie ${COOKIE}"
 
-${SCRIPT_DIR}/consul_proxy $@
+${SCRIPT_DIR}/{{release_name}} $@
diff --git a/apps/consul_proxy/src/consul_client.erl b/apps/consul_proxy/src/consul_client.erl
index 46215a38119581c03c35a552989a3701e40344af..ef9be505145e447a86bbedbe1e29038ea72042af 100644
--- a/apps/consul_proxy/src/consul_client.erl
+++ b/apps/consul_proxy/src/consul_client.erl
@@ -503,7 +503,7 @@ watch(Parent, Path, PathWithIndex, Delay) ->
 
 -spec trigger_webhooks(Path :: binary, Index :: number()) -> any().
 trigger_webhooks(<<"/v1/kv/consul_proxy?recurse">>, Index) ->
-    trigger_webhooks(<<"consul_proxy/watchers/kv">>, Index, []);
+    trigger_webhooks(<<"consul_proxy/watchers/kv">>, Index, [{<<"index">>, Index}]);
 trigger_webhooks(<<"/v1/catalog/services">>, Index) ->
     case consul_client:services() of
         {ok, Services} ->
diff --git a/apps/consul_proxy/src/consul_proxy.app.src b/apps/consul_proxy/src/consul_proxy.app.src
index 548d36bed4fe641b26990cad9afee2bf8b35cf0b..f69c3e4553156f7f64127022770c9699e4756958 100644
--- a/apps/consul_proxy/src/consul_proxy.app.src
+++ b/apps/consul_proxy/src/consul_proxy.app.src
@@ -1,6 +1,6 @@
 {application, consul_proxy, [
     {description, "Proxy for docker swarm using consul and vegur"},
-    {vsn, "0.5.3"},
+    {vsn, "0.6.0"},
     {registered, []},
     {mod, {consul_proxy_app, []}},
     {applications, [
diff --git a/apps/consul_proxy/src/consul_proxy_lager_backend.erl b/apps/consul_proxy/src/consul_proxy_lager_backend.erl
index 825e1e9df03184e996891eddbaa6981e0e082c0e..b5fb8ab733b8ed8352ccedd098c9c450ec765152 100644
--- a/apps/consul_proxy/src/consul_proxy_lager_backend.erl
+++ b/apps/consul_proxy/src/consul_proxy_lager_backend.erl
@@ -7,7 +7,6 @@
 -record(state, {level, formatter, config, socket}).
 
 init(Config) ->
-    random:seed(erlang:phash2([node()]), erlang:monotonic_time(), erlang:unique_integer()),
     Level = proplists:get_value(level, Config, info),
     Formatter = proplists:get_value(formatter, Config, consul_proxy_request_formatter),
     Levels = lager_util:config_to_mask(Level),
@@ -69,14 +68,14 @@ pick_node([]) ->
 pick_node([Node]) ->
     Node;
 pick_node(Nodes) ->
-    N = random:uniform(length(Nodes)),
+    N = rand:uniform(length(Nodes)),
     lists:nth(N, Nodes).
 
 %% @private
 lookup_nodes() ->
     case consul_proxy_utils:cache_get(logservice) of
         undefined ->
-            Service = application:get_env(consul_proxy, logservice, "logstash-udp"),
+            Service = application:get_env(consul_proxy, logservice, "logstash"),
             case consul_client:service(Service) of
                 {ok, List} ->
                     Nodes = lists:map(
diff --git a/apps/consul_proxy/src/consul_proxy_loadbalancer.erl b/apps/consul_proxy/src/consul_proxy_loadbalancer.erl
index 7cd0623e9e4064be18f103598e1e3f08b2942c53..39fb699e566559df2adcf689d6ecf24b32bfbb5b 100644
--- a/apps/consul_proxy/src/consul_proxy_loadbalancer.erl
+++ b/apps/consul_proxy/src/consul_proxy_loadbalancer.erl
@@ -97,7 +97,6 @@ start_link(Args) ->
     {stop, Reason :: term()} | ignore).
 init(Args) ->
     lager:info("Args: ~p", [Args]),
-    random:seed(erlang:phash2([node()]), erlang:monotonic_time(), erlang:unique_integer()),
     Counter = tsuru_counter:new(),
     ForwardDecays = ets:new(forward_decays, [set, {write_concurrency, true}]),
     Weights = ets:new(weights, [set, {write_concurrency, true}]),
@@ -118,7 +117,7 @@ init(Args) ->
     {stop, Reason :: term(), Reply :: term(), NewState :: #state{}} |
     {stop, Reason :: term(), NewState :: #state{}}).
 handle_call({pick, random, Services}, _From, State) ->
-    Index = random:uniform(length(Services)),
+    Index = rand:uniform(length(Services)),
     Pick = lists:nth(Index, Services),
     {reply, {ok, Pick, lists:delete(Pick, Services)}, State};
 
@@ -129,7 +128,7 @@ handle_call({pick, jsq, Services}, _From, State = #state{counter = Counter}) ->
                 {Service, get_count(Counter, Service), NewServices};
             (Candidate, {Current, CurrentCount, NewServices}) ->
                 CandidateCount = get_count(Counter, Candidate),
-                OneOrTwo = random:uniform(2),
+                OneOrTwo = rand:uniform(2),
                 if
                     CandidateCount < CurrentCount -> {Candidate, CandidateCount, [Current | NewServices]};
                     CandidateCount > CurrentCount -> {Current, CurrentCount, [Candidate | NewServices]};
@@ -147,7 +146,7 @@ handle_call({pick, esl, Services}, _From, State) ->
                 {Candidate, Weight, []};
             ({Candidate, Weight}, {Current, Sum, NewServices}) ->
                 NewSum = Sum + Weight,
-                R = random:uniform(NewSum),
+                R = rand:uniform(NewSum),
                 if
                     R > Sum ->
                         {Candidate, NewSum, [Current | NewServices]};
@@ -158,19 +157,19 @@ handle_call({pick, esl, Services}, _From, State) ->
     {reply, {ok, Pick, ServicesExcludingPick}, State};
 
 handle_call({sort, random, Services}, _From, State) ->
-    ShuffledServices = [R || {_, R} <- lists:sort([{random:uniform(), S} || S <- Services])],
+    ShuffledServices = [R || {_, R} <- lists:sort([{rand:uniform(), S} || S <- Services])],
     {reply, {ok, ShuffledServices}, State};
 
 handle_call({sort, jsq, Services}, _From, State = #state{counter = Counter}) ->
     OrderingFun = fun({A, _}, {B, _}) -> A =< B end,
-    ShuffledServices = [R || {_, R} <- lists:sort(OrderingFun, [{random:uniform(), S} || S <- Services])],
+    ShuffledServices = [R || {_, R} <- lists:sort(OrderingFun, [{rand:uniform(), S} || S <- Services])],
     WeightedServices = [{get_count(Counter, Service), Service} || Service <- ShuffledServices],
     SortedServices = [R || {_, R} <- lists:sort(OrderingFun, WeightedServices)],
     {reply, {ok, SortedServices}, State};
 
 handle_call({sort, esl, Services}, _From, State) ->
     OrderingFun = fun({A, _}, {B, _}) -> A =< B end,
-    ShuffledServices = [R || {_, R} <- lists:sort(OrderingFun, [{random:uniform(), S} || S <- Services])],
+    ShuffledServices = [R || {_, R} <- lists:sort(OrderingFun, [{rand:uniform(), S} || S <- Services])],
     WeightedServices = [{get_weight(State, Service), Service} || Service <- ShuffledServices],
     SortedServices = [R || {_, R} <- lists:sort(OrderingFun, WeightedServices)],
     {reply, {ok, SortedServices}, State};
diff --git a/apps/consul_proxy/src/consul_proxy_router.erl b/apps/consul_proxy/src/consul_proxy_router.erl
index 25395655498df67776a74dcc8aa3d392a569fb96..7e793c98f0a8937c5b8372d95a34d18072f9eca7 100644
--- a/apps/consul_proxy/src/consul_proxy_router.erl
+++ b/apps/consul_proxy/src/consul_proxy_router.erl
@@ -16,8 +16,7 @@
 
 -record(state, {services = undefined, headers = []}).
 
-init(AcceptTime, Upstream) ->
-    random:seed(AcceptTime),
+init(_AcceptTime, Upstream) ->
     {ok, Upstream, #state{}}.
 
 lookup_domain_name(Domain, Upstream, HandlerState) ->
@@ -163,7 +162,13 @@ lookup_resolver(_Domain, _Upstream, _Properties, undefined, _CacheFlag) ->
 lookup_resolver(Domain, Upstream, Properties, ServiceResolver, _CacheFlag) ->
     case consul_proxy_utils:eval_script(ServiceResolver, build_script_vars(Properties, Upstream)) of
         {ok, Result} ->
-            lookup_services(Domain, Upstream, Result, false);
+            case consul_proxy_utils:is_proplist(Result) of
+                true ->
+                    lookup_services(Domain, Upstream, Result, false);
+                false ->
+                    lager:error("Script '~s' result is not a proplist: ~p", [ServiceResolver, Result]),
+                    {error, route_lookup_failed}
+            end;
         {error, Reason} ->
             lager:error("Failed to evaluate '~s': ~p", [ServiceResolver, Reason]),
             {error, route_lookup_failed}
diff --git a/apps/consul_proxy/src/consul_proxy_utils.erl b/apps/consul_proxy/src/consul_proxy_utils.erl
index cb0dddda9faf8f5377aeca224e20c46cdc7bba20..e8a90f7354e7f633158c8b7ef747df46716f1b1b 100644
--- a/apps/consul_proxy/src/consul_proxy_utils.erl
+++ b/apps/consul_proxy/src/consul_proxy_utils.erl
@@ -12,7 +12,8 @@
     cache_get/1,
     cache_add/2,
     cache_purge/0,
-    cache_size/0
+    cache_size/0,
+    is_proplist/1
 ]).
 
 -include("consul_proxy.hrl").
@@ -296,3 +297,11 @@ cache_purge() ->
 -spec cache_size() -> non_neg_integer().
 cache_size() ->
     lru:size(consul_cache).
+
+-spec is_proplist(List :: term()) -> boolean().
+is_proplist([]) ->
+    true;
+is_proplist([{_, _} | L]) ->
+    is_proplist(L);
+is_proplist(_) ->
+    false.
diff --git a/apps/consul_proxy/test/common_steps.erl b/apps/consul_proxy/test/common_steps.erl
index e2f758ccfe71ee6b995cc3ebf54fc2a878ed4913..8a28a1d5694137952cf5a77cf5ba87e8274d17a9 100644
--- a/apps/consul_proxy/test/common_steps.erl
+++ b/apps/consul_proxy/test/common_steps.erl
@@ -25,26 +25,20 @@ setup_feature(_Tokens) ->
             {K, V}
         end, os:getenv()),
     lager:debug("~p", [Env]),
-    application:ensure_all_started(inets),
-    application:ensure_all_started(nkdocker),
-    {_Pid, State} = get_nkdocker_pid(#{os_env => Env, test_env => [], nkdocker_ids => []}),
-    {ok, State}.
+    application:ensure_all_started(hackney),
+    {ok, Pid} = dockerl:start_link(socket, <<"/var/run/docker.sock">>),
+    IPAddress = list_to_binary(inet:ntoa(local_ip_v4())),
+    {ok, #{os_env => Env, test_env => [{<<"ip_address">>, IPAddress}], applications => [], containers => [], dockerl_pid => Pid}}.
 
-teardown_feature(#{nkdocker_pid := Pid, nkdocker_ids := Ids}) ->
-    {async, Ref} = nkdocker:events(Pid),
+teardown_feature(#{dockerl_pid := Pid, containers := Containers, applications := Applications}) ->
+    [application:stop(Application) || Application <- lists:reverse(Applications)],
     lists:foreach(
         fun({Name, Id}) ->
-            ok = nkdocker:kill(Pid, Id),
-            nkdocker_receive_status(Ref, Id, <<"kill">>),
-            nkdocker_receive_status(Ref, Id, <<"die">>),
-            lager:notice("Docker container ~s killed", [Name]),
-            ok = nkdocker:rm(Pid, Id),
-            nkdocker_receive_status(Ref, Id, <<"destroy">>),
-            lager:notice("Docker container ~s destroyed", [Name])
-        end, Ids),
-    nkdocker:finish_async(Pid, Ref),
-    nkdocker_receive(Ref, {ok, user_stop}),
-    nkdocker:stop(Pid),
+            ok = dockerl:stop_container(Pid, Id),
+            lager:notice("Docker container ~s stopped", [Name]),
+            ok = dockerl:remove_container(Pid, Id),
+            lager:notice("Docker container ~s removed", [Name])
+        end, Containers),
     ok;
 teardown_feature(_State) ->
     ok.
@@ -56,63 +50,67 @@ teardown_scenario(_State) ->
     ok.
 
 %% noinspection ErlangUnboundVariable
-given([<<"a">>, <<"docker">>, <<"container">>, <<"named">>, Name, <<"running">>, Image, <<"with">>, <<"commands:">>, {docstring, Args}], State = #{nkdocker_pid := Pid, nkdocker_ids := Ids}) ->
+given([<<"a">>, <<"docker">>, <<"container">>, <<"named">>, Name, <<"running">>, Image, <<"with">>, <<"commands:">>, {docstring, Args}], State = #{dockerl_pid := Pid, containers := Containers}) ->
     InterpolatedImage = consul_proxy_utils:string_interpolate(Image, maps:get(os_env, State, []) ++ maps:get(test_env, State, []), []),
-    {async, Ref} = nkdocker:events(Pid),
-    {ok, #{<<"Id">> := Id}} = nkdocker:create(Pid, InterpolatedImage,
+    {ok, _} = dockerl:pull_image(Pid, Image),
+    {ok, Id} = dockerl:create_container(Pid, Image,
         #{
-            publish_all => true,
-            cmds => binary:split(Args, <<" ">>, [trim_all, global])
+            'Tty' => true,
+            'Cmd' => binary:split(Args, <<" ">>, [trim_all, global]),
+            'PublishAllPorts' => true
         }),
-    nkdocker_receive_status(Ref, Id, <<"create">>),
     lager:notice("Docker container ~s running ~s created: ~s", [Name, InterpolatedImage, Id]),
-    ok = nkdocker:start(Pid, Id),
-    nkdocker_receive_status(Ref, Id, <<"start">>),
-    lager:notice("Docker container ~s started", [Name]),
-    nkdocker:finish_async(Pid, Ref),
-    nkdocker_receive(Ref, {ok, user_stop}),
-    {ok, State#{nkdocker_ids => [{Name, Id} | Ids]}};
-
-given("$Name logs match $Pattern", State = #{nkdocker_pid := Pid, nkdocker_ids := Ids}) ->
-    Id = proplists:get_value(Name, Ids),
-    {async, Ref} = nkdocker:logs(Pid, Id, #{stdout=>true, follow=>true}),
-    {match, _Captured} = nkdocker_receive_match(Ref, Pattern),
-    nkdocker:finish_async(Pid, Ref),
-    nkdocker_receive(Ref, {ok, user_stop}),
+    ok = dockerl:start_container(Pid, Id),
+    lager:notice("Docker container ~s started", [Id]),
+    {ok, State#{containers => [{Name, Id} | Containers]}};
+
+given("$Name logs match $Pattern", State = #{dockerl_pid := Pid, containers := Containers}) ->
+    Id = proplists:get_value(Name, Containers),
+    {ok, Stream} = dockerl:container_logs(Pid, Id),
+    ok = match_logs(Stream, Pattern),
     {ok, State};
 
-given("consul_proxy is connected to $Name on port $Port", State = #{nkdocker_pid := Pid, nkdocker_ids := Ids}) ->
-    Id = proplists:get_value(Name, Ids),
-    {ok, Data} = nkdocker:inspect(Pid, Id),
-    NetworkSettings = maps:get(<<"NetworkSettings">>, Data),
-    IPAddress = maps:get(<<"IPAddress">>, NetworkSettings),
-    URL = binary_to_list(<<"http://", IPAddress/binary, ":", Port/binary>>),
+given("consul_proxy is connected to $Name port $Port", State = #{dockerl_pid := Pid, containers := Containers, applications := Applications}) ->
+    Id = proplists:get_value(Name, Containers),
+    {ok, Ports} = dockerl_utils:get_ports(Pid, Id),
+    [{_, IntPort}] = maps:get(Port, Ports),
+    BinPort = integer_to_binary(IntPort),
+    BinAddress = case os:type() of
+                     {unix, darwin} -> %% Todo: remove this hack once routing is fixed in Docker for Mac
+                         <<"127.0.0.1">>;
+                     _ ->
+                         {ok, Gateway} = dockerl_utils:get_gateway(Pid, Id),
+                         list_to_binary(inet:ntoa(Gateway))
+                 end,
+    URL = binary_to_list(<<"http://", BinAddress/binary, ":", BinPort/binary>>),
+    lager:notice("Consul URL: ~s", [URL]),
     ok = application:set_env(consul_proxy, consul_urls, URL, [{timeout, infinity}, {persistent, true}]),
     case application:ensure_all_started(consul_proxy) of
         {ok, Started} ->
             lager:notice("Started ~p applications: ~p on ~p~n", [erlang:length(Started), Started, node()]),
             {ok, HttpcPid} = inets:start(httpc, [{profile, consul_proxied}]),
             httpc:set_options([{proxy, {{"localhost", 8080}, []}}], consul_proxied),
-            {ok, State#{consul_proxied_httpc => HttpcPid}};
+            {ok, State#{consul_proxied_httpc => HttpcPid, applications => Applications ++ Started}};
         {error, Reason} ->
             lager:error("~p", [Reason]),
             {error, Reason}
     end;
 
-given("a UDP listener registered as $ServiceName", State) ->
-    {ok, Socket} = gen_udp:open(0, [binary, {ip, {127, 0, 0, 1}}, {active, false}]),
-    {ok, Port} = inet:port(Socket),
-    BinPort = integer_to_binary(Port),
-    Value = <<"{\"Name\":\"", ServiceName/binary, "\",\"Address\":\"127.0.0.1\",\"Port\":", BinPort/binary, "}">>,
+given("a UDP listener registered as $ServiceName", State = #{test_env := TestEnv}) ->
+    {ok, Socket} = gen_udp:open(0, [binary, {ip, {0, 0, 0, 0}}, {active, false}]),
+    {ok, IntPort} = inet:port(Socket),
+    BinPort = integer_to_binary(IntPort),
+    BinAddress = proplists:get_value(<<"ip_address">>, TestEnv),
+    Value = <<"{\"Name\":\"", ServiceName/binary, "\",\"Address\":\"", BinAddress/binary, "\",\"Port\":", BinPort/binary, "}">>,
     {ok, <<>>} = consul_client:http_put(<<"/v1/agent/service/register">>, Value),
-    lager:notice("UDP listener ~p started on ~p", [ServiceName, Port]),
+    lager:notice("UDP listener ~p started on ~p", [ServiceName, IntPort]),
     spawn(fun() -> udp_receive(Socket) end),
-    {ok, State#{test_env => [{<<ServiceName/binary, "_port">>, BinPort} | maps:get(test_env, State, [])]}};
+    {ok, State#{test_env => [{<<ServiceName/binary, "_port">>, BinPort} | TestEnv]}};
 
-given("an HTTP Server with root $Root and handlers $Handlers registered as $ServiceName", State) ->
+given("an HTTP Server with root $Root and handlers $Handlers registered as $ServiceName", State = #{test_env := TestEnv}) ->
     Modules = [binary_to_atom(Handler, utf8) || Handler <- binary:split(Handlers, <<",">>, [trim_all, global])],
     ServiceConfig = [
-        {bind_address, "localhost"},
+        {bind_address, "0.0.0.0"},
         {port, 0},
         {modules, [mod_esi, mod_dir, mod_get]},
         {erl_script_alias, {"/erl", Modules}},
@@ -124,7 +122,8 @@ given("an HTTP Server with root $Root and handlers $Handlers registered as $Serv
     {ok, Pid} = inets:start(httpd, ServiceConfig),
     Port = proplists:get_value(port, httpd:info(Pid)),
     BinPort = integer_to_binary(Port),
-    Value = <<"{\"Name\":\"", ServiceName/binary, "\",\"Address\":\"127.0.0.1\",\"Port\":", BinPort/binary, "}">>,
+    BinAddress = proplists:get_value(<<"ip_address">>, TestEnv),
+    Value = <<"{\"Name\":\"", ServiceName/binary, "\",\"Address\":\"", BinAddress/binary, "\",\"Port\":", BinPort/binary, "}">>,
     {ok, <<>>} = consul_client:http_put(<<"/v1/agent/service/register">>, Value),
     lager:notice("HTTP Server ~p started on ~p", [ServiceName, Port]),
     {ok, State#{test_env => [{<<ServiceName/binary, "_port">>, BinPort} | maps:get(test_env, State, [])]}};
@@ -171,91 +170,22 @@ then(Tokens, _State) ->
 %%===================================================================
 %% Internal functions
 %%===================================================================
-get_nkdocker_pid(State) ->
-    case maps:get(nkdocker_pid, State, undefined) of
-        undefined ->
-            {ok, Pid} = nkdocker:start_link(),
-            {ok, Version} = nkdocker:version(Pid),
-            lager:debug("Docker Version:~n~s", [io_lib_pretty:print(Version)]),
-            {Pid, State#{nkdocker_pid => Pid}};
-        Pid ->
-            {Pid, State}
-    end.
-
-nkdocker_receive(Ref, Data) ->
-    receive
-        {nkdocker, Ref, Data} ->
-            lager:debug("~p", [Data]),
-            ok;
-        Other ->
-            lager:debug("~p", [Other]),
-            nkdocker_receive(Ref, Data)
-    after
-        1000 ->
-            {error, timeout}
-    end.
-
-nkdocker_receive_status(Ref, Id, Status) ->
-    receive
-        {nkdocker, Ref, Data = {data, #{<<"id">>:=Id, <<"status">>:=Status}}} ->
-            lager:debug("~p", [Data]),
-            ok;
-        Other ->
-            lager:debug("~p", [Other]),
-            nkdocker_receive_status(Ref, Id, Status)
-    after
-        1000 ->
-            {error, timeout}
-    end.
-
-nkdocker_receive_data(Ref) ->
-    nkdocker_receive_data(Ref, <<>>, 3000).
-
-nkdocker_receive_data(Ref, Buffer, Timeout) ->
-    receive
-        {ok, <<>>} ->
-            {ok, Buffer};
-        {nkdocker, Ref, {data, Data}} when is_binary(Data) ->
-            lager:debug("~p", [Data]),
-            nkdocker_receive_data(Ref, <<Buffer/binary, Data/binary>>, Timeout);
-        {nkdocker, Ref, {data, Data}} ->
-            lager:debug("~p", [Data]),
-            nkdocker_receive_data(Ref, Buffer, Timeout);
-        Other ->
-            lager:debug("~p", [Other]),
-            nkdocker_receive_data(Ref, Buffer, Timeout)
-    after
-        Timeout ->
-            {error, timeout}
-    end.
 
-nkdocker_receive_match(Ref, RE) ->
-    nkdocker_receive_match(Ref, RE, 3000).
-
-nkdocker_receive_match(Ref, Regexp, Timeout) when is_binary(Regexp) ->
-    case re:compile(Regexp) of
-        {ok, MP} ->
-            nkdocker_receive_match(Ref, MP, Timeout);
-        {error, Reason} ->
-            {error, Reason}
-    end;
-nkdocker_receive_match(Ref, RE, Timeout) ->
+match_logs(Stream, Pattern) ->
     receive
-        {ok, <<>>} ->
-            nomatch;
-        {nkdocker, Ref, {data, Data}} when is_binary(Data) ->
-            lager:debug("~p", [Data]),
-            case re:run(Data, RE) of
-                nomatch ->
-                    nkdocker_receive_match(Ref, RE, Timeout);
-                Match ->
-                    Match
-            end;
-        Other ->
-            lager:debug("~p", [Other]),
-            nkdocker_receive_match(Ref, RE, Timeout)
+        done ->
+            {error, no_match};
+        Msg ->
+            case re:run(Msg, Pattern) of
+                {match, _} ->
+                    Stream ! stop,
+                    ok;
+                _ ->
+                    match_logs(Stream, Pattern)
+            end
     after
-        Timeout ->
+        10000 ->
+            Stream ! stop,
             {error, timeout}
     end.
 
@@ -267,3 +197,10 @@ udp_receive(Socket) ->
         {error, _Reason} ->
             udp_receive(Socket)
     end.
+
+local_ip_v4() ->
+    {ok, Addrs} = inet:getifaddrs(),
+    hd([
+        Addr || {_, Opts} <- Addrs, {addr, Addr} <- Opts,
+        size(Addr) == 4, Addr =/= {127, 0, 0, 1}
+    ]).
diff --git a/apps/consul_proxy/test/feature_consul_proxy.erl b/apps/consul_proxy/test/feature_consul_proxy.erl
index 9b8011b03b497b08e3b5f9148113f3511464fc0e..3ba9c3537d638a52749ab721ebaa0405b36515fb 100644
--- a/apps/consul_proxy/test/feature_consul_proxy.erl
+++ b/apps/consul_proxy/test/feature_consul_proxy.erl
@@ -37,12 +37,12 @@ given(Tokens, State) ->
 %% noinspection ErlangUnboundVariable
 'when'("the consul client lists nodes", State) ->
     {ok, Nodes} = consul_client:nodes(),
-    lager:notice("~p", [Nodes]),
+    lager:notice("Nodes: ~p", [Nodes]),
     {ok, State#{result => Nodes}};
 
 'when'("the consul client lists services", State) ->
     {ok, Services} = consul_client:services(),
-    lager:notice("~p", [Services]),
+    lager:notice("Services: ~p", [Services]),
     {ok, State#{result => Services}};
 
 'when'("a request is made to $URL", State) ->
diff --git a/apps/consul_proxy/test/features_test.erl b/apps/consul_proxy/test/features_test.erl
index db2280754b15d6bc7c5ba75da0982e0bf720ac34..4c458351d2af29abf3fb87c29086125deff38f43 100644
--- a/apps/consul_proxy/test/features_test.erl
+++ b/apps/consul_proxy/test/features_test.erl
@@ -11,6 +11,14 @@ features_test_() ->
     gurka_eunit:setup(Features, fun teardown/1).
 
 setup() ->
+    case file:consult("config/test-sys.config") of
+        {ok, [ConfigList]} ->
+            [application:set_env(Application, Key, Val, [{timeout, infinity}, {persistent, true}]) ||
+                {Application, Items} <- ConfigList,
+                {Key, Val} <- Items];
+        {error, Reason} ->
+            ?debugFmt("~p: ~p", ["config/test-sys.config", Reason])
+    end,
     lager:start().
 
 teardown(_) ->
diff --git a/config/test-sys.config b/config/test-sys.config
index 6628c229a499d00750b4cf0f3a6b3ea58989f8b4..6a4769863b6b063db5a30bbd7741018cc41ce895 100644
--- a/config/test-sys.config
+++ b/config/test-sys.config
@@ -30,7 +30,7 @@
         {crash_log_size, 10485760},
         {crash_log_date, "$D0"},
         {crash_log_count, 5},
-        {error_logger_redirect, false}
+        {error_logger_redirect, true}
     ]},
     {vegur, [
         {downstream_connect_timeout, 1000},
diff --git a/config/test-vm.args b/config/test-vm.args
deleted file mode 100644
index 1afe19d9c76a43e1a0ff07d4f3d3fdd86e9715a2..0000000000000000000000000000000000000000
--- a/config/test-vm.args
+++ /dev/null
@@ -1,16 +0,0 @@
-## Name of the node
--sname consul_proxy
-
-## Enable kernel poll and a few async threads
-+K true
-+A 64
-+P 262144
-
-## enable smp support
--smp auto
-
-## Increase number of concurrent ports/sockets
--env ERL_MAX_PORTS 16384
-
-## Tweak GC to run more often
--env ERL_FULLSWEEP_AFTER 10
diff --git a/features/consul_proxy.feature b/features/consul_proxy.feature
index e5f5ddc555ae24b62861911d5630a9c42f496f76..04d0bffa21c884e6abce5507500c0e5465e978f8 100644
--- a/features/consul_proxy.feature
+++ b/features/consul_proxy.feature
@@ -9,25 +9,25 @@ Feature: Proxy functionality
     agent -dev -ui-dir /ui -client 0.0.0.0
     """
     And consul logs match "Synced service 'consul'"
-    And consul_proxy is connected to consul on port 8500
+    And consul_proxy is connected to consul port 8500/tcp
     And a UDP listener registered as logstash
-    And an HTTP Server with root "test/www" and handlers "eunit_www" registered as eunit
+    And an HTTP Server with root "apps/consul_proxy/priv" and handlers "eunit_www" registered as eunit
     And consul client has set consul_proxy/watchers/kv to:
     """
     [
-        "http://localhost:$<eunit_port>/erl/eunit_www:info"
+        "http://$<ip_address>:$<eunit_port>/erl/eunit_www:info"
     ]
     """
     And consul client has set consul_proxy/watchers/services to:
     """
     [
-        "http://localhost:$<eunit_port>/erl/eunit_www:info"
+        "http://$<ip_address>:$<eunit_port>/erl/eunit_www:info"
     ]
     """
     And consul client has set consul_proxy/watchers/nodes to:
     """
     [
-        "http://localhost:$<eunit_port>/erl/eunit_www:info"
+        "http://$<ip_address>:$<eunit_port>/erl/eunit_www:info"
     ]
     """
     And consul client has set consul_proxy/domains/eunit to:
diff --git a/rebar.config b/rebar.config
index c67583ed812fab7002daaf570112102829337f47..1694dcb22758f7816c058f942e9fa9ac387b3a82 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,5 +1,10 @@
 {global_rebar_dir, ".rebar3"}.
 
+{plugins, [
+    {rebar_alias, "0.2.0"},
+    {rebar_cmd, "0.2.5"}
+]}.
+
 {erl_opts, [{parse_transform, lager_transform}, {lager_extra_sinks, [request_log, latency_log]}]}.
 
 {eunit_opts, [{report, {eunit_surefire, [{dir, "_build/test"}]}}]}.
@@ -7,25 +12,27 @@
 {edoc_opts, [{dir, "_build/edoc"}]}.
 
 {deps, [
-    {lager, {git, "https://github.com/basho/lager.git", {tag, "3.1.0"}}},
-    {tsuru, "1.4.0"},
+    {lager, "3.2.1"},
+    {tsuru, "1.4.1"},
     {msgpack, "0.4.0"},
     {jsx, "2.8.0"},
     {lru, "1.3.1"},
     {pbkdf2, "2.0.0"},
     {luerl, {git, "https://github.com/rvirding/luerl.git", {tag, "v0.3"}}},
-    {vegur, {git, "https://github.com/heroku/vegur.git", {tag, "v1.1.1"}}}
+    {vegur, {git, "https://github.com/heroku/vegur.git", {tag, "2.0.3"}}}
 ]}.
 
 {relx, [
-    {release, {consul_proxy, "0.5.3"}, [consul_proxy]}, {sys_config, "./config/sys.config"},
+    {release, {consul_proxy, "0.6.0"}, [consul_proxy]},
+    {sys_config, "./config/sys.config"},
     {vm_args, "./config/vm.args"},
     {dev_mode, true},
     {include_erts, false},
     {system_libs, false},
     {extended_start_script, true},
     {overlay, [
-        {copy, "apps/consul_proxy/priv/consul_proxy-wrapper", "bin/consul_proxy-wrapper"}
+        {template, "apps/consul_proxy/priv/wrapper", "bin/wrapper"},
+        {template, "apps/consul_proxy/priv/Dockerfile", "Dockerfile"}
     ]}
 ]}.
 
@@ -33,20 +40,56 @@
     {test, [
         {deps, [
             {gurka, "0.1.7"},
-            {gun, "1.0.0-pre.1"},
-            {cowlib, {git, "https://github.com/ninenines/cowlib.git", {tag, "1.3.0"}}},
-            {cowboy, ".*", {git, "https://github.com/extend/cowboy", {ref, "90ae31998e8d0887b9efe4b441136ac047708bb9"}}},
-            {nkpacket, {git, "https://github.com/NetComposer/nkpacket.git", {ref, "b2869f68060f779da56f63d0ff5e8c58a011d32c"}}},
-            {nkdocker, {git, "https://github.com/NetComposer/nkdocker.git", {ref, "f0fc3f866ecf9ded00c3eaaef2402afefc56f77f"}}}
+            {dockerl, {git, "https://gitlab.hedenstroem.com/erlang-ninja/dockerl.git", {tag, "0.1.0"}}}
         ]},
         {eunit_opts, [{report, {eunit_surefire, [{dir, "_build/test"}]}}]},
         {erl_opts, [debug_info, nowarn_unused_vars]}
     ]},
-    {production, [
+    {prod, [
+        {erl_opts, [no_debug_info, warnings_as_errors]},
         {relx, [
-            {dev_mode, false},
-            {include_erts, false}
+            {dev_mode, false}
         ]},
-        {erl_opts, [no_debug_info, warnings_as_errors]}
+        {commands, [
+            {docker, "docker build -t registry.hedenstroem.com/erlang-ninja/consul_proxy _build/prod/rel/consul_proxy"}
+        ]}
     ]}
 ]}.
+
+{dist_node, [
+    {setcookie, 'cookie'},
+    {sname, 'consul_proxy@localhost'}
+]}.
+
+{shell, [
+    {config, "config/test-sys.config"}
+]}.
+
+{dialyzer, [
+    {base_plt_location, global}
+]}.
+
+{alias, [
+    {test, [
+        {eunit, "--cover --application=consul_proxy --dir=apps/consul_proxy/test"},
+        {cover, "--verbose"}
+    ]},
+    {analyze, [
+        dialyzer,
+        xref
+    ]},
+    {cleanup, [
+        clean,
+        {cmd, "distclean"}
+    ]},
+    {docker, [
+        tar,
+        {cmd, "docker"}
+    ]}
+]}.
+
+{commands, [
+    {distclean, "rm -rf .rebar3 _build _checkouts/*/ebin ebin log"},
+    {sync, "git fetch upstream && git merge upstream/master"},
+    {docker, "docker build -t registry.hedenstroem.com/erlang-ninja/consul_proxy _build/default/rel/consul_proxy"}
+]}.
diff --git a/rebar.lock b/rebar.lock
index 5ab9781755b16f98011b5fe0d9dd1e1cdaf4e1a0..7a41e87cd8593e92c40d8bd1aa79b3bedf37c7db 100644
--- a/rebar.lock
+++ b/rebar.lock
@@ -1,6 +1,6 @@
 [{<<"cowboyku">>,
   {git,"https://github.com/heroku/cowboyku.git",
-       {ref,"ca64d29abe15c1522ba77283f15de20677aa5889"}},
+       {ref,"4acffec2be36d2ac66b79d4e9782de1213d1de4a"}},
   1},
  {<<"cowlib">>,
   {git,"https://github.com/ninenines/cowlib.git",
@@ -8,17 +8,11 @@
   1},
  {<<"erequest_id">>,
   {git,"https://github.com/heroku/erequest_id.git",
-       {ref,"e24f250c119e14975eff038ac30b2f9f7d1ceefa"}},
-  1},
- {<<"goldrush">>,
-  {git,"git://github.com/DeadZen/goldrush.git",
-       {ref,"212299233c7e7eb63a97be2777e1c05ebaa58dbe"}},
+       {ref,"6fae0c878f2dde809482915c8b207dc80882f7b3"}},
   1},
+ {<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.8">>},1},
  {<<"jsx">>,{pkg,<<"jsx">>,<<"2.8.0">>},0},
- {<<"lager">>,
-  {git,"https://github.com/basho/lager.git",
-       {ref,"b2cb2735713e3021e0761623ff595d53a545438e"}},
-  0},
+ {<<"lager">>,{pkg,<<"lager">>,<<"3.2.1">>},0},
  {<<"lru">>,{pkg,<<"lru">>,<<"1.3.1">>},0},
  {<<"luerl">>,
   {git,"https://github.com/rvirding/luerl.git",
@@ -32,7 +26,7 @@
  {<<"pbkdf2">>,{pkg,<<"pbkdf2">>,<<"2.0.0">>},0},
  {<<"quickrand">>,
   {git,"https://github.com/okeuday/quickrand.git",
-       {ref,"cf7ac11a820367496252243e49898480b25009f7"}},
+       {ref,"ad46bb697b98e8dcbf5c4a0af0099a5f1b2a0aa2"}},
   2},
  {<<"ranch">>,
   {git,"https://github.com/ninenines/ranch.git",
@@ -40,14 +34,14 @@
   1},
  {<<"ranch_proxy_protocol">>,
   {git,"https://github.com/heroku/ranch_proxy_protocol.git",
-       {ref,"5110e6ca4bc25dfb11d4ecf8d003169b95bf8969"}},
+       {ref,"0129227305a5b41f0875b337ac75f02f613f81c1"}},
   1},
- {<<"tsuru">>,{pkg,<<"tsuru">>,<<"1.4.0">>},0},
+ {<<"tsuru">>,{pkg,<<"tsuru">>,<<"1.4.1">>},0},
  {<<"uuid">>,
   {git,"https://github.com/okeuday/uuid.git",
-       {ref,"24325ae6309d03897735c3a320aab6f74b189ab7"}},
+       {ref,"4b705b22f5d095970558d904e43c4354bd0e0a7f"}},
   1},
  {<<"vegur">>,
   {git,"https://github.com/heroku/vegur.git",
-       {ref,"612d2de22bc6931dcc2bb0ae9c3e3187c4d77ca1"}},
+       {ref,"038542b071c8d1591f3f7843759271be3ed4a99b"}},
   0}].
diff --git a/scripts/consul-backup.go b/scripts/consul-backup.go
deleted file mode 100644
index 7c9cf0316b45e08c5cff82e5e69b3bec8d527729..0000000000000000000000000000000000000000
--- a/scripts/consul-backup.go
+++ /dev/null
@@ -1,173 +0,0 @@
-package main
-
-import (
-    "fmt"
-    "sort"
-    "os"
-    "io/ioutil"
-    "strings"
-    "github.com/hashicorp/consul/api"
-    "github.com/docopt/docopt-go"
-    "encoding/base64"
-)
-
-
-//type KVPair struct {
-//    Key         string
-//    CreateIndex uint64
-//    ModifyIndex uint64
-//    LockIndex   uint64
-//    Flags       uint64
-//    Value       []byte
-//    Session     string
-//}
-
-type ByCreateIndex api.KVPairs
-
-func (a ByCreateIndex) Len() int {
-    return len(a)
-}
-func (a ByCreateIndex) Swap(i, j int) {
-    a[i], a[j] = a[j], a[i]
-}
-//Sort the KVs by createIndex
-func (a ByCreateIndex) Less(i, j int) bool {
-    return a[i].CreateIndex < a[j].CreateIndex
-}
-
-func backup(ipaddress string, token string, outfile string) {
-
-    config := api.DefaultConfig()
-    config.Address = ipaddress
-    config.Token = token
-
-    client, _ := api.NewClient(config)
-    kv := client.KV()
-
-    pairs, _, err := kv.List("/", nil)
-    if err != nil {
-        panic(err)
-    }
-
-    sort.Sort(ByCreateIndex(pairs))
-
-    outstring := ""
-    for _, element := range pairs {
-        encoded_value := base64.StdEncoding.EncodeToString(element.Value)
-        outstring += fmt.Sprintf("%s:%s\n", element.Key, encoded_value)
-    }
-
-    file, err := os.Create(outfile)
-    if err != nil {
-        panic(err)
-    }
-
-    if _, err := file.Write([]byte(outstring)[:]); err != nil {
-        panic(err)
-    }
-}
-
-func backupAcls(ipaddress string, token string, outfile string) {
-
-    config := api.DefaultConfig()
-    config.Address = ipaddress
-    config.Token = token
-
-    client, _ := api.NewClient(config)
-    acl := client.ACL()
-
-    tokens, _, err := acl.List(nil)
-    if err != nil {
-        panic(err)
-    }
-    // sort.Sort(ByCreateIndex(tokens))
-
-    outstring := ""
-    for _, element := range tokens {
-        // outstring += fmt.Sprintf("%s:%s:%s:%s\n", element.ID, element.Name, element.Type, element.Rules)
-        outstring += fmt.Sprintf("====\nID: %s\nName: %s\nType: %s\nRules:\n%s\n", element.ID, element.Name, element.Type, element.Rules)
-    }
-
-    file, err := os.Create(outfile)
-    if err != nil {
-        panic(err)
-    }
-
-    if _, err := file.Write([]byte(outstring)[:]); err != nil {
-        panic(err)
-    }
-}
-
-/* File needs to be in the following format:
-    KEY1:VALUE1
-    KEY2:VALUE2
-*/
-func restore(ipaddress string, token string, infile string) {
-
-    config := api.DefaultConfig()
-    config.Address = ipaddress
-    config.Token = token
-
-    data, err := ioutil.ReadFile(infile)
-    if err != nil {
-        panic(err)
-    }
-
-    client, _ := api.NewClient(config)
-    kv := client.KV()
-
-    for _, element := range strings.Split(string(data), "\n") {
-        kvp := strings.Split(element, ":")
-
-        if len(kvp) > 1 {
-            decoded_value, decode_err := base64.StdEncoding.DecodeString(kvp[1])
-            if decode_err != nil {
-                panic(decode_err)
-            }
-
-            p := &api.KVPair{Key: kvp[0], Value: decoded_value}
-            _, err := kv.Put(p, nil)
-            if err != nil {
-                panic(err)
-            }
-        }
-    }
-}
-
-func main() {
-
-    usage := `Consul KV and ACL Backup with KV Restore tool.
-
-Usage:
-  consul-backup [-i IP:PORT] [-t TOKEN] [--aclbackup] [--aclbackupfile ACLBACKUPFILE] [--restore] <filename>
-  consul-backup -h | --help
-  consul-backup --version
-
-Options:
-  -h --help                          Show this screen.
-  --version                          Show version.
-  -i, --address=IP:PORT              The HTTP endpoint of Consul [default: 127.0.0.1:8500].
-  -t, --token=TOKEN                  An ACL Token with proper permissions in Consul [default: ].
-  -a, --aclbackup                    Backup ACLs, does nothing in restore mode. ACL restore not available at this time.
-  -b, --aclbackupfile=ACLBACKUPFILE  ACL Backup Filename [default: acl.bkp].
-  -r, --restore                      Activate restore mode`
-
-    arguments, _ := docopt.Parse(usage, nil, true, "consul-backup 1.0", false)
-    fmt.Println(arguments)
-
-    if arguments["--restore"] == true {
-        fmt.Println("Restore mode:")
-        fmt.Printf("Warning! This will overwrite existing kv. Press [enter] to continue; CTL-C to exit")
-        fmt.Scanln()
-        fmt.Println("Restoring KV from file: ", arguments["<filename>"].(string))
-        restore(arguments["--address"].(string), arguments["--token"].(string), arguments["<filename>"].(string))
-    } else {
-        fmt.Println("Backup mode:")
-        fmt.Println("KV store will be backed up to file: ", arguments["<filename>"].(string))
-        backup(arguments["--address"].(string), arguments["--token"].(string), arguments["<filename>"].(string))
-        if arguments["--aclbackup"] == true {
-            fmt.Println("ACL Tokens will be backed up to file: ", arguments["--aclbackupfile"].(string))
-            backupAcls(arguments["--address"].(string), arguments["--token"].(string), arguments["--aclbackupfile"].(string))
-        }
-    }
-}
diff --git a/scripts/genpasswd.escript b/scripts/genpasswd.escript
deleted file mode 100755
index 76f9f31729d78051f0aad4a064891f56cfd1cfa7..0000000000000000000000000000000000000000
--- a/scripts/genpasswd.escript
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env escript
-%%! -pa ../_build/default/lib/pbkdf2/ebin -Wall
-
--define(PBKDF2_SALT_LENGTH, 16).
--define(PBKDF2_ITERATIONS, 4096).
--define(PBKDF2_DERIVED_LENGTH, 32).
-
-main([Username, Password]) ->
-    try
-        Hash = base64:encode(hash(Password)),
-        io:format("~s:~s\n", [Username, Hash])
-    catch
-        _:_ ->
-            usage()
-    end;
-
-main(_) ->
-    usage().
-
-usage() ->
-    io:format("usage: genpasswd.escript username password\n"),
-    halt(1).
-
-hash(Password) when is_list(Password) ->
-    hash(list_to_binary(Password));
-
-hash(Password) ->
-    Salt = crypto:strong_rand_bytes(?PBKDF2_SALT_LENGTH),
-    {ok, Hash} = pbkdf2:pbkdf2(sha512, Password, Salt, ?PBKDF2_ITERATIONS, ?PBKDF2_DERIVED_LENGTH),
-    <<Salt/binary, Hash/binary>>.
diff --git a/scripts/genpasswd.go b/scripts/genpasswd.go
deleted file mode 100644
index d8d81576c33977364407ea4c9ddaebeaf5c94b39..0000000000000000000000000000000000000000
--- a/scripts/genpasswd.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package main
-
-import (
-    "os"
-    "fmt"
-    "flag"
-    "crypto/rand"
-    "crypto/sha512"
-    "encoding/base64"
-    "golang.org/x/crypto/pbkdf2"
-)
-
-func GenerateRandomBytes(n int) ([]byte, error) {
-    b := make([]byte, n)
-    _, err := rand.Read(b)
-    if err != nil {
-        return nil, err
-    }
-    return b, nil
-}
-
-func main() {
-
-    flag.Usage = func() {
-            fmt.Printf("Usage of %s:\n", os.Args[0])
-            fmt.Printf("    genpasswd username passwd\n")
-            flag.PrintDefaults()
-        }
-
-    flag.Parse()
-    if flag.NArg() == 0 {
-        flag.Usage()
-        os.Exit(1)
-    }
-
-    username := []byte(os.Args[1])
-    password := []byte(os.Args[2])
-    salt, err := GenerateRandomBytes(16)
-
-    if err != nil {
-        fmt.Printf("Failed to generate salt\n")
-        os.Exit(1)
-    }
-
-    hash := pbkdf2.Key(password, salt, 4096, 32, sha512.New)
-    output := base64.StdEncoding.EncodeToString(append(salt,hash...))
-
-    fmt.Printf("%s:%s\n", username, output)
-
-}
diff --git a/test/.gitignore b/test/.gitignore
deleted file mode 100644
index cdec5c9133b711fbc9b649f2f12f52ec2b4e16f4..0000000000000000000000000000000000000000
--- a/test/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-acme
diff --git a/test/boot2docker-route.sh b/test/boot2docker-route.sh
deleted file mode 100755
index f4ffdbc39f4f025fcdd153c9c2fe2408b2780a9a..0000000000000000000000000000000000000000
--- a/test/boot2docker-route.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env bash
-
-if [[ 'Running' != $(docker-machine status) ]]; then
-    echo "boot2docker's VM not running"
-    exit 1
-fi
-
-IP=$(docker-machine ip default 2> /dev/null)
-for NET in $(docker-machine ssh default route | awk '/docker0|br-/{print $1}'); do
-    case $1 in
-        "add" )
-            sudo route -n add "$NET" "$IP";;
-        "delete" )
-            sudo route -n delete "$NET" "$IP";;
-    esac
-done
-
-HOST_IP=$(docker-machine ssh default route | awk '/UG/{print $2}')
-
-echo "IP to host inside container: $HOST_IP"
-netstat -rn | awk "\$2 == \"$IP\"||/Destination.*Refs/{print;}"
diff --git a/test/defaults.consul b/test/defaults.consul
deleted file mode 100644
index e1eb12a355d30ed616b664223444453f65d38c43..0000000000000000000000000000000000000000
--- a/test/defaults.consul
+++ /dev/null
@@ -1,11 +0,0 @@
-consul_proxy/domains/test.service.docker:ewogICJTZXJ2aWNlTmFtZSIgOiAidGVzdCIKfQ==
-consul_proxy/domains/consul.service.docker:ewogICJTZXJ2aWNlTmFtZSIgOiAiY29uc3VsIgp9
-consul_proxy/domains/rewrite-example:ewogICJTZXJ2aWNlTmFtZSIgOiAiJDxzZXJ2aWNlPiIsCiAgIkFsaWFzZXMiIDogWwogICAgIig/PHNlcnZpY2U+LiopLXJld3JpdGVbLl1zZXJ2aWNlWy5dZG9ja2VyIgogIF0sCiAgIlJld3JpdGUiIDogWwogICAgWyJeL2FwaS8oLiopJCIsIi9pbmZvLnBocD9hcGk9JDEiXQogIF0KfQ==
-consul_proxy/scripts/resolver-example.erl:UmVxdWVzdCA9IHByb3BsaXN0czpnZXRfdmFsdWUocmVxdWVzdCwgUHJvcHMsIFtdKSwKTWV0YSA9IHByb3BsaXN0czpnZXRfdmFsdWUobWV0YSwgUmVxdWVzdCwgW10pLApDYXB0dXJlID0gcHJvcGxpc3RzOmdldF92YWx1ZShob3N0X2NhcHR1cmUsIE1ldGEsIFtdKSwKcHJvcGxpc3RzOmdldF92YWx1ZSg8PCJzZXJ2aWNlIj4+LCBDYXB0dXJlKS4=
-consul_proxy/watchers/nodes:WwogICAgImh0dHBzOi8vdGVzdC5zZXJ2aWNlLmRvY2tlci9pbmZvLnBocCIKXQ==
-consul_proxy/watchers/services:WwogICAgImh0dHBzOi8vdGVzdC5zZXJ2aWNlLmRvY2tlci9pbmZvLnBocCIKXQ==
-consul_proxy/watchers/kv:WwogICAgImh0dHBzOi8vdGVzdC5zZXJ2aWNlLmRvY2tlci9pbmZvLnBocCIKXQ==
-consul_proxy/hijackers:WwogIHsKICAgICJ1c2VybmFtZSIgOiAiaGlqYWNrZXIiLAogICAgInBhc3N3b3JkIiA6ICIwdEhWdFNhOThrSGkyZStkVHVWdHo3S3lYWTgzVys3cGZ6eEZYd2VKWUtualcxOXRSeHBVbFFSV1lYbGI4V21YIiwKICAgICJkb21haW5zIiA6IFsKICAgICAgIi4qIgogICAgXQogIH0KXQ==
-consul_proxy/domains/resolver-example-erl:ewogICJTZXJ2aWNlUmVzb2x2ZXIiIDogInJlc29sdmVyLWV4YW1wbGUuZXJsIiwKICAiQWxpYXNlcyIgOiBbCiAgICAiKD88c2VydmljZT4uKiktcmVzb2x2ZXItZXJsWy5dc2VydmljZVsuXWRvY2tlciIKICBdCn0=
-consul_proxy/domains/resolver-example-lua:ewogICJTZXJ2aWNlUmVzb2x2ZXIiIDogInJlc29sdmVyLWV4YW1wbGUubHVhIiwKICAiQWxpYXNlcyIgOiBbCiAgICAiKD88c2VydmljZT4uKiktcmVzb2x2ZXItbHVhWy5dc2VydmljZVsuXWRvY2tlciIKICBdCn0=
-consul_proxy/scripts/resolver-example.lua:cmV0dXJuIHByb3BzLnJlcXVlc3QubWV0YS5ob3N0X2NhcHR1cmUuc2VydmljZTs=
diff --git a/test/docker-compose.yml b/test/docker-compose.yml
deleted file mode 100644
index 34d7a45776cbb26481b4eec1ea6210c4ef184385..0000000000000000000000000000000000000000
--- a/test/docker-compose.yml
+++ /dev/null
@@ -1,77 +0,0 @@
-version: '2'
-
-services:
-
-  consul:
-    image: ehedenst/consul:x86
-    command: agent -dev -ui-dir /ui -client 0.0.0.0
-    environment:
-      - SERVICE_8300_IGNORE=true
-      - SERVICE_8301_IGNORE=true
-      - SERVICE_8302_IGNORE=true
-      - SERVICE_8400_IGNORE=true
-      - SERVICE_8500_NAME=consul
-      - SERVICE_8600_NAME=consul-dns
-    ports:
-      - "8500:8500"
-      - "8600:8600/udp"
-
-  registrator:
-    image: ehedenst/registrator:x86
-    command: -internal -ttl 600 -ttl-refresh 300 -resync 600 -cleanup consul://consul:8500/dc1
-    links:
-      - consul
-    environment:
-      - GODEBUG=netdns=cgo
-      - SERVICE_IGNORE=true
-    volumes:
-      - /var/run/docker.sock:/tmp/docker.sock
-
-  hitch:
-    image: ehedenst/hitch:x86
-    environment:
-      - SERVICE_402_NAME=acme-challenge
-      - SERVICE_443_NAME=hitch
-      - MODE=staging
-    ports:
-      - "443:443"
-    volumes:
-      - ./hitch:/var/lib/hitch
-      - ./acme:/var/lib/acme
-
-  logstash:
-    image: ehedenst/logstash:x86
-    ports:
-      - "5000/udp"
-    volumes:
-      - ./logstash:/opt/logstash/config
-
-  test-slow:
-    image: ehedenst/php5:x86
-    environment:
-      - SERVICE_NAME=test
-      - SERVICE_TAGS=php5,slow
-      - SIMULATED_DELAY=100
-      - SIMULATED_FAILURE_RATE=20
-    volumes:
-      - ./www:/var/www
-
-  test-medium:
-    image: ehedenst/php5:x86
-    environment:
-      - SERVICE_NAME=test
-      - SERVICE_TAGS=php5,medium
-      - SIMULATED_DELAY=10
-      - SIMULATED_FAILURE_RATE=10
-    volumes:
-      - ./www:/var/www
-
-  test-fast:
-    image: ehedenst/php5:x86
-    environment:
-      - SERVICE_NAME=test
-      - SERVICE_TAGS=php5,fast
-      - SIMULATED_DELAY=1
-      - SIMULATED_FAILURE_RATE=1
-    volumes:
-      - ./www:/var/www
diff --git a/test/hitch/certs/localhost.pem b/test/hitch/certs/localhost.pem
deleted file mode 100644
index aa5050e33006b93fcf18344c6f7b21f826990566..0000000000000000000000000000000000000000
--- a/test/hitch/certs/localhost.pem
+++ /dev/null
@@ -1,57 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDuDCCAqACCQD34vO1za/WdTANBgkqhkiG9w0BAQsFADCBozELMAkGA1UEBhMC
-U0UxEjAQBgNVBAgTCVN0b2NraG9sbTESMBAGA1UEBxMJU3RvY2tob2xtMR4wHAYD
-VQQKExVFcmlrJ3MgU2VsZi1TaWduZWQgQ0ExDDAKBgNVBAsTA0RldjEZMBcGA1UE
-AxQQRXJpayBIZWRlbnN0csO2bTEjMCEGCSqGSIb3DQEJARYUZXJpa0BoZWRlbnN0
-cm9lbS5jb20wHhcNMTYwMjA1MjEzNzQ1WhcNMjYwMjAyMjEzNzQ1WjCBlzEYMBYG
-A1UEChQPSGVkZW5zdHLDtm0uY29tMQwwCgYDVQQLEwNEZXYxJDAiBgkqhkiG9w0B
-CQEWFWFkbWluQGhlZGVuc3Ryb2VtLmNvbTESMBAGA1UEBxMJU3RvY2tob2xtMRIw
-EAYDVQQIEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMRIwEAYDVQQDEwlsb2NhbGhv
-c3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCyA3S6aIQ3e5GOa4kX
-SuAZRGLhHhEPy9IDxav39qunBuvcLBdhpKJvWV2FbpaSl+3YIAvOeFQH1vVcfATJ
-pub0Jvjq9XdFAopmUQ4SWzbyCeZWULw/L2u14iz+Tpi6S2vn34ehFm6o5SlC1JhI
-CZYAAkfo+AcawESF256+8ubfM5rIPmXg9ROs3SWFlEYR0++3raG6gNt9565DWkln
-GyLNQuuKyQIBgC9adc7MNMxMTe/hKLVje4yDIQX4/S9d1Abavw3xGSy4GKgccAeO
-CA3HTCGmo4PAbgQaZJfANMu8HP+8rlblDf8BUcdDCYwTFIBhyLQC4zTtC31YnRb4
-fbPNAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJALsYVe5TnBg+q5hAUyxjFcTfam
-dMFShOu6EWSrxPu1bkvwQBrmd0dFEtQEY/UDmm96jz0uzMplJrR//4zwVHI8IyfF
-i9iGyd2vvaBMv1xW8p6/ydPyVjHcFHcaB6/IZuHSWeQoAAWghim/vzDemWMCtC9l
-zvTQT+/4h+CUAL+oUAyVkIqCGZUDOaTfzGyrzaDYAeHIPa+OmZcNqfv5b8HpHDwM
-jYXdweOfFPoo7PvQKbTvVPr77SFAIxT3hsfk1k64ezqLTL1aJzr90grrG+Ejtg4w
-m1GAiisBsaWMgxWppAdhXO2iPGIltq9aDCSkDvcIeOwr9NiAYH0R6pFElSg=
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAsgN0umiEN3uRjmuJF0rgGURi4R4RD8vSA8Wr9/arpwbr3CwX
-YaSib1ldhW6Wkpft2CALznhUB9b1XHwEyabm9Cb46vV3RQKKZlEOEls28gnmVlC8
-Py9rteIs/k6Yuktr59+HoRZuqOUpQtSYSAmWAAJH6PgHGsBEhduevvLm3zOayD5l
-4PUTrN0lhZRGEdPvt62huoDbfeeuQ1pJZxsizULriskCAYAvWnXOzDTMTE3v4Si1
-Y3uMgyEF+P0vXdQG2r8N8RksuBioHHAHjggNx0whpqODwG4EGmSXwDTLvBz/vK5W
-5Q3/AVHHQwmMExSAYci0AuM07Qt9WJ0W+H2zzQIDAQABAoIBADDS/9YMyo7JJpAQ
-cIZh8/saJaCm9XkGpzB/q/4TutrR7Cj0MumGFUNDGIJ7ZXMJlqObjoFvwWRxEdTu
-8wU38MpwUf9nmfHkk38ipiBkwjo6euGbvTX7VKiLQ1nwxrT58LulNHb7Rxit2dZJ
-pwbDElAoT/7W4GP27hRkuzKWPrpi4JPBWPY13CO34hyqYzderPB/FZyen2mR0O1d
-bSSnqOeFLd8ku33dW0bXiqS8Iul2F3kSUGGsT9gBzI1d2Zs8EqpmOX7MfoIbsTqE
-eWfR5gIXRMPmdqUhdDnSdmM74ztoCX7PM7lbO6HBliOFPmv0O/Usdhpr3y3pmATr
-UVcViqECgYEA5n0wMv5GPoR87Oi8UhSZw4e7fBPrwxmqxSPtscfk3EnOWoEOc+aU
-c3tGNoOsdpYJtD+zasAY2ENVoHujBy1WTobVy1uwUn1yrbHR925XsJLhmkKHYw/s
-zTnhzYw+Mwv8JKwpw0l4NahAPJbC6Pn2gg+dppl0mhPDueTvUhTIavUCgYEAxbdl
-PFWPvMRljNFcZ8e1E6GySM3fbICIled2WuSSyJVI/qPN6kj+8b8Z7QTxciFouM0k
-NJPaFmLkU4OOU2mmGPef4wT7SMuhC7BkqzcKnjvf/7vLbLu53S1LQd5dasSBO5Wy
-+9KhjPKfaGQT6Gzkvemu0MG/P7BS1JsuadWqznkCgYEAwnqrKrvGhYXA6x1NmWxs
-ecGTfpRIgCyuHP292B40i3NzPIZcrYrHg9FmYyUjZkQfGAoP12kTDZdzLqBj5PBq
-PIQk7RwGYPQcyVabNc3TC9hDp6evGPUc9+V5E7jb2rKoJEFoU7EwTwYSfY0wFOil
-CQUoHqSo8EDxC2+SR43ltekCgYBGqTqXC4UpU49vektqE6eVco6DEoCtCGrIGEbm
-SRZkdWX3C5fGCXyD7WZYnRGlVmdU1IwB9m1U3tb3OecdzH4+IhGUUu1zoMLXqJzx
-y+QRlRiDDxyuqZDNiSiCS/Ra+gutvdyPv0FZXES4TDwJLxG5BdEibnvpSRzxOtyl
-mmVHEQKBgES8SCwlAimiUlPHKxBaK0iMiuxZC8pMqPQE+k0h5JExBNfLfQwtoks8
-LcsGsXzpkCYhyYprTEmTxhtiRXAsgU83Fb7XUMEruFPdADC7YXPj06ZS50V9Ec/K
-l9E98WWzbSe55My7zxT8hvqvmUY5DOkbllcgu0r61ATYXWpLd6ow
------END RSA PRIVATE KEY-----
------BEGIN DH PARAMETERS-----
-MIIBCAKCAQEAwjbh/sVLbivqHsPaDjbMSBijjMdV6e6RnS7KHzumCXJulgM0NV/g
-SEvbCJtqAfAnxgq8THO6hk0JY17IRX2td5y9deCbL//SR7jZRr9hg/QkIxorxQdF
-rQCQjfOXz98n9IlbkGNYCORErNFGtgyu4FEFFPbSMcwTuLChfFUEsxTgy2H7kF1p
-9R6mGrHyFMIOcQn4HGERmJM2Z13slYbE8+jcy9K2opEFzDB5JqOVwideZKngPuGo
-JMI5t36h0ac8E7OBmcdOR55Nid5DjxvwUtBus/q3jqNVb/XVKmzJC51JqAC8NeAO
-Zdt92vY64PPk/nzsUXClkCxPjLYwMumiCwIBAg==
------END DH PARAMETERS-----
diff --git a/test/hitch/certs/service.dc1.consul.pem b/test/hitch/certs/service.dc1.consul.pem
deleted file mode 100644
index 1952856fafacbaedb01f0bc93093f5eaa427a7d6..0000000000000000000000000000000000000000
--- a/test/hitch/certs/service.dc1.consul.pem
+++ /dev/null
@@ -1,58 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDwzCCAqsCCQD34vO1za/WdjANBgkqhkiG9w0BAQsFADCBozELMAkGA1UEBhMC
-U0UxEjAQBgNVBAgTCVN0b2NraG9sbTESMBAGA1UEBxMJU3RvY2tob2xtMR4wHAYD
-VQQKExVFcmlrJ3MgU2VsZi1TaWduZWQgQ0ExDDAKBgNVBAsTA0RldjEZMBcGA1UE
-AxQQRXJpayBIZWRlbnN0csO2bTEjMCEGCSqGSIb3DQEJARYUZXJpa0BoZWRlbnN0
-cm9lbS5jb20wHhcNMTYwMjI0MTIxODE3WhcNMjYwMjIxMTIxODE3WjCBojEYMBYG
-A1UEChQPSGVkZW5zdHLDtm0uY29tMQwwCgYDVQQLEwNEZXYxJDAiBgkqhkiG9w0B
-CQEWFWFkbWluQGhlZGVuc3Ryb2VtLmNvbTESMBAGA1UEBxMJU3RvY2tob2xtMRIw
-EAYDVQQIEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMR0wGwYDVQQDFBQqLnNlcnZp
-Y2UuZGMxLmNvbnN1bDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN9p
-2mHDSxhE9s03/6+TR21bO/nnY4V8aQGWyAMmgY1tLO6r0qEjsF7fGOnOddt0vBl0
-k2rOJ1ksmvIKTkhwlVVPrdjySoN5NV9P5XhCS37vjPaG1sjl3Uzfj/ItLjon6cJh
-nhVENIURsLEk0rRS1kflU4e3OgkzSFW3PMagnDM10dx1HrHxrmxxnkR/gxESsW4K
-0OW/9OLIRfpt4QMs5usD8lXyAEExwxaD6WG49Hk6ywtMZx9hJTahKBNc6NQyEXIb
-BbG/pzKvoBO7SAnvw/VqJy6QrGKkY6OPwdrP0MXGG43zhfn8OeEjM9viXpmcb1l7
-Y0/UGhXDgqQA9ymizr8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAkJTdFD9aStoP
-GOc7R0h1k13Gu0tuNdX+ktEQQgBreNvwnseSk9Zjl4UZ0i5fw5+J/4vj275tZ9Mu
-B0FwbD82PEmlQcGLDi1bQ5ncq6NbixVETeX+iA16HdUpA1iNJt28r0Z0iNd1CLqE
-ckFMy4CsrLmwkRh0BxHovYHfHckjtcpL4Jz8DB97sB9KyZgvNswll6habP3nCiFc
-w7x6XahrKdpwBVn36UdOk46Luku8UhDBhun9rNkAU57tFssBlT67yshCw0IrJrBn
-Sne7zdcFdsIc8k9O/TQyWCd9DxHYY/5o0oXus6QWM2n2RLw/f85d06nzrm/67ImR
-SqRd8MBXfQ==
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEA32naYcNLGET2zTf/r5NHbVs7+edjhXxpAZbIAyaBjW0s7qvS
-oSOwXt8Y6c5123S8GXSTas4nWSya8gpOSHCVVU+t2PJKg3k1X0/leEJLfu+M9obW
-yOXdTN+P8i0uOifpwmGeFUQ0hRGwsSTStFLWR+VTh7c6CTNIVbc8xqCcMzXR3HUe
-sfGubHGeRH+DERKxbgrQ5b/04shF+m3hAyzm6wPyVfIAQTHDFoPpYbj0eTrLC0xn
-H2ElNqEoE1zo1DIRchsFsb+nMq+gE7tICe/D9WonLpCsYqRjo4/B2s/QxcYbjfOF
-+fw54SMz2+JemZxvWXtjT9QaFcOCpAD3KaLOvwIDAQABAoIBAApJy5646ZpigqMM
-sx+Yvq9QhkCJ4VFiW0uRcACFI24p2unay8ZT6GlWCMWrlk3W4Fqjva4rdDBtF22R
-/+ziEl5tXuogrkHDsSuEeGLDWsqrqWgo6Xcy7q/9k5lpbzmKYP9sk2UTUP/XwrVF
-ptZbAjcpXmFflLKbw/b+izPybX8GI2S+fixjzHr1id2RVdFh5F3D3ooS9kbKJWQc
-VWMqfxpd0l67NA1Yn3IH9xFkkRzHDE5+prGiuTXZgPq9Dof5iNB69GSvtNsYSEjK
-NlFyXUnhwRhVB2RRvA1HhdnEf5k62EC+AteauVX1zXAxM2jHk5kezenqg5ks/DHp
-NPRf34ECgYEA/iPBDFz3EVMd/lTI4U9dEwT/ng2aprfYta2mbYozy5TmfHTeJ0fh
-/DkHlwfdhUgUYsTpi+UVqCR/aeyqSVqMj2SjegyTrjl81blViE1FDKuQ+LSgVF9C
-29h24ATVijtamBfzNQGvzuRYH18UucvS7ali6nO5tkgRiybF8tgss6ECgYEA4QyF
-AEY4zQuVYOchDcMXW5kIzDYsZp5C2IxrtrInkVa3GYsaDuAld5VvVcxmrFI3yggL
-N34Ivq0hVUmkbzUaVD8GJWCgDRf6WZ2JR/5uxIAMKbgFEHoKIT1OkKJf8u1JoKzx
-7m/EnoCu+CgYJ0Py3m04R0Lfu4nJQxOXEA86Zl8CgYBfjJHIVCuQF+/u73GXRH95
-5yc0BWlfxT91DxTDmnJe2FzP7iCYJC6S5d40qoBe2/rOJ7qnHjpGPXKqIJDlg2XV
-g8Dy4kej+Xk14biGxoZvfRHEcCTXk/lPLtOC5k5i6m3lQRvvkfLHlpKLOPRR5pAn
-Ssgl3dy06+Osrac+5ofoAQKBgB3nD/UNX5a/J0YM7/NoLL5bAzQ/Ln8kIDWt0tIf
-seo533JhbUD0v4W4MWbxFeNnuUn676Kb+IV9c6RleJfeMnVnOmXVBO84dGdb61XJ
-lOY/LV6NuP6LeLUZ9Ep7iMw6g0H6ONs5tqJo7tbCXRM6kBbF5Ghzlk7Q7BEhlTzp
-CRV5AoGAQ9xHxPNqFh5vA04ltV7VTHF+y2QW3dK6sIy9jb5dqkOAzv8980nU98Fj
-V6VViG/Y7O+TPWU5iJom5y62ixUoGES44+hSYuc2sVsqvavl8aHaqrLWbRur+WHb
-qz8czi8gnSeFT5sz4x7SMpFkJzCHdqFhQ03SRGcMvCbLpoAIb4Y=
------END RSA PRIVATE KEY-----
------BEGIN DH PARAMETERS-----
-MIIBCAKCAQEA56b6LH9zRQI6s+3Vy3Z1YmL8jZpvxpPgvtIuyNAcAufMIHwglyzW
-04YEZW96llnhGDEnIO3ldifmn24iKCtr3nR86P+zUiTK6VB0onjT31AaSAaP84Ff
-1SUU6KRkta9SbJqKWX8SewILiuEVcrCnM12EWh+PDvUDcUQMqQtdhNx4lNBGSqLu
-az6YsExuhWrmNAxeX/RkDcfS2+61GkDZd+97qaL/QMKAEznVeCVlSuigynGVf7AY
-IQgX+s6X6M9lBk+lLiZNAsFcdWaDF6gPNC3pRyj0aA2stmXxNugZGdIcbCh9SQzO
-dej+srAW4Uzb4xYfj84jrF3JKkgdV26u6wIBAg==
------END DH PARAMETERS-----
diff --git a/test/hitch/certs/service.docker.pem b/test/hitch/certs/service.docker.pem
deleted file mode 100644
index f08e6102ca77000ab6bd16ec6296a446a44194b0..0000000000000000000000000000000000000000
--- a/test/hitch/certs/service.docker.pem
+++ /dev/null
@@ -1,58 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDvzCCAqcCCQD34vO1za/WeDANBgkqhkiG9w0BAQsFADCBozELMAkGA1UEBhMC
-U0UxEjAQBgNVBAgTCVN0b2NraG9sbTESMBAGA1UEBxMJU3RvY2tob2xtMR4wHAYD
-VQQKExVFcmlrJ3MgU2VsZi1TaWduZWQgQ0ExDDAKBgNVBAsTA0RldjEZMBcGA1UE
-AxQQRXJpayBIZWRlbnN0csO2bTEjMCEGCSqGSIb3DQEJARYUZXJpa0BoZWRlbnN0
-cm9lbS5jb20wHhcNMTYwMzExMDgzNTMyWhcNMjYwMzA5MDgzNTMyWjCBnjEYMBYG
-A1UEChQPSGVkZW5zdHLDtm0uY29tMQwwCgYDVQQLEwNEZXYxJDAiBgkqhkiG9w0B
-CQEWFWFkbWluQGhlZGVuc3Ryb2VtLmNvbTESMBAGA1UEBxMJU3RvY2tob2xtMRIw
-EAYDVQQIEwlTdG9ja2hvbG0xCzAJBgNVBAYTAlNFMRkwFwYDVQQDFBAqLnNlcnZp
-Y2UuZG9ja2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4kqNxlr3
-qBvHERxyuyH0jgfMB0hY6xyfKhQAuUqFAwTi9gYBlknhbOiLT5nB6M18PgiAn+E5
-OaOL8Tv3gAf+qtpuKGvA5XzR37GBFwK6SYfdiv8pjEzOj64PFfQMj46k6EO/tjdD
-oEgUBvkCwreChJgyZPdPfhTTKGYe+zMwe6wn+poP6wfchXLMn6TUXOFrb9gIYY8i
-6J2UP/PrIq35FZ18dDllBCvHLp5x0AEv/r9bBuwctcAQrLgK5KObag9d2CizX1ks
-tW2afgDJ9WnYpp+d4ZBNUQs/whhcejVYGAekLnm2ZkWYUmQGMlrm5PMGKMFGSvH3
-2Lx0C+iWCDAhZQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBqgQiUUjBriUynmGpD
-E/CIZCJvsJj46TAHe4W8pVpkWAdtxWLZ9xcQ37CRMPezDsO4u3aK9LGoY1k6ZidH
-bnu76Iay2ebyyzIHfTo73J6HlElnmk0YnAvTJgAzKAIsxJR0zg6lx0iiyRnjJgWp
-0U1XibBqVO2qEanFCE3ReTR1jqcwJmM7/gEEdoW/DMrYF+TiwF60vX4W4Hq2DrGP
-ofcPS2RXWWEvt9ekODJOzmt+bPg3WuJiFBzFYoV8VLzOi4sM/dIMIQto1zvnjVXC
-v/WLyllL4ZnV6CK7G3Y/zEjqpdNbTsAuJzhDcDrMW3/bKZ2gVPcLg8H7I9+Izk+x
-R0Ue
------END CERTIFICATE-----
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA4kqNxlr3qBvHERxyuyH0jgfMB0hY6xyfKhQAuUqFAwTi9gYB
-lknhbOiLT5nB6M18PgiAn+E5OaOL8Tv3gAf+qtpuKGvA5XzR37GBFwK6SYfdiv8p
-jEzOj64PFfQMj46k6EO/tjdDoEgUBvkCwreChJgyZPdPfhTTKGYe+zMwe6wn+poP
-6wfchXLMn6TUXOFrb9gIYY8i6J2UP/PrIq35FZ18dDllBCvHLp5x0AEv/r9bBuwc
-tcAQrLgK5KObag9d2CizX1kstW2afgDJ9WnYpp+d4ZBNUQs/whhcejVYGAekLnm2
-ZkWYUmQGMlrm5PMGKMFGSvH32Lx0C+iWCDAhZQIDAQABAoIBAQCKXDlZaa95WxqZ
-TMKdxsInwX6viT3M66Ap8zcKFBVF5kv7T2rTAHNTys+7KPEWLeXkbABxQR1jL6tW
-IWtQHhNJVer6zf+QkYQlePvMHP/YC7mazi8SOLgnw643pxOzBu2vkhT7DclMjCWq
-qcBVXCzyc7iEYW56UbNWRTJ2NzNSuacGQhy5kwC0WBi7jp1bkB2wyiQFDuD8CzLi
-6qEX/9+JFztJrmVaDtQFMl0l68zQ4NlDDmatk+9uokq6DXedscGNWgKH0l2UwNld
-WbgBQOCoiFXJjUYSi0Yi8IweuI3v+eUir7aRMmvpYLbIVeK9uK1ZXJoDPIf8NuX8
-ocoIHUBVAoGBAPXtnYRckwDFquAF0/KBM9z7gpJ5YJMYEyrp/raqpBzCweJt8Vve
-P+cHY1t2NCO88496rZLEoLiADF3qYQSxIm58ghvwrpO7ngm0foeNlVWPHmvEoF4q
-zjVoDZtktlBMnuoae8S0GX45zI4uqAymQ36at4WGVvh9sbeM2XfAPk4PAoGBAOuP
-DwpZCunYwWhEspZ4hd5VG21dMn2TUseKztQFjCxQ+YLNZHPI5RwItA3sHUjk0vS1
-6Cp1BM/wZtkts0sRGxdrrSJfuvm7N+XlRf4uZzjKAP4SXRY63yERhRwGW29dN/Lg
-PqqAVz5t/cT3LdIqbK88C92BVfXQBoMahasc/41LAoGBAMdcC1AMV6LNmpqmPs2c
-jXV7cbrZqD81yfwE2lYr+IPUIaYzp+/oN/dJ1vKC3PuHpg3OzjxnJz7JlrzfTiym
-h5n3VuXdczgRZKjLZ7LtRHyqW2fTaolLvAQxSK6KsvxfUIfIVkL8GJppsngkPFic
-w6QzOciFQaWJB3MbPANGlXtjAoGAVS5XXwOSCbwjPGRTPEx7BEo8b9Da2EQ1FAli
-/5K9/KyPfbhuUdxc1UVkbwBqGpj8nBdHzEqiodsqJfD7u/KEnHSImDyL7ZDBBvZg
-2CjJlOSfdUEIvmgtldSzEM5PtDa+a6qhnqBobB/0O4yy2iQTR07sb348qnY+VJx7
-p8QFuX8CgYA+TaFn70Nhr4l7RxjtbP7v0vH+HodHRr3TzR4WAiBiLKjYIGiH5es6
-8xRYFn0yoaZGKTahTy9phwY+9z6mhrDd6ATWQ7zBuhZf0VvZUcR5dULb2O35NwSM
-HgsQc+fIp1JwFQ62BvxEpxxr1uYCBY0hFUdUq9y6Bc6QRY5pkhNdSg==
------END RSA PRIVATE KEY-----
------BEGIN DH PARAMETERS-----
-MIIBCAKCAQEAnPMKREqaIMGAf0Ctj6LDl+dSuUJQZWgcR2EcJq5r7eQpgPXrp1Nu
-zX95VvkhX8uqYULeS1gDL2EsYwVx9B4/DXCpRDeb/UZU6G9l3edGlaT/yGd8p59z
-PuSrwm7Lbz+qUc+VlHA/1CzdE17f5zgJe/4BGmrRRXTc+kpc3qkQZOtMNxy22iUU
-woZs4/uPsRrideqVzRBgY9f++/7FFT2UNYYDq7MVPN7cMS+abeaeHQupNL4QOsb1
-hBKXZxPGtD6WZ/6PFsA5ebPsh9y4nuvhE1xNsA1Waxts31q2T91m5P7c+AZc8ubp
-XPNqizO/8ESTyvnYQcjViw/KG7Jl3eJvowIBAg==
------END DH PARAMETERS-----
diff --git a/test/hitch/conf/hitch.conf b/test/hitch/conf/hitch.conf
deleted file mode 100644
index 42c7914a6d62a1114cbfe08abecbbf2de6b42e5d..0000000000000000000000000000000000000000
--- a/test/hitch/conf/hitch.conf
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# Example configuration file for hitch(8).
-#
-# NOTE: all config file parameters can be overriden
-#       from command line!
-
-# Listening address. REQUIRED.
-# Can be specified multiple times for multiple listen endpoints.
-# type: string
-# syntax: [HOST]:PORT[+CERT]
-frontend = "[*]:443"
-
-# Upstream server address. REQUIRED.
-#
-# type: string
-# syntax: [HOST]:PORT.
-backend = "[10.0.2.2]:8081"
-
-# SSL x509 certificate file. REQUIRED.
-# List multiple certs to use SNI. Certs are used in the order they
-# are listed; the last cert listed will be used if none of the others match
-#
-# type: string
-pem-file = ""
-
-# SSL protocol.
-#
-# tls = on
-# ssl = off
-
-# List of allowed SSL ciphers.
-#
-# Run openssl ciphers for list of available ciphers.
-# type: string
-ciphers = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
-
-# Enforce server cipher list order
-#
-# type: boolean
-prefer-server-ciphers = off
-
-# Use specified SSL engine
-#
-# type: string
-ssl-engine = ""
-
-# Number of worker processes
-#
-# type: integer
-workers = 4
-
-# Listen backlog size
-#
-# type: integer
-backlog = 100
-
-# TCP socket keepalive interval in seconds
-#
-# type: integer
-keepalive = 3600
-
-# Chroot directory
-#
-# type: string
-chroot = ""
-
-# Set uid after binding a socket
-#
-# type: string
-user = "hitch"
-
-# Set gid after binding a socket
-#
-# type: string
-group = "nogroup"
-
-# Quiet execution, report only error messages
-#
-# type: boolean
-quiet = off
-
-# Use syslog for logging
-#
-# type: boolean
-syslog = off
-
-# Syslog facility to use
-#
-# type: string
-syslog-facility = "daemon"
-
-# Run as daemon
-#
-# type: boolean
-daemon = off
-
-# Report client address by writing IP before sending data
-#
-# NOTE: This option is mutually exclusive with option write-proxy-v2, write-proxy and proxy-proxy.
-#
-# type: boolean
-write-ip = off
-
-# Report client address using SENDPROXY protocol, see
-# http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
-# for details.
-#
-# NOTE: This option is mutually exclusive with option write-proxy-v2, write-ip and proxy-proxy.
-#
-# type: boolean
-write-proxy-v1 = on
-
-# Report client address using SENDPROXY v2 binary protocol, see
-# http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
-# for details.
-#
-# NOTE: This option is mutually exclusive with option write-ip, write-proxy-v1 and proxy-proxy.
-#
-# type: boolean
-write-proxy-v2 = off
-
-# Proxy an existing SENDPROXY protocol header through this request.
-#
-# NOTE: This option is mutually exclusive with option write-proxy-v2, write-ip and write-proxy-v1.
-#
-# type: boolean
-proxy-proxy = off
-
-# Abort handshake when the client submits an unrecognized SNI server name.
-#
-# type: boolean
-sni-nomatch-abort = on
-
-# EOF
diff --git a/test/logstash/logstash.conf b/test/logstash/logstash.conf
deleted file mode 100644
index 31616602a5befb9099f2ef7a21ae2a2f7deb2020..0000000000000000000000000000000000000000
--- a/test/logstash/logstash.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-input {
-  udp {
-    port => 5000
-    codec => msgpack
-    type => "consul_proxy"
-  }
-}
-output {
-  stdout { codec => rubydebug }
-}
diff --git a/test/www/index.html b/test/www/index.html
deleted file mode 100644
index 7808a81ff747bad161df23f0c3b973b64e9168e7..0000000000000000000000000000000000000000
--- a/test/www/index.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <title></title>
-</head>
-<body>
-<h1>Hello World</h1>
-</body>
-</html>
diff --git a/test/www/index.php b/test/www/index.php
deleted file mode 100644
index 73f78e936b02bff0155d001ed80a00a65072371b..0000000000000000000000000000000000000000
--- a/test/www/index.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-$tags = getenv('SERVICE_TAGS');
-
-$delay = intval(getenv('SIMULATED_DELAY'));
-if ($delay > 0) {
-    usleep(1000 *$delay);
-}
-$failure_rate = intval(getenv('SIMULATED_FAILURE_RATE'));
-if ($failure_rate != 0 && rand(0, 100) < $failure_rate) {
-    header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
-    echo "<h1>$tags</h1><p>error, delay $delay msec.</p>";
-} else {
-    echo "<h1>$tags</h1><p>ok, delay $delay msec.</p>";
-}
diff --git a/test/www/info.php b/test/www/info.php
deleted file mode 100644
index 61ace196d4129411be0800919d883e132b0bf075..0000000000000000000000000000000000000000
--- a/test/www/info.php
+++ /dev/null
@@ -1,2 +0,0 @@
-<?php
-phpinfo();