All-in-one docker compose

Hello,
Newbie here trying to learn OpenZiti. After multiple trial and errors, and reading multiple other threads with similar issues, I seem to have stumbled on successfully spinning up the all-in-one docker image as I'm able to get to the admin console. But it doesn't seem to take in a .env file to specify the username and password. So I'm unable to log in to the console. Since I have little to no understanding about ZT, I hope I can articulate what I'm trying to do correctly.

  1. How do I connect a service to this Ziti controller?
  2. How do I connect a device eg android or ios device to this Ziti controller to access those services?
    Would someone be able to point me down the right path on what's next?

Hi @Trading6165, welcome to the community and to OpenZiti (and zrok and BrowZer)!

The all-in-one image doesn't leverage the older, bash-based quickstart which uses a .env file. It uses a newer quickstart that's available in the ziti cli itself. Unless you chose to override the password, it should be 'admin' as shown here in the Dockerfile

You also should make sure you set ZITI_CTRL_ADVERTISED_ADDRESS and ZITI_CTRL_ADVERTISED_PORT to something that is routable by all the clients you want to connect. It'll be best if those values are routable/available on the on the internet but if you're just learning, it could be a private network address if you want.

I assume you're starting this instance on the internet in a VPS somewhere? Assuming yes, you want to set those two environent variables before starting your overlay.

Hope that helps?

Thank you so much! I wasn't sure I was supposed to modify the compose.yml file. I have indeed set the ZITI_PWD; ZITI_CTRL_ADVERTISED_ADDRESS; and ZITI_CTRL_ADVERTISED_PORT. Went ahead and mapped the ZITI_HOME to a directory as well.
Now I can login using the updated password.

Yes, I'm running this on my Oracle ARM VM and have allowed ingress on port 1280 from my home IP address for testing.

Cool. You don't have to edit the compose file. You could set an environment variable or you could use a .env file if you prefer. But you can definitely edit the compose if you want. :slight_smile: Whatever works for you. Have fun!

Hmm, maybe i misunderstood your first comment...

I assume this meant that it doesn't use a .env file.

Would you mind expanding on what you mean by 'overlay'?

That's entirely a docker thing. The docker file leverages variables. It will react, use and follow regular docker conventions.

An overlay network means it's built virtually "on top" of other networking, generally on IP but not exclusively. OpenZiti is built on IP. Classic IP would be considered the underlay network for the OpenZiti overlay

Thank you for your patience and guidance so far.

Got it. I've started over with a vanilla compose file with the exception of adding:
env_file: ".env"
and specifying the few variables in the .env file eg.
ZITI_CTRL_ADVERTISED_ADDRESS=my vps public ip address
ZITI_PWD=mysecretpassword
ZITI_CLI_TAG=main
ZITI_HOME=./config
The newly spun up container used the .env variables.

Now I am able to connect my phone's ZME to this controller from my home, but not from outside my home, which makes sense since I only allowed ingress on port 1280 from my home IP address. So my next question is regarding the ports...
Unlike other instructions I've seen such as the Host Openziti Anywhere which use several ports eg:
* 8440/tcp: edge controller providing router control plane
* 8441/tcp: edge controller providing client sessions
* 8442/tcp: edge router providing client connections
* 8443/tcp: Ziti Admin Console (ZAC) [optional]
the compose.yml for this all-in-one only specifies these 2 ports:
- ${ZITI_CTRL_ADVERTISED_PORT:-1280}
- ${ZITI_ROUTER_PORT:-3022}
Do I need to open both of these ports to the world, to make ZME and ziti-edge-tunnel connect to this controller?

Yes. The original quickstarts are from a time before ALPN was implemented and were also intended to be used as learning vehicles. They try to illustrate all the settings and variables you can change.

The newer quickstarts are leveraging ALPN so fewer ports are necessary. You still need one port for the controller, one port for the router, and one port for ZAC. Eventually, once you get a little further into your OpenZiti journey you'll find you can split off the management API of the controller and also remove the Zac from the Internet as well.

