title: Building a Redis cluster using docker images on top of Vagrant: Cannot ping machines
body: <p>I'm trying to build a simple redis cluster locally on OSX, using docker inside virtualbox VMS. Specifically, I want to create a master redis node (192.168.0.100) with two slaves (.101 and .102). This involves configuring each machine and issuing a command to each slave to tell it who the master is in the key-value-store relationship.</p>
  
  <p>This worked great, until I decided to make my configuration more flexible by doing some programmatic stuff inside my Vagrantfile. The result is that I am unable to even ping any of the machines beside .102, let alone uses redis-cli commands (for example, <code>redis-cli -h 192.168.0.100 INFO</code> to see that the master has slaves set up correctly)</p>
  
  <p>My goals/constraints:</p>
  
  <ul>
  <li>Run docker inside a virtualbox VM: I saw several ways to do this when reading the docs. I chose the way I do it because I don't want to refer to a ton of external files.</li>
  <li>Run a sequence of commands on each VM after configuration to set slaves and whatnot.</li>
  <li>I'd prefer not to just use boot2docker as I have a bunch other stuff I'm gonna be adding... twemproxy, sentinel and I want to simulate a production environment at least a little bit.</li>
  </ul>
  
  <p>What am I doing wrong in my new file?</p>
  
  <p>EDIT: I've investigated a bit more. One thing I tried was destroying all images, then running the old vagrant file to build the machines, and then reloading them with the new vagrant file. In this scenario, the machines worked, though each time I'd see authentication failure messages like <code>redis1: Warning: Authentication failure. Retrying...</code> after the machine had gone up. I was able to ping the machine no problem though.</p>
  
  <hr>
  
  <p>New Vagrantfile (uses config file below):</p>
  
  <pre><code>require './config.rb'
  include RedisClusterConfig
  
  Vagrant.configure(2) do |config|
      config.vm.provider "virtualbox"
  
      ## Redis Nodes (Can define multiple triplets) ##
      for node in RedisClusterConfig.redisNodes
          config.vm.define node.name do |a|
              a.vm.hostname = node.name
              a.vm.box = "ubuntu/trusty64"
  
              # Skip checking for an updated Vagrant box
              a.vm.box_check_update = false
  
              # Networking
              a.vm.network :private_network, ip: node.address
              a.ssh.forward_agent = true
              a.ssh.insert_key = false
  
              # Set up docker with 'redis' image
              a.vm.provision "docker" do |d|
                  d.images = ["redis"]
                  d.run "redis", name: "redis", args: "-p "+node.port+":"+node.port
              end
  
              # Additional configuration
              a.trigger.after [:up, :resume, :reload, :provision] do
                  # Master/slave
                  unless node.slaveOfAddress.nil?
                      system("redis-cli -h " + node.address + " SLAVEOF " + node.slaveOfAddress + " " + node.slaveOfPort)
                      puts "Finished setting up slave node: " + node.name
                  else
                      puts "Finished setting up master node: " + node.name
                  end
              end
          end 
      end
  
  end
  </code></pre>
  
  <p>config.rb:</p>
  
  <pre><code>module RedisClusterConfig
      attr_reader :redisNodes 
  
      RedisNode = Struct.new("RedisNode", :name, :address, :port, :slaveOfAddress, :slaveOfPort)
  
      p = "6379" # Default redis port
      baseAddr = "192.168.0."
  
      # Define a triplet
      redis0 = RedisNode.new("redis0", baseAddr + "100", p, nil, nil)
      redis1 = RedisNode.new("redis1", baseAddr + "101", p, baseAddr + "100", p)
      redis2 = RedisNode.new("redis2", baseAddr + "102", p, baseAddr + "100", p)
  
      @redisNodes = [redis0, redis1, redis2]
  end
  </code></pre>
  
  <hr>
  
  <p>Old Vagrantfile:</p>
  
  <pre><code># Make sure you have triggers plugin:
  #     vagrant plugin install vagrant-triggers
  #
  # TODO:
  # - We really would like to run some shell commands after everything is done, not after each machine is provisioned
  
  Vagrant.configure(2) do |config|
      config.vm.provider "virtualbox"
  
      ## Redis Nodes ##
  
      ### Master Node###
      config.vm.define "redis0" do |a|
          a.vm.hostname = "redis0"
          a.vm.box = "ubuntu/trusty64"
  
          # Skip checking for an updated Vagrant box
          a.vm.box_check_update = false
  
          # Networking
          a.vm.network :private_network, ip: "192.168.0.100"
          a.ssh.forward_agent = true
          a.ssh.insert_key = false
  
          a.vm.provision "docker" do |d|
            d.images = ["redis"]
            d.run "redis",
              name: "redis",
              args: "-p 6379:6379"
          end
      end
  
      ### Slave Nodes ###
      config.vm.define "redis1" do |a|
          a.vm.hostname = "redis1"
          a.vm.box = "ubuntu/trusty64"
  
          # Skip checking for an updated Vagrant box
          a.vm.box_check_update = false
  
          # Networking
          a.vm.network :private_network, ip: "192.168.0.101"
          a.ssh.forward_agent = true
          a.ssh.insert_key = false
  
          a.vm.provision "docker" do |d|
            d.images = ["redis"]
            d.run "redis",
              name: "redis",
              args: "-p 6379:6379"
          end
      end
  
      config.vm.define "redis2" do |a|
          a.vm.hostname = "redis2"
          a.vm.box = "ubuntu/trusty64"
  
          # Skip checking for an updated Vagrant box
          a.vm.box_check_update = false
  
          # Networking
          a.vm.network :private_network, ip: "192.168.0.102"
          a.ssh.forward_agent = true
          a.ssh.insert_key = false
  
          a.vm.provision "docker" do |d|
            d.images = ["redis"]
            d.run "redis",
              name: "redis",
              args: "-p 6379:6379"
          end
      end
  
      # After everything else has finished provisioning...
      config.trigger.after [:up, :resume, :reload] do
          # Configuring redis master/slave triplet
          system('echo Configuring redis master/slave triplet...')
          system('redis-cli -h 192.168.0.101 SLAVEOF 192.168.0.100 6379')
          system('redis-cli -h 192.168.0.102 SLAVEOF 192.168.0.100 6379')
      end
  
  end
  </code></pre>