Example using docker compose

@jptechnical can you provide the compose.yml you are using that worked? I am trying to do something similar, spent about 4 hours on it yesterday. I can get Traefik to route me to the /zac as well as display the DNS:1280 for the controller, but when I go to enroll my phone it still shows ziti-edge-controller:1280 instead of my public DNS. I have tried changing all the variables listed in the post, edit the dns.yaml in the docker, and the dns.yaml in the volumes but can not get that advertised variable to change.

Hi @rcwilbert001, welcome to the community and to OpenZiti! (and browzer and zrok)

I take it you are following this thread entirely? Are you using the openziti/quickstart image? There are newer containers out there that are availalble as well. Do you care which image you use or are you open to "anything that works"? (also are you ok if i make this a new forum topic?)

Hello!

My latest compose was using the openziti/quickstart with the all in one compose, but I have also tried the simplified-docker-compose.yml as well. I am open to anything that works. I was originally using the host-anywhere quickstart for 3 days, which somehow I managed to totally lock myself out of, lol. So now I am trying to come up with a single traefik/ziti compose file that I can just execute with a specified host DNS. I think it would make my life easier, as well as newer tech users that are not as strong in the networking space. This is mainly for homelab access fyi. Feel free to start a new thread if you prefer, this was just the only thread I came across that mentioned my specific issue.

I think you'd be best off now-a-days with the example from the doc. You can find that here: Deploy the Controller with Docker | OpenZiti

Running the controller will boil down to nothing much more than:

Then just docker compose up.

You'll need a router too. Example compose fragment is here https://get.openziti.io/dist/docker-images/ziti-router/compose.yml

Hope that helps...

Yes, I went that route for one of the times, but I kept having issues with the router accepting the .jwt. To me it would see super easy to just have a default one launch compose file. Like I said zac.example.host.com works perfect. Also example.host.com:1280 works when I am registering the controller. It is only an issue when I try to register a new identity. This is the current docker compose that I am using.

