From 79ec8150a6b25a171fb3ccbaae5fc5ecca5432a1 Mon Sep 17 00:00:00 2001 From: Kenneth Bingham Date: Mon, 18 Dec 2023 16:28:49 -0500 Subject: [PATCH] add self-hosted zrok instance for Docker --- docker/compose/zrok-instance/Caddyfile | 30 ++++ docker/compose/zrok-instance/caddy.Dockerfile | 13 ++ docker/compose/zrok-instance/compose.yml | 76 ++++++++++ docker/compose/zrok-instance/ctrl.web.yaml | 141 ++++++++++++++++++ docker/compose/zrok-instance/zrok_ctrl.yml | 25 ++++ .../compose/zrok-instance/zrok_frontend.yml | 12 ++ 6 files changed, 297 insertions(+) create mode 100644 docker/compose/zrok-instance/Caddyfile create mode 100644 docker/compose/zrok-instance/caddy.Dockerfile create mode 100644 docker/compose/zrok-instance/compose.yml create mode 100644 docker/compose/zrok-instance/ctrl.web.yaml create mode 100644 docker/compose/zrok-instance/zrok_ctrl.yml create mode 100644 docker/compose/zrok-instance/zrok_frontend.yml diff --git a/docker/compose/zrok-instance/Caddyfile b/docker/compose/zrok-instance/Caddyfile new file mode 100644 index 00000000..22d037c7 --- /dev/null +++ b/docker/compose/zrok-instance/Caddyfile @@ -0,0 +1,30 @@ + +{ + email ${ZROK_ACME_EMAIL} + acme_ca https://acme-v02.api.letsencrypt.org/directory +} + +*.${ZROK_ZONE} { + tls { + dns digitalocean {env.DIGITALOCEAN_ACCESS_TOKEN} + propagation_timeout 60m + } + + log { + output stdout + format console + level DEBUG + } + + @oauth host oauth.${ZROK_ZONE} + reverse_proxy @oauth frontend:8181 + + @ctrl host ctrl.${ZROK_ZONE} + reverse_proxy @ctrl zrok:18080 + + reverse_proxy frontend:8080 { + header_up Host {http.request.host} + } + +} + diff --git a/docker/compose/zrok-instance/caddy.Dockerfile b/docker/compose/zrok-instance/caddy.Dockerfile new file mode 100644 index 00000000..155c9fb6 --- /dev/null +++ b/docker/compose/zrok-instance/caddy.Dockerfile @@ -0,0 +1,13 @@ +# Use the official Caddy image as a parent image +FROM caddy:2-builder AS builder + +# Build Caddy with the digitalocean DNS provider +RUN xcaddy build \ + --with github.com/caddy-dns/digitalocean + +# Use the official Caddy image to create the final image +FROM caddy:2 + +# Copy the custom Caddy build into the final image +COPY --from=builder /usr/bin/caddy /usr/bin/caddy + diff --git a/docker/compose/zrok-instance/compose.yml b/docker/compose/zrok-instance/compose.yml new file mode 100644 index 00000000..3f4f6640 --- /dev/null +++ b/docker/compose/zrok-instance/compose.yml @@ -0,0 +1,76 @@ +services: + zrok_env: + image: busybox + command: chown -Rc 65534:65534 /var/lib/zrok/env; chmod ug=rwX,o-rwx -Rc /var/lib/zrok/env + volumes: + - zrok_env:/var/lib/zrok/env + zrok: + depends_on: + zrok_env: + condition: service_completed_successfully + image: openziti/zrok:0.4.20 + command: controller --verbose ./etc/ctrl.yml + working_dir: /var/lib/zrok + volumes: + - ./zrok_etc:/var/lib/zrok/etc + networks: + quickstart: + restart: unless-stopped + ports: + - 127.0.0.1:18080:18080 + environment: + PFXLOG_NO_JSON: "true" + frontend: + depends_on: + zrok_env: + condition: service_completed_successfully + image: openziti/zrok:0.4.20 + command: access public --verbose ./etc/frontend.yml + working_dir: /var/lib/zrok + volumes: + - zrok_env:/var/lib/zrok/env + - ./zrok_etc:/var/lib/zrok/etc + networks: + quickstart: + restart: unless-stopped + ports: + - 127.0.0.1:8080:8080 + - 127.0.0.1:8081:8081 + environment: + PFXLOG_NO_JSON: "true" + HOME: /var/lib/zrok/env + ZROK_ADMIN_TOKEN: + ZROK_API_ENDPOINT: + quickstart: + restart: unless-stopped + networks: + quickstart: + aliases: + - ziti.${ZROK_ZONE} + caddy: + build: + context: . + dockerfile: ./caddy.Dockerfile + restart: unless-stopped + environment: + DIGITALOCEAN_ACCESS_TOKEN: + ports: + - "80:80" + - "443:443" + - "443:443/udp" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile + - caddy_data:/data + - caddy_config:/config + networks: + quickstart: + +volumes: + caddy_data: + caddy_config: + zrok_env: + +networks: + quickstart: + driver: bridge + diff --git a/docker/compose/zrok-instance/ctrl.web.yaml b/docker/compose/zrok-instance/ctrl.web.yaml new file mode 100644 index 00000000..793b84bc --- /dev/null +++ b/docker/compose/zrok-instance/ctrl.web.yaml @@ -0,0 +1,141 @@ +# this is a partial ziti controller configuration that redefines the quickstart's list of web listeners as two: +# client-management (private listener) and edge-client (public listener) +web: + # name - required + # Provides a name for this listener, used for logging output. Not required to be unique, but is highly suggested. + - name: edge-client + # bindPoints - required + # One or more bind points are required. A bind point specifies an interface (interface:port string) that defines + # where on the host machine the webListener will listen and the address (host:port) that should be used to + # publicly address the webListener(i.e. mydomain.com, localhost, 127.0.0.1). This public address may be used for + # incoming address resolution as well as used in responses in the API. + bindPoints: + #interface - required + # A host:port string on which network interface to listen on. 0.0.0.0 will listen on all interfaces + - interface: 0.0.0.0:1280 + # address - required + # The public address that external incoming requests will be able to resolve. Used in request processing and + # response content that requires full host:port/path addresses. + address: ziti.${ZROK_ZONE}:1280 + # identity - optional + # Allows the webListener to have a specific identity instead of defaulting to the root 'identity' section. + identity: + ca: "/persistent/pki/root-ca/certs/root-ca.cert" + key: "/persistent/pki/intermediate-ca/keys/server.key" + server_cert: "/persistent/pki/intermediate-ca/certs/server.chain.pem" + cert: "/persistent/pki/intermediate-ca/certs/client.cert" + #alt_server_certs: + #- server_cert: "" + # server_key: "" + + # options - optional + # Allows the specification of webListener level options - mainly dealing with HTTP/TLS settings. These options are + # used for all http servers started by the current webListener. + options: + # idleTimeoutMs - optional, default 5000ms + # The maximum amount of idle time in milliseconds allowed for pipelined HTTP requests. Setting this too high + # can cause resources on the host to be consumed as clients remain connected and idle. Lowering this value + # will cause clients to reconnect on subsequent HTTPs requests. + idleTimeout: 5000ms #http timeouts, new + # readTimeoutMs - optional, default 5000ms + # The maximum amount of time in milliseconds http servers will wait to read the first incoming requests. A higher + # value risks consuming resources on the host with clients that are acting bad faith or suffering from high latency + # or packet loss. A lower value can risk losing connections to high latency/packet loss clients. + readTimeout: 5000ms + # writeTimeoutMs - optional, default 100000ms + # The total maximum time in milliseconds that the http server will wait for a single requests to be received and + # responded too. A higher value can allow long-running requests to consume resources on the host. A lower value + # can risk ending requests before the server has a chance to respond. + writeTimeout: 100000ms + # minTLSVersion - optional, default TLS1.2 + # The minimum version of TSL to support + minTLSVersion: TLS1.2 + # maxTLSVersion - optional, default TLS1.3 + # The maximum version of TSL to support + maxTLSVersion: TLS1.3 + # apis - required + # Allows one or more APIs to be bound to this webListener + apis: + # binding - required + # Specifies an API to bind to this webListener. Built-in APIs are + # - edge-management + # - edge-client + # - fabric-management + # - binding: edge-management + # # options - arg optional/required + # # This section is used to define values that are specified by the API they are associated with. + # # These settings are per API. The example below is for the 'edge-api' and contains both optional values and + # # required values. + # options: { } + - binding: edge-client + options: { } + #- binding: fabric + # options: { } + - name: client-management + # bindPoints - required + # One or more bind points are required. A bind point specifies an interface (interface:port string) that defines + # where on the host machine the webListener will listen and the address (host:port) that should be used to + # publicly address the webListener(i.e. mydomain.com, localhost, 127.0.0.1). This public address may be used for + # incoming address resolution as well as used in responses in the API. + bindPoints: + #interface - required + # A host:port string on which network interface to listen on. 0.0.0.0 will listen on all interfaces + - interface: 0.0.0.0:1281 + # address - required + # The public address that external incoming requests will be able to resolve. Used in request processing and + # response content that requires full host:port/path addresses. + address: 127.0.0.1:1281 + # identity - optional + # Allows the webListener to have a specific identity instead of defaulting to the root 'identity' section. + identity: + ca: "/persistent/pki/root-ca/certs/root-ca.cert" + key: "/persistent/pki/intermediate-ca/keys/server.key" + server_cert: "/persistent/pki/intermediate-ca/certs/server.chain.pem" + cert: "/persistent/pki/intermediate-ca/certs/client.cert" + #alt_server_certs: + #- server_cert: "" + # server_key: "" + + # options - optional + # Allows the specification of webListener level options - mainly dealing with HTTP/TLS settings. These options are + # used for all http servers started by the current webListener. + options: + # idleTimeoutMs - optional, default 5000ms + # The maximum amount of idle time in milliseconds allowed for pipelined HTTP requests. Setting this too high + # can cause resources on the host to be consumed as clients remain connected and idle. Lowering this value + # will cause clients to reconnect on subsequent HTTPs requests. + idleTimeout: 5000ms #http timeouts, new + # readTimeoutMs - optional, default 5000ms + # The maximum amount of time in milliseconds http servers will wait to read the first incoming requests. A higher + # value risks consuming resources on the host with clients that are acting bad faith or suffering from high latency + # or packet loss. A lower value can risk losing connections to high latency/packet loss clients. + readTimeout: 5000ms + # writeTimeoutMs - optional, default 100000ms + # The total maximum time in milliseconds that the http server will wait for a single requests to be received and + # responded too. A higher value can allow long-running requests to consume resources on the host. A lower value + # can risk ending requests before the server has a chance to respond. + writeTimeout: 100000ms + # minTLSVersion - optional, default TLS1.2 + # The minimum version of TSL to support + minTLSVersion: TLS1.2 + # maxTLSVersion - optional, default TLS1.3 + # The maximum version of TSL to support + maxTLSVersion: TLS1.3 + # apis - required + # Allows one or more APIs to be bound to this webListener + apis: + # binding - required + # Specifies an API to bind to this webListener. Built-in APIs are + # - edge-management + # - edge-client + # - fabric-management + - binding: edge-management + # options - arg optional/required + # This section is used to define values that are specified by the API they are associated with. + # These settings are per API. The example below is for the 'edge-api' and contains both optional values and + # required values. + options: { } + #- binding: edge-client + # options: { } + - binding: fabric + options: { } diff --git a/docker/compose/zrok-instance/zrok_ctrl.yml b/docker/compose/zrok-instance/zrok_ctrl.yml new file mode 100644 index 00000000..099ccfba --- /dev/null +++ b/docker/compose/zrok-instance/zrok_ctrl.yml @@ -0,0 +1,25 @@ +# _____ __ ___ | | __ +# |_ / '__/ _ \| |/ / +# / /| | | (_) | < +# /___|_| \___/|_|\_\ +# controller configuration + +v: 3 +admin: + # generate these admin tokens from a source of randomness, e.g. + # LC_ALL=C tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c32 + secrets: + - "" +endpoint: + host: 0.0.0.0 + port: 18080 +invites: + invites_open: true + token_strategy: store +store: + path: ./etc/zrok.db + type: sqlite3 +ziti: + api_endpoint: https://ziti.${ZROK_ZONE}:1281/edge/management/v1 + username: admin + password: "" diff --git a/docker/compose/zrok-instance/zrok_frontend.yml b/docker/compose/zrok-instance/zrok_frontend.yml new file mode 100644 index 00000000..4dd2eef4 --- /dev/null +++ b/docker/compose/zrok-instance/zrok_frontend.yml @@ -0,0 +1,12 @@ +v: 3 +host_match: ${ZROK_ZONE} +address: 0.0.0.0:8080 +oauth: + bind_address: 0.0.0.0:8181 + redirect_url: https://oauth.${ZROK_ZONE} + cookie_domain: ${ZROK_ZONE} + hash_key: ${ZROK_OAUTH_HASH_KEY} + providers: + - name: google + client_id: "" + client_secret: ""