Would you be able to point me to a guide to understand how to do this? I think I need to learn to do this before opening the ports to the world. As is, if I open 1280 to the world, then the ZAC is exposed as well...

You can edit the controller's configuration YAML to change which APIs are bound to each web listener.

The web section of the config has a list of listeners. Each listener has a list of bindings (link to list of available bindings).

You need to add a web listener and bind the API named edge-management. Then you can control access to that listener separately from the one that binds edge-client, which must remain publicly published for enrollment, authentication, etc.

Split client and management API example:

web:
  - name: public
    bindPoints:
      - interface: 0.0.0.0:1280
        address: ziti.example.com:1280
    options:
      idleTimeout: 5000ms
      readTimeout: 5000ms
      writeTimeout: 100000ms
      minTLSVersion: TLS1.2
      maxTLSVersion: TLS1.3
    apis:
      - binding: edge-client
        options: { }
  - name: private
    bindPoints:
      - interface: 127.0.0.1:1281
        address: 127.0.0.1:1281
    options:
      idleTimeout: 5000ms
      readTimeout: 5000ms
      writeTimeout: 100000ms
      minTLSVersion: TLS1.2
      maxTLSVersion: TLS1.3
    apis:
      - binding: edge-management
        options: { }
      - binding: edge-client
        options: { }
      - binding: fabric
        options: { }
      - binding: zac
        options:
          location: /opt/openziti/share/console
          indexFile: index.html

IMO, it's entirely fine to start here. I have a couple ZAC instances exposed like https://ctrl.clint.demo.openziti.org:8441/zac/login. So I don't think there's any harm in having it exposed per-se. Is it better to have it split off an inacessible to the world? sure, but I would STRONGLY urge you to get things working with it exposed, understand how things work without splitting the API, then migrate to having it split off. But if you want to start off that way - you can :slight_smile:

If you're interested in a video you can watch https://www.youtube.com/watch?v=FI4byEDg344

Hmm, after making the changes in your example to the quickstart/ctrl.yaml, are there any other changes that need to be made to the compose.yml file to properly split them up?
I destroyed the existing containers and 'config/quickstart' folder and rebuilt the container with the above changes, I'm getting this error when accessing the ZAC:

{"error":{"cause":{"code":"UNHANDLED","message":"path /edge/client/v1/zac/ was not found"},"code":"NOT_FOUND","message":"The resource requested was not found or is no longer available","requestId":"F5h3XYpnS-"},"meta":{"apiEnrollmentVersion":"0.0.1","apiVersion":"0.0.1"}}

The zac binding shares a listener with the edge-management binding, so you must access it with a URL to that listener like https://127.0.0.1:1281 from the example. Still, I agree with @TheLumberjack it's not critical to obscure the listener that provides admin access, but I would guard the credential and use only cert auth wherever possible, securing the password as a recovery option.

Okay if I can't figure out this splitting by end of today, then I'll take the route recommended by @TheLumberjack.
So I see in your example, in the web section, I am binding the 'edge-client' to the public facing port of 1280. And on the private port 1281, I'm binding 'edge-management', 'fabric', and 'zac'.
But in the compose.yml file the only port variables I see being exposed are

      - ${ZITI_CTRL_ADVERTISED_PORT:-1280}
      - ${ZITI_ROUTER_PORT:-3022}

From looking at the docker-compose file from Local-Docker-Compose I see other port variables that are used, but I don't know which port variable I need to in the compose.yml to expose port 1281 for zac.
I suspect I need to modify the entrypoint; ports; and expose in the compose.yml?

    entrypoint:
      - bash
      - -euc
      - |
        ZITI_CMD+=" --ctrl-address ${ZITI_CTRL_ADVERTISED_ADDRESS:-quickstart}"\
        " --ctrl-port ${ZITI_CTRL_ADVERTISED_PORT:-1280}"\
        " --router-address ${ZITI_ROUTER_ADVERTISED_ADDRESS:-${ZITI_CTRL_ADVERTISED_ADDRESS:-quickstart}}"\
        " --router-port ${ZITI_ROUTER_PORT:-3022}"\
        " --password ${ZITI_PWD:-admin}"
    ports:
      - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_CTRL_ADVERTISED_PORT:-1280}:${ZITI_CTRL_ADVERTISED_PORT:-1280}
      - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_ROUTER_PORT:-3022}:${ZITI_ROUTER_PORT:-3022}
    expose:
      - ${ZITI_CTRL_ADVERTISED_PORT:-1280}
      - ${ZITI_ROUTER_PORT:-3022}