services:
  ziti-controller:
    image: "${ZITI_IMAGE}:${ZITI_VERSION}"
    labels:
      - traefik.http.routers.ziti-controller.rule=Host(`example.host.com`)
      - traefik.http.routers.ziti-controller.tls=true
      - traefik.http.routers.ziti-controller.tls.certresolver=lets-encrypt
      - traefik.port=1280
    healthcheck:
      test: curl -m 1 -s -k -f https://${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS:-ziti-edge-controller}:${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280}/edge/client/v1/version
      interval: 1s
      timeout: 3s
      retries: 30
    env_file:
      - ./.env
    ports:
      - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280}:${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280}
      - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_CTRL_ADVERTISED_PORT:-6262}:${ZITI_CTRL_ADVERTISED_PORT:-6262}
    environment:
      - ZITI_CTRL_NAME=${ZITI_CTRL_NAME:-ziti-edge-controller}
      - ZITI_CTRL_EDGE_ADVERTISED_ADDRESS=${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS:-ziti-edge-controller}
      - ZITI_CTRL_EDGE_ADVERTISED_PORT=${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280}
      - ZITI_CTRL_EDGE_IP_OVERRIDE=${ZITI_CTRL_EDGE_IP_OVERRIDE:-127.0.0.1}
      - ZITI_CTRL_ADVERTISED_PORT=${ZITI_CTRL_ADVERTISED_PORT:-6262}
      - ZITI_EDGE_IDENTITY_ENROLLMENT_DURATION=${ZITI_EDGE_IDENTITY_ENROLLMENT_DURATION}
      - ZITI_ROUTER_ENROLLMENT_DURATION=${ZITI_ROUTER_ENROLLMENT_DURATION}
      - ZITI_USER=${ZITI_USER:-admin}
      - ZITI_PWD=${ZITI_PWD}
    networks:
      ziti:
        aliases:
          - ziti-edge-controller
    volumes:
      - ziti-fs:/persistent
    entrypoint:
      - "/var/openziti/scripts/run-controller.sh"

  ziti-controller-init-container:
    image: "${ZITI_IMAGE}:${ZITI_VERSION}"
    depends_on:
      ziti-controller:
        condition: service_healthy
    environment:
      - ZITI_CTRL_EDGE_ADVERTISED_ADDRESS=${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS:-ziti-edge-controller}
      - ZITI_CTRL_EDGE_ADVERTISED_PORT=${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280}
    env_file:
      - ./.env
    networks:
      ziti:
    volumes:
      - ziti-fs:/persistent
    entrypoint:
      - "/var/openziti/scripts/run-with-ziti-cli.sh"
    command:
      - "/var/openziti/scripts/access-control.sh"

  ziti-edge-router:
    image: "${ZITI_IMAGE}:${ZITI_VERSION}"
    env_file:
      - ./.env
    depends_on:
      ziti-controller:
        condition: service_healthy
    ports:
      - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_ROUTER_PORT:-3022}:${ZITI_ROUTER_PORT:-3022}
      - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_ROUTER_LISTENER_BIND_PORT:-10080}:${ZITI_ROUTER_LISTENER_BIND_PORT:-10080}
    environment:
      - ZITI_CTRL_ADVERTISED_ADDRESS=${ZITI_CTRL_ADVERTISED_ADDRESS:-ziti-controller}
      - ZITI_CTRL_ADVERTISED_PORT=${ZITI_CTRL_ADVERTISED_PORT:-6262}
      - ZITI_CTRL_EDGE_ADVERTISED_ADDRESS=${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS:-ziti-edge-controller}
      - ZITI_CTRL_EDGE_ADVERTISED_PORT=${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280}
      - ZITI_ROUTER_NAME=${ZITI_ROUTER_NAME:-ziti-edge-router}
      - ZITI_ROUTER_ADVERTISED_ADDRESS=${ZITI_ROUTER_ADVERTISED_ADDRESS:-ziti-edge-router}
      - ZITI_ROUTER_PORT=${ZITI_ROUTER_PORT:-3022}
      - ZITI_ROUTER_LISTENER_BIND_PORT=${ZITI_ROUTER_LISTENER_BIND_PORT:-10080}
      - ZITI_ROUTER_ROLES=public
    networks:
      - ziti
    volumes:
      - ziti-fs:/persistent
    entrypoint: /bin/bash
    command: "/var/openziti/scripts/run-router.sh edge"

  ziti-console:
    image: openziti/zac
    labels:
      - traefik.http.routers.ziti-console.rule=Host(`zac.example.host.com.com`)
      - traefik.http.routers.ziti-console.tls=true
      - traefik.http.routers.ziti-console.tls.certresolver=lets-encrypt
      - traefik.port=8443
    working_dir: /usr/src/app
    environment:
      - ZAC_SERVER_CERT_CHAIN=/persistent/pki/${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS:-ziti-edge-controller}-intermediate/certs/${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS:-ziti-edge-controller}-server.cert
      - ZAC_SERVER_KEY=/persistent/pki/${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS:-ziti-edge-controller}-intermediate/keys/${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS:-ziti-edge-controller}-server.key
      - ZITI_CTRL_EDGE_ADVERTISED_ADDRESS=${ZITI_CTRL_EDGE_ADVERTISED_ADDRESS:-ziti-edge-controller}
      - ZITI_CTRL_EDGE_ADVERTISED_PORT=${ZITI_CTRL_EDGE_ADVERTISED_PORT:-1280}
      - ZITI_CTRL_NAME=${ZITI_CTRL_NAME:-ziti-edge-controller}
      - PORTTLS=8443
    depends_on:
      ziti-controller:
        condition: service_healthy
    ports:
      - ${ZITI_INTERFACE:-0.0.0.0}:8443:8443
    volumes:
      - ziti-fs:/persistent
    networks:
      - ziti

networks:
  ziti:

