Skip to main content
Star us on GitHub Star

Local - With Docker

Docker is a popular container engine, and many developers enjoy using solutions delivered via Docker. Ziti provides a single Docker container which contains the entire stack of Ziti components. This is not the most common mechanism for deploying containers, we recognize that. However, we think that this makes it a bit easier for people to get started with deploying Ziti components using Docker. We will certainly look to create individual containers for each component in the future but for now it's a single container. You can get this container by issuing docker pull openziti/quickstart:latest.

Starting the Controller

All Ziti Networks require a Ziti Controller. Without a controller, edge routers won't be able to authorize new connections rendering a new network useless. You must have a controller running.

Required - Docker Named Volume

Running Ziti locally via Docker will require you to create a "named volume" in docker where any and all persistent files will be saved.

Create the named volume now using this command:

docker volume create myPersistentZitiFiles

Required - Docker Network

Other containers on the Docker network will need to address the controller. To do this, the container requires a network alias. This forces you to add the container to a network which is not the default network.

Create the docker network now using this command:

docker network create myFirstZitiNetwork

When starting containers participating in this OpenZiti Network, the docker network name will be supplied as a parameter to the docker command. It's important for containers to be able to address other containers on the docker network, this requires predictable container names on the docker network. When looking at the example commands below, these options are the ones controlling the network name and network alias on the network: --network myFirstZitiNetwork --network-alias ziti-controller.

Optional - Expose Controller Port

Docker containers by default won't expose any ports that you could use from your local machine. If you want to be able to use this controller from outside of Docker, you'll need to export the controller's API port. That's easy to do, simply pass one more parameter to the docker command: -p ${externalPort}:${internalPort}

Running the Controller

Here's an example of how to launch a controller using the folder created in the steps above. Also, notice this command passes a couple extra flags you'll see used on this page. Notably the --rm flag and the -it flag. The --rm flag instructs Docker to delete the container when the container exits. The -it flag will run the container interactively. Running interactively like this makes it easier to see the logs produced, but you will need a terminal for each process you want to run. The choice is yours, but in these examples we'll use -it to make seeing the output from the logs easier.

Here's an example which will use the Docker network named "myFirstZitiNetwork" and expose the controller to your local computer on port 1280 (the default port).

docker run \
--name ziti-controller \
-e ZITI_CTRL_ADVERTISED_ADDRESS=ziti-edge-controller \
--network myFirstZitiNetwork \
--network-alias ziti-controller \
--network-alias ziti-edge-controller \
-p 1280:1280 \
-it \
--rm \
-v myPersistentZitiFiles:/persistent \
openziti/quickstart \

Create Edge Router Policies

OpenZiti requires explicit authorization of identities using (edge router policies), as well as authorization of services and routers using (service edge router policies). The docker-based quickstart doesn't perform these steps automatically. Run the initialization container one time, after starting the controller as shown

docker run \
--network myFirstZitiNetwork \
--network-alias ziti-controller-init-container \
-it \
--rm \
-v myPersistentZitiFiles:/persistent \
openziti/quickstart \
/var/openziti/scripts/ /var/openziti/scripts/

Edge Router

At this point you should have a Ziti Controller running. You should have created your Docker network as well as creating the volume mount. Now it's time to connect your first edge router. The same Docker image that runs the controller can run an edge router. To start an edge router, you will run a very similar command as the one to start the controller with a couple of key differences.

The first noticeable difference is that we need to pass in the name of the edge router we want it to be. To use this network, the name supplied needs tobe addressable by clients. Also notice the port exported is port 3022. This is the default port used by edge routers.

docker run \
--name ziti-edge-router-1 \
-e ZITI_ROUTER_NAME=ziti-edge-router-1 \
-e ZITI_ROUTER_ADVERTISED_ADDRESS=ziti-edge-router-1 \
--network myFirstZitiNetwork \
--network-alias ziti-edge-router-1 \
-p 3022:3022 \
-it \
--rm \
-v myPersistentZitiFiles:/persistent \
openziti/quickstart \
/var/openziti/scripts/ edge

If you want to create a second edge router, you'll need to override the router port, don't forget to export that port too

docker run \
--name ziti-edge-router-2 \
-e ZITI_ROUTER_NAME=ziti-edge-router-2 \
-e ZITI_ROUTER_ADVERTISED_ADDRESS=ziti-edge-router-2 \
--network myFirstZitiNetwork \
--network-alias ziti-edge-router-2 \
-p 4022:4022 \
-it \
--rm \
-v myPersistentZitiFiles:/persistent \
openziti/quickstart \
/var/openziti/scripts/ edge

Testing the Network

Using Docker Locally

Using the OpenZiti Network outside the docker environment is somewhat complex. The aliases chosen when starting the docker containers need to be addressable from wherever a client is connecting. This includes the ziti CLI, tunnelers, SDKs, etc. This quickstart expects you understand this and every router added to the overlay will require a route to the alias used. The easiest way to accomplish this is to use the operating system's "hosts file" but a nameserver such as a pi hole also works well. Understanding this concept in-depth is out of scope of this guide. It is assumed you have added the following entries to your operating system's hosts file or DNS nameserver:

  • ziti-edge-controller
  • ziti-edge-router-1
  • ziti-edge-router-2


With the controller and router running, you can now attach to the Docker host running the Ziti controller and test that the router did indeed come online and is running as you expect. To do this, we'll use another feature of the docker command and exec into the machine. First, you'll need to know your Docker container name which you can figure out by running docker ps.

$ docker ps

1b86c4b461e7 openziti/quickstart "/var/openziti/scripts/r…" 10 minutes ago Up 10 minutes>3022/tcp, :::3022->3022/tcp musing_engelbart
a33d58248d6e openziti/quickstart "/var/openziti/scripts/r…" 46 minutes ago Up 46 minutes>1280/tcp, :::1280->1280/tcp xenodochial_cori

Above, you'll see my controller is running in a container named "xenodochial_cori". I can tell because it's using the default port of 1280, the default port for the controller. Now I can exec into this container: docker exec -it xenodochial_cori /bin/bash

Once in the container, I can now issue zitiLogin to authenticate the ziti CLI.

Token: b16f182f-88b3-4fcc-9bfc-1e32319ca486
Saving identity 'default' to /persistent/ziti-cli.json

And finally, once authenticated I can test to see if the edge router is online in the controller and as you'll see, the isOnline property is true!

ziti@a33d58248d6e:/persistent$ ziti edge list edge-routers
id: qNZyqZEix3 name: ziti-edge-router-1 isOnline: true role attributes: {}
results: 1-1 of 1

Next Steps

    Try the Wizard