I didn't take into account that it's running in a container. Your private interface needs to listen on 0.0.0.0 instead of 127.0.0.1 or it won't be reachable from the Docker host.

  - name: private
    bindPoints:
      - interface: 0.0.0.0:1281
        address: 127.0.0.1:1281
    options:
      idleTimeout: 5000ms
      readTimeout: 5000ms

Then, your compose.yml can publish the additional port 1281.

    entrypoint:
      - bash
      - -euc
      - |
        ZITI_CMD+=" --ctrl-address ${ZITI_CTRL_ADVERTISED_ADDRESS:-quickstart}"\
        " --ctrl-port ${ZITI_CTRL_ADVERTISED_PORT:-1280}"\
        " --router-address ${ZITI_ROUTER_ADVERTISED_ADDRESS:-${ZITI_CTRL_ADVERTISED_ADDRESS:-quickstart}}"\
        " --router-port ${ZITI_ROUTER_PORT:-3022}"\
        " --password ${ZITI_PWD:-admin}"
    ports:
      - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_CTRL_ADVERTISED_PORT:-1280}:${ZITI_CTRL_ADVERTISED_PORT:-1280}
      - 127.0.0.1:1281:1281  # only publish mgmt port to Docker host's loopback
      - ${ZITI_INTERFACE:-0.0.0.0}:${ZITI_ROUTER_PORT:-3022}:${ZITI_ROUTER_PORT:-3022}
    expose:
      - ${ZITI_CTRL_ADVERTISED_PORT:-1280}
      - 1281 # mgmt port
      - ${ZITI_ROUTER_PORT:-3022}

There are no env vars like ZITI_* that configure a mgmt port. The configuration generator assumes there's one web listener with both client and management bindings, but that's just a starting point. It's perfectly fine to customize the configuration. Re-running ziti edge quickstart with the --home option means the configuration is generated only if it does not already exist.

BTW, earlier in this thread you linked to an old version of the all-in-one quickstart compose project. Here's the latest (default branch "main" instead of old default branch "release-next"): ziti/quickstart/docker/all-in-one at main ยท openziti/ziti ยท GitHub. This compose example uses the standard ziti-controller container image and simply runs ziti edge quickstart with additional configuration to simplify getting started and to enable the console.

Making the changes you suggested, and using the 'main' tag, I was able to make it work on my Proxmox server (x64 based) in a LXC running docker compose. I'm able to log in to the zac. But as soon as I tried to add an identity, I get an error about certificates.

could not get enrollment signer: could not determine enrollment signer: 
could not find a configured server certificate that matches hostname [---------------] in root controller identity nor in xweb identities

If I roll back to 1.1.15 tag or earlier then that certificate error goes away.

But what's weird, when I make the exact changes on my oracle vps (arm64) the container fails with a handshake error and a panic about quickstart-router missing. No matter which tag I use. What's more weird, I cannot roll back to the original working configuration. ie, even if I start from scratch, wipe everything in the working folder, using different tags (including the previously working tag of 1.1.11), ie. without splitting the edge-client from the zac, I get the same error below.