volumes:
  ziti-fs:```

That's helpful -- i'll use your compose and see what i see. Thanks for supplying it. Do you use a .env file to start your compose or do you use exported env vars? I'm just trying to understand what you set (or don't) in case it's relevant

I use a .env file. I copied one from the openziti/ziti repo and tried modifying the variables. As well as tried to simulate the .env from the post that I responded in.

Using your compose file (assuming you're using openziti/quickstart as the image) here's how you can deploy it using compose.

Use this .env file -- update the values accordingly

ZITI_IMAGE="openziti/quickstart"
ZITI_VERSION="latest"
ZITI_USER="admin"
ZITI_PWD="your_password_here"

ZITI_CTRL_ADVERTISED_ADDRESS="ec2-3-18-113-172.us-east-2.compute.amazonaws.com"
ZITI_CTRL_ADVERTISED_PORT="8660"
ZITI_CTRL_EDGE_ADVERTISED_ADDRESS="ec2-3-18-113-172.us-east-2.compute.amazonaws.com"
ZITI_CTRL_EDGE_ADVERTISED_PORT="8661"
ZITI_ROUTER_ADVERTISED_ADDRESS="ec2-3-18-113-172.us-east-2.compute.amazonaws.com"
ZITI_ROUTER_LISTENER_BIND_PORT="8662"

ZITI_EDGE_IDENTITY_ENROLLMENT_DURATION="30000"
ZITI_ROUTER_ENROLLMENT_DURATION="30000"

You can confirm you have everything setup correctly by running the new ziti ops verify-traffic command such as:

ziti ops verify-traffic --host ec2-3-18-113-172.us-east-2.compute.amazonaws.com --port 8661 --password your_password_here

You'll see something like this when it succeeds

Lemme know if that gets you goin...

Making Progress! When I go to enroll, it is providing the me the correct hostname.com:8661 , now my problem lies in the fact that I can't create and entry point with traefik to that port because it is being bound by the docker containers. Thoughts?
I really appreciate the help!

Thought: Is there a way to set the entrypoint/api to subdomain. ctrl.hostdomain.com without a port. So that I can just route the data through traefik ctrl.hostdomain.com -> localhost:8661. But I think it is always going to bind to a port correct?

Hrmmmm... I'm not sure any of our stuff comes out of the gate supporting some kind of reverse proxy approach... Really what you need is for traefik to bind $EXTERNAL_IP:$PORT, and for it to send traffic to $INTERNAL_IP:$PORT but to do that you'd still want your advertised address to be $EXTERNAL_IP:$PORT... I don't think we support an "easy button" for reverse-proxied setups all that well as it is. I image for you it is mandatory for the traffic goes through traefik for "reasons"...

You will need to:

  • start the environment
  • edit the /persistent/ziti-edge-controller.yaml file mounted/used by the controller
  • find the ctrl.listener and change it to "any other port" (right now it might be listener: tls:0.0.0.0:8660, chance that port to 8770 or whatever)
  • update traefik to bind 8660 and send it to 8770 PASS THROUGH (traefik cannot terminate tls and this is not HTTP traffic, this is TCP)
  • find the web.bindPoints.interface (mine shows interface: 0.0.0.0:8661) and change 8661 to 8771
  • update traefik to bind 8661 and send traffic to 8771, again pass through. this i HTTP traffic, but traefik cannot terminate TLS
  • open the compose file (not the .env) and find/change ZITI_CTRL_ADVERTISED_PORT->8770 and ZITI_CTRL_EDGE_ADVERTISED_PORT --> 8771

Restart docker and docker should now be listening on 8770 and 8771, but be ADVERTISING 8660 and 8661 still...

I THINK that will work? But tbh I don't have a setup that I can effectively test/prove this with... That make sense?

It isn't really mandatory, it is just the path I have set myself down. The end goal would be that I would end up with a full fledged docker compose, with a minimal modified .env file, and subdomains would already be designated for zac/edge/etc. The setup would be minutes, and as long as the user had their DNS pointed to the IP address. Not to mention everything would be https:// through lets encrypt.

I don't know enough about the networking stuff, but if I could just override the api network for the JWT on submission it would make it easy.

"everything" is already TLS/mTLS/HTTPS via OpenZiti. It's just not necessary (for most people) to leverage a third-party independently verifiable cert like one from LetsEncrypt because generally speaking, the OpenZiti overlay and components are invisible to "normal" users. (only a bit hand-wavy there, but I feel the sentiment is generally accurate)

If you have no need for sending traffic through traefik, the original post/.env file will work and will get you going in minutes. If you're not using traefik for some reason, I'd just leave it out and you'd be done. :slight_smile:

If there's a reason for it though, do let us know why you'd want/need it. It might change my mind and help me help you better. Otherwise, I'd just send the traffic through to OpenZiti and you're gtg. :slight_smile:

Ok, so you are correct, I just opened the correct port on the firewall, and bypass the traefik host all together. Since I already have a Ziti-controller, Ziti-router, and Zac setup in this config. Is there a simplified way to add the .ziti dns router? I looked at the docs and it is confusing me. I tried to do it earlier and it was erroring out on the .jwt import for the tporxy-router, so I wasn't sure if there was an easier process to just modify my current setup.

I really do appreciate you taking the time to answer the questions. While I consider myself very proficient in a lot of technologies/softwares, this stuff is humbling me a little bit. As well as my lack of understanding of the magic happening.

can you expand on what you're asking here? Are you attempting to provide "intercept" capabilities to a docker container? I'm not quite following what you're up to, so it's hard for me to respond. It sounds like you have your overlay all setup - did you confirm things were good to go by using ziti ops verify-traffic? Let's make sure we're in the clear before going on... :slight_smile: assuming that is good, just let me know what you're trying to do next. That context will help me help you.

You're quite welcome. :slight_smile: we'll get there...

Yep everything is working as expected. I was able to add a tunnel from my home media server. I was also able to register my phone. So when I did the hosted anywhere quick start, I was able to register my proxmox home address as, prox.ziti, and ziti would just proxy that to my home network local ip address for the server. I tried to do something similar on this setup and it wasn't working. I saw there was the sidecar setup, but again I got a little lost and failed at that attempt.

The sidecar setup can be used in two different ways. The most common is to just run a router inside the docker network of your choosing and use it to provide reach into that docker network. That'd be the "host" version. You run a tunneler or a router and use it exclusively to get into docker.

The "tproxy router" is used to provide "intercept" capabilities to a docker container. In my experience, this is a far, far less-common type of deployment but it's super-useful if you're deploying a docker-based app "somewhere else" (at a friend's house, in the cloud, etc)... For example, I did this with my work for "External OpenZiti" with EdgeXFoundry. I used the public Router to also intercept traffic from the OpenZiti controller to tunnel through down to EdgeXFoundry Vault server, also an uncommon setup, but super cool. :slight_smile:

So, I'm not sure you need it yet, but maybe you do or are just wanting to learn how you'd do that?

Ok, so my current ziti dockers are running on a DigitalOcean VPS. I am using that as the central node for my Phone to connect to my home service, and eventually everywhere else. So what I was able to do with my host-anywhere quickstart, and what I would like to do with my current dockers, is tunnel into the network with my phone, type homeassist.ziti in a url, it gets intercepted by the ziti dns, and routes down the homelab server tunnel, and lets me access 192.168.1.13:8123. Maybe with my setup it should work out of the box and I just didn't set it up right.

Yeah you don't need the proxy sidecar for this scenario. You're ziti mobile edge will intercept the homeassistant.ziti URL and send it to a tunneler in your home network. Personally, I'd use a router deployed in the same location as home assistant or I would deploy a ziti-edge-tunnel (Linux tunneler) adjacent to home assistant. That identity (router or tunneler) would be responsible for offloading data from the overlay, back to home assistant.

I don't know what the state is currently, but there used to be an OpenZiti plug-in/extension for home assistant. @NicFragale I think maintained it. You might find that interesting too