This tutorial guides you through the process of deploying two nodes using Docker


The tutorial assumes you have an XMPP server up and running, with user accounts and a group setup, as described in the tutorial on deploying an XMPP server using Docker

Configure host network and directories

First, you need to install Docker and Open vSwitch and create a network namespace in the Docker host:

curl -fsSL | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] bionic stable"
sudo apt-get update -y
sudo apt-get install -y openvswitch-switch \
                        python3 python3-pip python3-venv \
                        apt-transport-https \
                        ca-certificates \
                        curl git \
                        software-properties-common \
                        docker-ce-cli \
sudo groupadd -f docker
sudo usermod -a -G docker $USER
sudo docker network create dkrnet

**Note: Make sure you log out and back in again so the docker group addition is in effect

**Note: If you are using Ubuntu 20.04, start OVS manually:

sudo systemctl start ovs-vswitchd.service

Now, create directories in the host to hold configuration files and logs for your containers:

mkdir evio
cd evio
mkdir config
mkdir logs
mkdir logs/001
mkdir logs/002

Setup configuration files

First, let’s create a configuration file for a container that uses XMPP user test1. You may change the name of the user below.

Copy and save this as /home/$USER/evio/config/config-001.json (the directory you created in the previous step) - make sure you replace A.B.C.D with the IP address of your XMPP host:

  "CFx": {
    "Model": "Default",
    "Overlays": [
  "Logger": {
    "LogLevel": "DEBUG",
    "Device": "File",
    "Directory": "/var/log/edge-vpnio/",
    "CtrlLogFileName": "ctrl.log",
    "TincanLogFileName": "tincan_log",
    "MaxFileSize": 10000000,
    "MaxArchives": 1
  "Signal": {
    "Enabled": true,
    "Overlays": {
      "101000F": {
        "HostAddress": "A.B.C.D",
        "Port": "5222",
        "Username": "test1@openfire.local",
        "Password": "password_test1",
        "AuthenticationMethod": "PASSWORD"
  "Topology": {
    "PeerDiscoveryCoalesce": 1,
    "Overlays": {
      "101000F": {
        "Name": "SymphonyRing",
        "Description": "Scalable Symphony Ring Overlay for Bounded Flooding.",
        "MaxSuccessors": 2,
        "MaxOnDemandEdges": 1,
        "MaxConcurrentEdgeSetup": 5,
        "Role": "Switch"
  "LinkManager": {
    "Dependencies": [
    "Stun": [
    "Overlays": {
      "101000F": {
        "Type": "TUNNEL",
        "TapName": "tnl-"
  "UsageReport": {
    "Enabled": true,
    "TimerInterval": 3600,
    "WebService": ""
  "BridgeController": {
    "Dependencies": [
    "BoundedFlood": {
      "OverlayId": "101000F",
      "LogDir": "/var/log/edge-vpnio/",
      "LogFilename": "bf.log",
      "LogLevel": "INFO",
      "BridgeName": "edgbr",
      "DemandThreshold": "100M",
      "FlowIdleTimeout": 60,
      "FlowHardTimeout": 60,
      "MulticastBroadcastInterval": 60,
      "MaxBytes": 10000000,
      "BackupCount": 0,
      "ProxyListenAddress": "",
      "ProxyListenPort": 5802,
      "MonitorInterval": 60,
      "MaxOnDemandEdges": 0
    "Overlays": {
      "101000F": {
        "NetDevice": {
          "AutoDelete": true,
          "Type": "OVS",
          "SwitchProtocol": "BF",
          "NamePrefix": "edgbr",
          "MTU": 1410,
          "AppBridge": {
            "AutoDelete": true,
            "Type": "OVS",
            "NamePrefix": "brl",
            "IP4": "",
            "PrefixLen": 24,
            "MTU": 1410,
            "NetworkAddress": ""
        "SDNController": {
          "ConnectionType": "tcp",
          "HostName": "",
          "Port": "6633"

To configure the second container, copy config-001.json to config-002.json, and replace the following entry in the json file to set up another IP address:

        "IP4": "",

Start the containers

Now you will run two containers, named evio001 and evio002, mapping the different configuration file and the log directories to different mount points. Note: the examples below use the dkrnet network and Docker NAT. This requires TURN if you connect multiple hosts. If you plan to run a single container in your host, it’s advisable you use the host’s network instead, by replacing dkrnet by host below.

Instructions for Evio 20.12.0 and above:

NOTE Evio versions 20.12.0+ have moved the configuration file location to /etc/opt/evio:

docker run -d -v /home/$USER/evio/config/config-001.json:/etc/opt/evio/config.json -v /home/$USER/evio/logs/001:/var/log/edge-vpnio/ --rm --privileged --name evio001 --network dkrnet edgevpnio/evio-node:20.12.0 /sbin/init

docker run -d -v /home/$USER/evio/config/config-002.json:/etc/opt/evio/config.json -v /home/$USER/evio/logs/002:/var/log/edge-vpnio/ --rm --privileged --name evio002 --network dkrnet edgevpnio/evio-node:20.12.0 /sbin/init

Test your connection

You can open a shell into the container evio001 (virtual IP address, and ping the evio002 node (virtual IP

docker exec -it evio001 /bin/bash
# ping

Or, the other way around:

docker exec -it evio002 /bin/bash
# ping