ERROR transport/v2/tls.(*sharedListener).processConn [tls:0.0.0.0:1280]: {remote=[-----------:39986] error=[tls: client didn't provide a certificate]} handshake failed
panic: open /home/ziggy/quickstart/quickstart-router.yaml: no such file or directory

This bug was fixed on the default branch "main," and the fix hasn't been released yet. I'm unsure if the bug was present in any prior releases. It may have been introduced and fixed between two releases.

When you said "'main' tag," did you mean that you ran this container image: openziti/ziti-controller:main? That's the bleeding-edge build, and it has the bugfix, but you must docker compose pull to get the latest image because tag :main is continually updated when changes merge to the default branch in GitHub, as is :latest for each stable release.

My goal in linking the newer compose.yml on branch "main" was to ensure you're benefiting from any improvements that may have occurred since the time the old one you'd linked earlier stopped being developed. I recommend setting your container image to the latest stable release tag which is currently :1.1.15, and :latest is usually fine too if you want your deployment to auto-upgrade on docker compose pull and restarting the container. I apologize for being unclear!

I'm trying to reproduce the problem. I was able to run a simplified quickstart with arm64 emulation and confirmed that the router was online and the console was available on https://127.0.0.1:1281/zac/. The handshake "error" isn't an error, per se, though it is misleadingly reported as one. It just means something connected and didn't authenticate with a certificate, which is normal for lots of legitimate clients of that TLS listener, like enrollees and those authenticating with a password. The panic due to a missing file is interesting, however. Does the file exist? Are you mounting a volume to store the stateful files like that router configuration YAML?

docker run --rm --platform linux/arm64 --entrypoint= \
--publish 127.0.0.1:1281:1281 \
--publish 127.0.0.1:3023:3023 \
docker.io/openziti/ziti-controller:1.1.15 \
ziti edge quickstart \
--ctrl-address 127.0.0.1 \
--ctrl-port 1281 \
--router-address 127.0.0.1 \
--router-port 3023 \
--password zitipw

Yes my .env file looks like this:

ZITI_CTRL_ADVERTISED_ADDRESS=my-vps-public-ip-address
ZITI_PWD=mysecretpassword
ZITI_CLI_TAG=latest  <-- changed from main to latest based on your comment.
ZITI_HOME=./config

No, that file does not exist in my VPS, but it also does not exist in my working LXC (x64) based test system either... What's weird, when I first tested out this all-in-one image several days ago, these files were in that folder.

quickstart-router.cas                                                                      
quickstart-router.cert                                                                     
quickstart-router.jwt                                                                      
quickstart-router.key                                                                      
quickstart-router.server.chain.cert                                                        
quickstart-router.yaml  

But after making some changes, these are the only files/folders in quickstart folder in both the x64 and the arm64 system but at that time the zac was accessible:

drwxr-xr-x 4 opc root   4096 Oct 11 21:23 .
drwxr-xr-x 4 opc root   4096 Oct 11 21:23 ..
-rw------- 1 opc root 524288 Oct 11 21:31 bbolt.db
-rw-r--r-- 1 opc root  10737 Oct 11 21:23 ctrl.yaml
drwxr-xr-x 2 opc root   4096 Oct 11 21:23 db
drwxr-xr-x 4 opc root   4096 Oct 11 21:23 pki

Perhaps, the LXC (x64) system just appear to be working b/c I'm able to log into the zac and add an identity, but I just haven't tried to use something that requires the quickstart-router yet?

I cleaned out all existing ziti-related images on the arm64 based VPS, started with a new folder/stack name and started from scratch using with a vanilla compose.yml from the link you provided (ie not trying to separate edge-client from the zac). I'm still getting the same error about quickstart-router.yaml. Suspecting a user permission issue, I tried a couple of different UIDs in the system, and even chmod (recursively) the config directory that contains quickstart to 777 and still the same error:

ERROR ziti/ziti/router.run: {configFile=[/home/ziggy/quickstart/quickstart-router.yaml] error=[open /home/ziggy/quickstart/quickstart-router.yaml: no such file or directory] revision=[0eec47ce3c80] os=[linux] version=[v1.1.15] arch=[arm64] build-date=[2024-10-02T13:03:23Z] go-version=[go1.23.1]} error loading ziti router config
panic: open /home/ziggy/quickstart/quickstart-router.yaml: no such file or directory

OK, you're bind-mounting a Docker host directory relative to the compose.yml file by setting ZITI_HOME=./config in the compose project env. That's valid.

Check the permissions on those files. That compose project is set to run ziti as UID 1000 unless you set ZIGGY_UID to something else. Is your user's UID 1000?

id -u

A normal all-in-one ZITI_HOME directory looks like this, assuming it's a directory named "config."

./config
โ””โ”€โ”€ quickstart
    โ”œโ”€โ”€ bbolt.db
    โ”œโ”€โ”€ ctrl.yaml
    โ”œโ”€โ”€ db
    โ”œโ”€โ”€ pki
    โ”‚   โ”œโ”€โ”€ intermediate-ca
    โ”‚   โ”‚   โ”œโ”€โ”€ certs
    โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ client.cert
    โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ client.chain.pem
    โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ intermediate-ca.cert
    โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ intermediate-ca.chain.pem
    โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ server.cert
    โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ server.chain.pem
    โ”‚   โ”‚   โ”œโ”€โ”€ crlnumber
    โ”‚   โ”‚   โ”œโ”€โ”€ crls
    โ”‚   โ”‚   โ”œโ”€โ”€ index.txt
    โ”‚   โ”‚   โ”œโ”€โ”€ index.txt.attr
    โ”‚   โ”‚   โ”œโ”€โ”€ keys
    โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ client.key
    โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ intermediate-ca.key
    โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ server.key
    โ”‚   โ”‚   โ””โ”€โ”€ serial
    โ”‚   โ””โ”€โ”€ root-ca
    โ”‚       โ”œโ”€โ”€ certs
    โ”‚       โ”‚   โ”œโ”€โ”€ intermediate-ca.cert
    โ”‚       โ”‚   โ””โ”€โ”€ root-ca.cert
    โ”‚       โ”œโ”€โ”€ crlnumber
    โ”‚       โ”œโ”€โ”€ crls
    โ”‚       โ”œโ”€โ”€ index.txt
    โ”‚       โ”œโ”€โ”€ index.txt.attr
    โ”‚       โ”œโ”€โ”€ keys
    โ”‚       โ”‚   โ”œโ”€โ”€ intermediate-ca.key
    โ”‚       โ”‚   โ””โ”€โ”€ root-ca.key
    โ”‚       โ””โ”€โ”€ serial
    โ”œโ”€โ”€ quickstart-router.cas
    โ”œโ”€โ”€ quickstart-router.cert
    โ”œโ”€โ”€ quickstart-router.jwt
    โ”œโ”€โ”€ quickstart-router.key
    โ”œโ”€โ”€ quickstart-router.server.chain.cert
    โ””โ”€โ”€ quickstart-router.yaml

11 directories, 29 files

It's possible that generating a configuration on the first run hit a snag and never generated a router configuration. If so, you can delete the contents of the directory and re-run it to start fresh. A log line like this indicates it has completed the first run successfully.

INFO ziti/router/state.(*apiSessionAddedHandler).applySync: finished synchronizing api sessions [count: 3, syncId: cm26bpg3m000101knvyopjz87, duration: 10.557ยตs]

Thank you for your patience and guidance!
I wiped my LXC, emptied out the folder/stack, which is in my user's home folder (~/) and started from scratch again. eg. /home/myusername/ziti/
On this machine my logged in user is UID 1000.
First I simply followed this without any changes. The docker compose up command successfully ends shortly after

INFO ziti/router/state.(*apiSessionAddedHandler).applySync: finished synchronizing api sessions 

So then I added the env_file: ".env" variable to the compose file and created a .env file like the one above to bind-mount the config folder eg. /home/myusername/ziti/config. Then I try to recreate with one of these commands below:

docker compose up --force-recreate quickstart
--or--
docker compose down -v --remove-orphans
sudo rm -r config/
docker compose up

Both of these methods result in the container failing to successfully create and ends with a timeout and the system restarting over and over:

I should say, it doesn't matter if I bind-mount by using the .env file or by changing the compose.yml file to ./config:/home/ziggy. The issue seems to be specifying the bind-mount...

quickstart-1  | [   0.336]    INFO ziti/controller/server.NewController: edge controller instance id: cm26dbqts000001osth4fkwkk
quickstart-1  | [   0.336]    INFO ziti/controller.(*Controller).RegisterXmgmt: adding xmgmt *server.submgmt, enabled? true
quickstart-1  | [   0.336]    INFO ziti/controller/server.(*Controller).Initialize: initializing edge
quickstart-1  | [   0.342]    INFO ziti/controller/internal/policy.NewSessionEnforcer: {sessionTimeout=[30m0s] frequency=[5s]} session enforcer configured
quickstart-1  | [   0.343]    INFO ziti/controller/server.(*Controller).Run: starting edge
quickstart-1  | [   0.343]    INFO ziti/controller.(*Controller).Run.GoroutinesPoolMetricsConfigF.func1.1: {maxWorkers=[16] poolType=[pool.listener.ctrl] minWorkers=[1] idleTime=[10s] maxQueueSize=[1]} starting goroutine pool
quickstart-1  | [   0.347]    INFO channel/v3.(*UnderlayDispatcher).Run: started
quickstart-1  | [   0.348]    INFO ziti/controller/server.(*Controller).checkEdgeInitialized: edge initialized
quickstart-1  | [   0.416]    INFO ziti/controller/zac.ZitiAdminConsoleFactory.New: initializing ZAC SPA Handler from /ziti-console
quickstart-1  | [   0.416]    INFO xweb/v2.(*Server).Start: starting ApiConfig to listen and serve tls on 0.0.0.0:1280 for server client-management with APIs: [edge-management edge-client fabric zac]
quickstart-1  | [   0.417]    INFO ziti/controller/network.(*Network).Run: started
quickstart-1  | timed out waiting for controller: https://my_proxmox_public_ip:1280    <---------- time out here then the container restarts (and proceeds to boot loop)
quickstart-1  | Environment left intact at: /home/ziggy/quickstart

I then repeated the same process on the arm64 VPS. My logged in user is 1001 on this server.
If I don't use the .env and use the default compose.yml settings (either UID-1000 or changing it to 1001), the system successfully come up to:

INFO ziti/router/state.(*apiSessionAddedHandler).applySync: finished synchronizing api sessions

But if I bind-mount the config folder using the .env file or by specifying it in the compose.yml then the I get a similar same behavior as on LXC server with timeout and boot looping, but the log is a little different:

[   0.803]    INFO xweb/v2.(*Server).Start: starting ApiConfig to listen and serve tls on 0.0.0.0:1280 for server client-management with APIs: [edge-management edge-client fabric zac]
[   0.804]    INFO ziti/controller/network.(*Network).Run: started
[   0.863]    INFO ziti/ziti/cmd/edge.(*QuickstartOpts).run: Controller online. Continuing...
[   0.863]   ERROR ziti/ziti/router.run: {version=[v1.1.15] go-version=[go1.23.1] configFile=[/home/ziggy/quickstart/quickstart-router.yaml] arch=[arm64] revision=[0eec47ce3c80] build-date=[2024-10-02T13:03:23Z] os=[linux] error=[open /home/ziggy/quickstart/quickstart-router.yaml: no such file or directory]} error loading ziti router config
panic: open /home/ziggy/quickstart/quickstart-router.yaml: no such file or directory
goroutine 33 [running]:
github.com/openziti/ziti/ziti/router.run(0x4000806608, {0x40024874f0, 0x1, 0x3abf0dc?})
	github.com/openziti/ziti/ziti/router/run.go:66 +0x1200
github.com/spf13/cobra.(*Command).execute(0x4000806608, {0x4002487490, 0x1, 0x1})
	github.com/spf13/cobra@v1.8.1/command.go:989 +0x81c
github.com/spf13/cobra.(*Command).ExecuteC(0x4000806608)
	github.com/spf13/cobra@v1.8.1/command.go:1117 +0x344
github.com/spf13/cobra.(*Command).Execute(...)
	github.com/spf13/cobra@v1.8.1/command.go:1041
github.com/openziti/ziti/ziti/cmd/edge.(*QuickstartOpts).run.func2()
	github.com/openziti/ziti/ziti/cmd/edge/quickstart.go:303 +0xa4
created by github.com/openziti/ziti/ziti/cmd/edge.(*QuickstartOpts).run in goroutine 1
	github.com/openziti/ziti/ziti/cmd/edge/quickstart.go:297 +0x13f0
DEBUG: run command is: ziti edge quickstart --home /home/ziggy/quickstart  --ctrl-address my_vps_public_ip --ctrl-port 1280 --router-address my_vps_public_ip --router-port 3022 --password my_password
Controller running... Configuring and starting Router...
[   0.000]    INFO ziti/ziti/cmd/edge.(*QuickstartOpts).run: permanent --home '/home/ziggy/quickstart' will not be removed on exit
[   0.010] WARNING ziti/controller/config.LoadConfig: this environment is using a default generated trust domain [spiffe://00b244da3c76803c8ef3829afe17cf01fc33b459], it is recommended that a trust domain is specified in configuration via URI SANs or the 'trustDomain' field
[   0.010] WARNING ziti/controller/config.LoadConfig: this environment is using a default generated trust domain [spiffe://00b244da3c76803c8ef3829afe17cf01fc33b459], it is recommended that if network components have enrolled that the generated trust domain be added to the configuration field 'additionalTrustDomains' array when configuring a explicit trust domain
[   0.011]    INFO ziti/ziti/controller.run: {version=[v1.1.15] os=[linux] go-version=[go1.23.1] build-date=[2024-10-02T13:03:23Z] nodeId=[client] revision=[0eec47ce3c80] arch=[arm64]} starting ziti-controller
[   0.015]    INFO ziti/controller/db.RunMigrations.(*migrationManager).Migrate.func1: edge datastore is up to date at version 37
[   0.659]    INFO ziti/common/metrics.ConfigureGoroutinesPoolMetrics.GoroutinesPoolMetricsConfigF.func1.1: {poolType=[pool.router.messaging] maxWorkers=[100] idleTime=[30s] maxQueueSize=[100] minWorkers=[0]} starting goroutine pool
[   0.659]    INFO ziti/controller/network.(*Network).showOptions: network = {
  "CreateCircuitRetries": 2,
  "CycleSeconds": 60,
  "EnableLegacyLinkMgmt": false,
  "InitialLinkLatency": 65000000000,
  "IntervalAgeThreshold": 0,
  "MetricsReportInterval": 60000000000,
  "MinRouterCost": 10,
  "PendingLinkTimeout": 10000000000,
  "RouteTimeout": 10000000000,
  "RouterConnectChurnLimit": 60000000000,
  "RouterComm": {
    "QueueSize": 100,
    "MaxWorkers": 100
  },

  "Smart": {
    "RerouteFraction": 0.02,
    "RerouteCap": 4,
    "MinCostDelta": 15
  }
}
[   0.660]    INFO ziti/controller/webapis.NewFabricManagementApiFactory: initializing management api factory with 0 xmgmt instances
[   0.660]    INFO ziti/controller.(*Controller).showOptions: ctrl = {
  "OutQueueSize": 4,
  "MaxQueuedConnects": 1,
  "MaxOutstandingConnects": 16,
  "ConnectTimeout": 5000000000,
  "DelayRxStart": false,
  "WriteTimeout": 0,
  "MessageStrategy": null,
  "NewListener": null,
  "AdvertiseAddress": {},
  "RouterHeartbeatOptions": {
    "sendInterval": 10000000000,
    "checkInterval": 1000000000,
    "closeUnresponsiveTimeout": 30000000000
  },
  "PeerHeartbeatOptions": {
    "sendInterval": 10000000000,
    "checkInterval": 1000000000,
    "closeUnresponsiveTimeout": 30000000000
  }
}
[   0.660]    INFO ziti/controller/server.NewController: edge controller instance id: cm26f7old000001qm1ulbr7mb
[   0.660]    INFO ziti/controller.(*Controller).RegisterXmgmt: adding xmgmt *server.submgmt, enabled? true
[   0.660]    INFO ziti/controller/server.(*Controller).Initialize: initializing edge
[   0.663]    INFO ziti/controller/internal/policy.NewSessionEnforcer: {frequency=[5s] sessionTimeout=[30m0s]} session enforcer configured
[   0.663]    INFO ziti/controller/server.(*Controller).Run: starting edge
[   0.663]    INFO ziti/controller.(*Controller).Run.GoroutinesPoolMetricsConfigF.func1.1: {poolType=[pool.listener.ctrl] minWorkers=[1] maxWorkers=[16] idleTime=[10s] maxQueueSize=[1]} starting goroutine pool
[   0.664]    INFO channel/v3.(*UnderlayDispatcher).Run: started
[   0.665]    INFO ziti/controller/server.(*Controller).checkEdgeInitialized: edge initialized
[   0.697]   ERROR transport/v2/tls.(*sharedListener).processConn [tls:0.0.0.0:1280]: {remote=[my_vps_public_ip:56112] error=[tls: client didn't provide a certificate]} handshake failed
[   0.779]   ERROR transport/v2/tls.(*sharedListener).processConn [tls:0.0.0.0:1280]: {remote=[my_vps_public_ip:56120] error=[tls: client didn't provide a certificate]} handshake failed
[   0.808]    INFO ziti/controller/zac.ZitiAdminConsoleFactory.New: initializing ZAC SPA Handler from /ziti-console
[   0.809]    INFO xweb/v2.(*Server).Start: starting ApiConfig to listen and serve tls on 0.0.0.0:1280 for server client-management with APIs: [edge-management edge-client fabric zac]
[   0.810]    INFO ziti/controller/network.(*Network).Run: started
[   0.863]    INFO ziti/ziti/cmd/edge.(*QuickstartOpts).run: Controller online. Continuing...
[   0.863]   ERROR ziti/ziti/router.run: {version=[v1.1.15] go-version=[go1.23.1] error=[open /home/ziggy/quickstart/quickstart-router.yaml: no such file or directory] os=[linux] arch=[arm64] build-date=[2024-10-02T13:03:23Z] revision=[0eec47ce3c80] configFile=[/home/ziggy/quickstart/quickstart-router.yaml]} error loading ziti router config
panic: open /home/ziggy/quickstart/quickstart-router.yaml: no such file or directory
goroutine 146 [running]:
github.com/openziti/ziti/ziti/router.run(0x4003032008, {0x4001a907d0, 0x1, 0x1?})
	github.com/openziti/ziti/ziti/router/run.go:66 +0x1200
github.com/spf13/cobra.(*Command).execute(0x4003032008, {0x4001a90740, 0x1, 0x1})
	github.com/spf13/cobra@v1.8.1/command.go:989 +0x81c
github.com/spf13/cobra.(*Command).ExecuteC(0x4003032008)
	github.com/spf13/cobra@v1.8.1/command.go:1117 +0x344
github.com/spf13/cobra.(*Command).Execute(...)
	github.com/spf13/cobra@v1.8.1/command.go:1041
github.com/openziti/ziti/ziti/cmd/edge.(*QuickstartOpts).run.func2()
	github.com/openziti/ziti/ziti/cmd/edge/quickstart.go:303 +0xa4
created by github.com/openziti/ziti/ziti/cmd/edge.(*QuickstartOpts).run in goroutine 1
	github.com/openziti/ziti/ziti/cmd/edge/quickstart.go:297 +0x13f0