diff --git a/advanced_examples/minikube-simple/.gitignore b/advanced_examples/minikube-simple/.gitignore new file mode 100644 index 0000000..172c657 --- /dev/null +++ b/advanced_examples/minikube-simple/.gitignore @@ -0,0 +1,2 @@ +_build/ +rebar.lock diff --git a/advanced_examples/minikube-simple/.travis.yml b/advanced_examples/minikube-simple/.travis.yml new file mode 100644 index 0000000..7848113 --- /dev/null +++ b/advanced_examples/minikube-simple/.travis.yml @@ -0,0 +1,48 @@ +sudo: required + +dist: xenial + +addons: + apt: + packages: + - curl + +env: +- CHANGE_MINIKUBE_NONE_USER=true + +before_script: +# Download minikube. +- MINIKUBE_VERSION=latest +- curl -Lo minikube https://storage.googleapis.com/minikube/releases/$MINIKUBE_VERSION/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/ +# Download kubectl, which is a requirement for using minikube. +- KUBERNETES_VERSION=$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt) +- curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/$KUBERNETES_VERSION/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/ +# Test that it works +- kubectl -h +- sudo minikube start -v 7 --logtostderr --vm-driver=none --kubernetes-version "$KUBERNETES_VERSION" +# Fix the kubectl context, as it's often stale. +- minikube update-context +# Wait for Kubernetes to be up and ready. +- JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1; done + +script: +- kubectl cluster-info +# kube-addon-manager is responsible for managing other kubernetes components, such as kube-dns, dashboard, storage-provisioner.. +- JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl -n kube-system get pods -lcomponent=kube-addon-manager -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 5;echo "waiting for kube-addon-manager to be available"; kubectl get pods --all-namespaces; done +# Wait for kube-dns to be ready. +- JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl -n kube-system get pods -lk8s-app=kube-dns -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 5;echo "waiting for kube-dns to be available"; kubectl get pods --all-namespaces; done +- kubectl create service nodeport dockerwatch --tcp=8080:8080 --tcp=8443:8443 +- kubectl get service +- ./create-certs $(minikube ip) +- kubectl create secret generic dockerwatch --from-file=ssl/ +- kubectl get secret +- docker build -t dockerwatch . +- kubectl apply -f dockerwatch-deploy.yaml +# Wait for dockerwatch to be ready. +- JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl -n default get pods -lapp=dockerwatch -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 5;echo "waiting for dockerwatch to be available"; kubectl get pods --all-namespaces; done +- HTTP=$(minikube service dockerwatch --url | head -1) +- HTTPS=$(minikube service dockerwatch --url --https | tail -1) +- "curl -v -H 'Content-Type: application/json' -X POST -d '' $HTTP/cnt" +- "curl -v -H 'Content-Type: application/json' -X POST -d '{}' $HTTP/cnt" +- "curl -v --cacert ssl/dockerwatch-ca.pem -H 'Accept: application/json' $HTTPS/" +- "curl -v --cacert ssl/dockerwatch-ca.pem -H 'Accept: application/json' $HTTPS/cnt" diff --git a/advanced_examples/minikube-simple/Docker-Cheat-Sheet.md b/advanced_examples/minikube-simple/Docker-Cheat-Sheet.md new file mode 100644 index 0000000..9d58795 --- /dev/null +++ b/advanced_examples/minikube-simple/Docker-Cheat-Sheet.md @@ -0,0 +1,26 @@ +## Docker Cheatsheet + +* Remove all containers that are not running: + + $ docker rm $(docker ps -aq -f status=exited) + +* Remove dangling images: + + $ docker rmi $(docker images -f dangling=true -q) + +* Attach to running docker: + + $ docker exec -i -t NameOrId /bin/sh + +## Core generation + + * `/proc/sys/core_pattern` is clearly persisted on the host. Taking note of + its content before starting any endeavour is therefore highly encouraged. + * dockers `--privileged` is necessary for a gdb session to catch the stack, + without privileges, gdb just complains about No stack. Google still is + hardly knowledgeable about this phenomenon... + * setting ulimit on docker run works perfectly, for future googlers (syntax hard to find), + a docker-compose example: + + ulimits: + core: -1 diff --git a/advanced_examples/minikube-simple/Dockerfile b/advanced_examples/minikube-simple/Dockerfile new file mode 100644 index 0000000..e2f1c7e --- /dev/null +++ b/advanced_examples/minikube-simple/Dockerfile @@ -0,0 +1,37 @@ +# Build stage 0 +FROM erlang:alpine + +# Install Rebar3 +RUN mkdir -p /buildroot/rebar3/bin +ADD https://s3.amazonaws.com/rebar3/rebar3 /buildroot/rebar3/bin/rebar3 +RUN chmod a+x /buildroot/rebar3/bin/rebar3 + +# Setup Environment +ENV PATH=/buildroot/rebar3/bin:$PATH + +# Reset working directory +WORKDIR /buildroot + +# Copy our Erlang test application +COPY dockerwatch dockerwatch + +# And build the release +WORKDIR dockerwatch +RUN rebar3 as prod release + + +# Build stage 1 +FROM alpine + +# Install some libs +RUN apk add --no-cache openssl && \ + apk add --no-cache ncurses-libs + +# Install the released application +COPY --from=0 /buildroot/dockerwatch/_build/prod/rel/dockerwatch /dockerwatch + +# Expose relevant ports +EXPOSE 8080 +EXPOSE 8443 + +CMD ["/dockerwatch/bin/dockerwatch", "foreground"] diff --git a/advanced_examples/minikube-simple/README-CERTS.md b/advanced_examples/minikube-simple/README-CERTS.md new file mode 100644 index 0000000..10b9565 --- /dev/null +++ b/advanced_examples/minikube-simple/README-CERTS.md @@ -0,0 +1,23 @@ +## Generating Certificate + +Generate certificates in subdirectory `ssl`. + +### Root CA + + $ openssl genrsa -out dockerwatch-ca.key 4096 + + $ openssl req -x509 -new -nodes -key dockerwatch-ca.key -sha256 -days 1024 -out dockerwatch-ca.pem + +### Server Certificate + + $ openssl genrsa -out dockerwatch-server.key 4096 + +Certificate signing request + + $ openssl req -new -key dockerwatch-server.key -out dockerwatch-server.csr + +The most important field: `Common Name (eg, YOUR name) []: localhost`. We use localhost in this example. + +### Sign it + + $ openssl x509 -req -in dockerwatch-server.csr -CA dockerwatch-ca.pem -CAkey dockerwatch-ca.key -CAcreateserial -out dockerwatch-server.pem -days 500 -sha256 diff --git a/advanced_examples/minikube-simple/README.md b/advanced_examples/minikube-simple/README.md new file mode 100644 index 0000000..b06b957 --- /dev/null +++ b/advanced_examples/minikube-simple/README.md @@ -0,0 +1,206 @@ +# Using Minikube and Erlang + +This is a quick demo of using minikube to run an Erlang node. The example we will +use is the [Docker Watch](http://github.com/erlang/docker-erlang-example/tree/master) +node. + +This is only meant to be an example of how to get started. It is not the only, +nor neccesarily the best way to setup minikube with Erlang. + +# Other Demos + +* [Using Docker](http://github.com/erlang/docker-erlang-example/) +* [Using Docker: Logstash](http://github.com/erlang/docker-erlang-example/tree/logstash) +* [Using Docker Compose: Logstash/ElasticSearch/Kibana](http://github.com/erlang/docker-erlang-example/tree/elk) +* [Using Minikube: Simple](http://github.com/erlang/docker-erlang-example/tree/minikube-simple) +* [Using Minikube: Prometheus/Grafana](http://github.com/erlang/docker-erlang-example/tree/minikube-prom-graf) +* [Using Minikube: Distributed Erlang](http://github.com/erlang/docker-erlang-example/tree/minikube-dist) +* [Using Minikube: Encrypted Distributed Erlang](http://github.com/erlang/docker-erlang-example/tree/minikube-tls-dist) + +# Prerequisites + +To start with you should familiarize yourself with minikube through this guide: +https://kubernetes.io/docs/setup/minikube/ + +In a nutshell: + +## Install + + * [VirtualBox](https://www.virtualbox.org/wiki/Downloads) + * [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) + * [minikube](https://github.com/kubernetes/minikube/releases) + +## Start and test + + > minikube start + > kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.10 --port=8080 + > kubectl expose deployment hello-minikube --type=NodePort + > curl $(minikube service hello-minikube --url) + ## Should print a lot of text + > kubectl delete services hello-minikube + > kubectl delete deployment hello-minikube + > minikube stop + +# Deploying Dockerwatch + +In this demo we will be doing three things: + +* Create a Service that will be used to access the dockerwatch API +* Create a Secret for our ssl keys +* Create a Deployment of dockerwatch that implements the Service + +First however, make sure that the minikube cluster is started: + + > minikube start + +and that you have cloned this repo and checked out this branch: + + > git clone https://github.com/erlang/docker-erlang-example + > cd docker-erlang-example + > git checkout minikube-simple + +## Create a Service + +The Service is what will be used to connect to the dockerwatch application +from outside the kubernetes cluster. It is not stricly neccesary to create the +Service before the deployment is done. However, it is considered good practice +to do so, as otherwise environment variables about the Service will not be +available in the Pods. + + > kubectl create service nodeport dockerwatch --tcp=8080:8080 --tcp=8443:8443 + service/dockerwatch created + +Check that it was created: + + > kubectl get service + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + dockerwatch NodePort 10.103.32.142 8080:31716/TCP,8443:30383/TCP 21m + kubernetes ClusterIP 10.96.0.1 443/TCP 1h + +We can see the external IP and port used through the minikube API: + + > minikube service dockerwatch --url + http://192.168.99.101:31716 + http://192.168.99.101:30383 + +Take a note of the IP addresses you get as we will need them when creating the +ssl certifcates. + +## Create a Secret + +We then need to create a new Secret that will be used to store the ssl private key +and the certificate. The Secret will then be mounted into the running Pod just +as was done in the original example. We start by generating the CA and the +server certificate: + + > ./create-certs $(minikube ip) + +Note that I put the IP address we got from `minikube service dockerwatch` above +as an argument. This is needed in order for SNI to work properly and in extension +to be able to connect to the service. The command will put a some files into +the ssl folder. We then use the `kubectl` command to create a Secret with those files. + + > kubectl create secret generic dockerwatch --from-file=ssl/ + secret/dockerwatch created + +We can then see that the secret has been created using: + + > kubectl get secrets + NAME TYPE DATA AGE + dockerwatch Opaque 6 16s + +## Deploy dockerwatch + +Now that we have our Secret and Service configured we are ready to create the +dockerwatch Deployment. First we need to build the docker image just as in the +docker example. However to make things simple we will build the docker image +inside the kubernetes cluster. This is not really recommended, but it +simplifies things for these examples. In a realworld scenario you probably want +to setup your own docker registry. + +So, to start with we need to setup our shell to contect the minikube docker +server instead of our local one. This is done through the `minikube` command: + + > eval $(minikube docker-env) + +Then we can use `docker` as normal to build the image: + + > docker build -t dockerwatch . + +Then the only thing that remains is to create the deployment. + +``` +cat < minikube service dockerwatch --url + http://192.168.99.101:31716 + http://192.168.99.101:30383 + +The IP:Port pairs above are the external ports exposed to access our dockerwatch +service. So to work with the content we use the same REST API as in dockerwatch: + + > curl -H "Content-Type: application/json" -X POST -d "" http://192.168.99.101:31716/cnt + > curl --cacert ssl/dockerwatch-ca.pem -H "Accept: application/json" https://192.168.99.101:30383 + ["cnt"] + +## Further exploration + +Minikube comes with the kubernetes dashboard, so we can easily look through a +web interface to look and change whatever we want. You access it by running: + + > minikube dashboard + +This should open up a tab in your default browser where you can poke about. For +instance one thing to try is to change the number of replicas of the dockerwatch +ReplicaSet to and see what happens. diff --git a/advanced_examples/minikube-simple/create-certs b/advanced_examples/minikube-simple/create-certs new file mode 100755 index 0000000..69ffc4d --- /dev/null +++ b/advanced_examples/minikube-simple/create-certs @@ -0,0 +1,22 @@ +#!/bin/sh + +set -e + +if [ ! -d ssl ]; then + mkdir ssl +fi + +# Create the root CA (Certificate Authority) +openssl genrsa -out ssl/dockerwatch-ca.key 4096 + +## Certificate signing request for root CA +openssl req -x509 -new -nodes -key ssl/dockerwatch-ca.key -sha256 -days 1024 -subj "/C=SE/" -out ssl/dockerwatch-ca.pem + +# Create the server certificate +openssl genrsa -out ssl/dockerwatch-server.key 4096 + +## Certificate signing request for server certificate +openssl req -new -key ssl/dockerwatch-server.key -subj "/C=SE/CN=$1/" -out ssl/dockerwatch-server.csr + +## Sign the server certificate using the root CA +openssl x509 -req -in ssl/dockerwatch-server.csr -CA ssl/dockerwatch-ca.pem -CAkey ssl/dockerwatch-ca.key -CAcreateserial -out ssl/dockerwatch-server.pem -days 500 -sha256 diff --git a/advanced_examples/minikube-simple/dockerwatch-deploy.yaml b/advanced_examples/minikube-simple/dockerwatch-deploy.yaml new file mode 100644 index 0000000..2402271 --- /dev/null +++ b/advanced_examples/minikube-simple/dockerwatch-deploy.yaml @@ -0,0 +1,35 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + ## Name and labels of the Deployment + labels: + app: dockerwatch + name: dockerwatch +spec: + replicas: 1 + selector: + matchLabels: + app: dockerwatch + template: + metadata: + labels: + app: dockerwatch + spec: + containers: + ## The container to launch + - image: dockerwatch + name: dockerwatch + imagePullPolicy: Never ## Set to Never as we built the image in the cluster + ports: + - containerPort: 8080 + protocol: TCP + - containerPort: 8443 + protocol: TCP + volumeMounts: + - name: kube-keypair + readOnly: true + mountPath: /etc/ssl/certs + volumes: + - name: kube-keypair + secret: + secretName: dockerwatch \ No newline at end of file diff --git a/advanced_examples/minikube-simple/dockerwatch/config/sys.config b/advanced_examples/minikube-simple/dockerwatch/config/sys.config new file mode 100644 index 0000000..674fbc9 --- /dev/null +++ b/advanced_examples/minikube-simple/dockerwatch/config/sys.config @@ -0,0 +1,5 @@ +[%% Kernel/logger + {kernel, [{logger,[{handler,default,logger_std_h,#{}}]} + %%,{logger_level,info} + ]} +]. diff --git a/advanced_examples/minikube-simple/dockerwatch/config/vm.args b/advanced_examples/minikube-simple/dockerwatch/config/vm.args new file mode 100644 index 0000000..3c1f4b6 --- /dev/null +++ b/advanced_examples/minikube-simple/dockerwatch/config/vm.args @@ -0,0 +1,2 @@ +-sname dockerwatch + diff --git a/advanced_examples/minikube-simple/dockerwatch/rebar.config b/advanced_examples/minikube-simple/dockerwatch/rebar.config new file mode 100644 index 0000000..cc81bc3 --- /dev/null +++ b/advanced_examples/minikube-simple/dockerwatch/rebar.config @@ -0,0 +1,17 @@ + +{deps, [{jsone, "1.4.7"}, %% JSON Encode/Decode + {cowboy, "2.5.0"}]}. %% HTTP Server + +{relx, [{release, {"dockerwatch", "1.0.0"}, [dockerwatch]}, + {vm_args, "config/vm.args"}, + {sys_config, "config/sys.config"}, + {dev_mode, true}, + {include_erts, false}, + {extended_start_script, true} + ]}. + +{profiles, [{prod, [{relx, [{dev_mode, false}, + {include_erts, true}, + {include_src, false}]}]} + ]}. +%% vim: ft=erlang diff --git a/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch.app.src b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch.app.src new file mode 100644 index 0000000..0142fc9 --- /dev/null +++ b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch.app.src @@ -0,0 +1,16 @@ +%% Feel free to use, reuse and abuse the code in this file. + +{application, dockerwatch, [ + {description, "Cowboy REST Hello World example."}, + {vsn, "1.0.0"}, + {modules, []}, + {registered, [dockerwatch_sup]}, + {applications, [ + kernel, + stdlib, + jsone, + cowboy + ]}, + {mod, {dockerwatch_app, []}}, + {env, []} +]}. diff --git a/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch.erl b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch.erl new file mode 100644 index 0000000..3e5b400 --- /dev/null +++ b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch.erl @@ -0,0 +1,45 @@ +%% +%% Copyright (C) 2014 Björn-Egil Dahlberg +%% +%% File: dockerwatch.erl +%% Author: Björn-Egil Dahlberg +%% Created: 2014-09-10 +%% + +-module(dockerwatch). + +-export([start_link/0, all/0, create/1, get/1, increment/2, decrement/2]). + +-type counter() :: binary(). + +-spec start_link() -> {ok, pid()}. +start_link() -> + {ok, spawn_link(fun() -> ets:new(?MODULE, [named_table, public]), + receive after infinity -> ok end end)}. + +-spec all() -> [counter()]. +all() -> + ets:select(?MODULE, [{{'$1','_'},[],['$1']}]). + +-spec create(counter()) -> ok | already_exists. +create(CounterName) -> + case ets:insert_new(?MODULE, {CounterName, 0}) of + true -> + ok; + false -> + already_exists + end. + +-spec get(counter()) -> integer(). +get(CounterName) -> + ets:lookup_element(?MODULE, CounterName, 2). + +-spec increment(counter(), integer()) -> ok. +increment(CounterName, Howmuch) -> + _ = ets:update_counter(?MODULE, CounterName, [{2, Howmuch}]), + ok. + +-spec decrement(counter(), integer()) -> ok. +decrement(CounterName, Howmuch) -> + _ = ets:update_counter(?MODULE, CounterName, [{2, -1 * Howmuch}]), + ok. diff --git a/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch_app.erl b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch_app.erl new file mode 100644 index 0000000..a85b5b6 --- /dev/null +++ b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch_app.erl @@ -0,0 +1,19 @@ +%% +%% Copyright (C) 2014 Björn-Egil Dahlberg +%% +%% File: dockerwatch_app.erl +%% Author: Björn-Egil Dahlberg +%% Created: 2014-09-10 +%% + +-module(dockerwatch_app). +-behaviour(application). + +-export([start/2,stop/1]). +%% API. + +start(_Type, _Args) -> + dockerwatch_sup:start_link(). + +stop(_State) -> + ok. diff --git a/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch_handler.erl b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch_handler.erl new file mode 100644 index 0000000..1ac15f9 --- /dev/null +++ b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch_handler.erl @@ -0,0 +1,103 @@ +%% +%% Copyright (C) 2014 Björn-Egil Dahlberg +%% +%% File: dockerwatch_handler.erl +%% Author: Björn-Egil Dahlberg +%% Created: 2014-09-10 +%% + +-module(dockerwatch_handler). + +-export([init/2]). +-export([allowed_methods/2]). +-export([content_types_accepted/2]). +-export([content_types_provided/2]). +-export([handle_post/2]). +-export([to_html/2]). +-export([to_json/2]). +-export([to_text/2]). + +init(Req, []) -> + {cowboy_rest, Req, []}. + +%% Which HTTP methods are allowed +allowed_methods(Req, State) -> + {[<<"GET">>, <<"POST">>], Req, State}. + +%% Which content types are accepted by POST/PUT requests +content_types_accepted(Req, State) -> + {[{{<<"application">>, <<"json">>, []}, handle_post}], + Req, State}. + +%% Handle the POST/PUT request +handle_post(Req, State) -> + case cowboy_req:binding(counter_name, Req) of + undefined -> + {false, Req, State}; + Name -> + case cowboy_req:has_body(Req) of + true -> + {ok, Body, Req3} = cowboy_req:read_body(Req), + Json = jsone:decode(Body), + ActionBin = maps:get(<<"action">>, Json, <<"increment">>), + Value = maps:get(<<"value">>, Json, 1), + Action = list_to_atom(binary_to_list(ActionBin)), + ok = dockerwatch:Action(Name, Value), + {true, Req3, State}; + false -> + ok = dockerwatch:create(Name), + {true, Req, State} + end + end. + +%% Which content types we handle for GET/HEAD requests +content_types_provided(Req, State) -> + {[{<<"text/html">>, to_html}, + {<<"application/json">>, to_json}, + {<<"text/plain">>, to_text} + ], Req, State}. + + +%% Return counters/counter as json +to_json(Req, State) -> + Resp = case cowboy_req:binding(counter_name, Req) of + undefined -> + dockerwatch:all(); + Counter -> + #{ Counter => dockerwatch:get(Counter) } + end, + {jsone:encode(Resp), Req, State}. + +%% Return counters/counter as plain text +to_text(Req, State) -> + Resp = case cowboy_req:binding(counter_name, Req) of + undefined -> + [io_lib:format("~s~n",[Counter]) || Counter <- dockerwatch:all()]; + Counter -> + io_lib:format("~p",[dockerwatch:get(Counter)]) + end, + {Resp, Req, State}. + +%% Return counters/counter as html +to_html(Req, State) -> + Body = case cowboy_req:binding(counter_name, Req) of + undefined -> + Counters = dockerwatch:all(), + ["
    \n", + [io_lib:format("
  • ~s
  • \n", [Counter]) || Counter <- Counters], + "
\n"]; + Counter -> + Value = dockerwatch:get(Counter), + io_lib:format("~s = ~p",[Counter, Value]) + end, + {[html_head(),Body,html_tail()], Req, State}. + +html_head() -> + <<" + + + dockerwatch + ">>. +html_tail() -> + <<" + ">>. diff --git a/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch_sup.erl b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch_sup.erl new file mode 100644 index 0000000..ef298ad --- /dev/null +++ b/advanced_examples/minikube-simple/dockerwatch/src/dockerwatch_sup.erl @@ -0,0 +1,49 @@ +%% +%% Copyright (C) 2014 Björn-Egil Dahlberg +%% +%% File: dockerwatch_sup.erl +%% Author: Björn-Egil Dahlberg +%% Created: 2014-09-10 +%% + +-module(dockerwatch_sup). +-behaviour(supervisor). + +-export([start_link/0,init/1]). + +%% API. + +-spec start_link() -> {ok, pid()}. +start_link() -> + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +%% supervisor. + +init([]) -> + CertsDir = "/etc/ssl/certs/", + + Dispatch = cowboy_router:compile([ + {'_', [{"/[:counter_name]", dockerwatch_handler, []}]} + ]), + + HTTPS = ranch:child_spec( + cowboy_https, 100, ranch_ssl, + [{port, 8443}, + {cacertfile, filename:join(CertsDir, "dockerwatch-ca.pem")}, + {certfile, filename:join(CertsDir, "dockerwatch-server.pem")}, + {keyfile, filename:join(CertsDir, "dockerwatch-server.key")}], + cowboy_tls, + #{env=>#{dispatch=>Dispatch}}), + + HTTP = ranch:child_spec( + cowboy_http, 100, ranch_tcp, + [{port, 8080}], + cowboy_clear, + #{env=>#{dispatch=>Dispatch}}), + + Counter = {dockerwatch, {dockerwatch, start_link, []}, + permanent, 5000, worker, [dockerwatch]}, + + Procs = [Counter, HTTP, HTTPS], + + {ok, {{one_for_one, 10, 10}, Procs}}.