How to create repeatable development environments on KVM on Power using Vagrant and Docker

Continuing our series on Vagrant usage with KVM on Power, in this article we’ll see how to create repeatable development environments using Vagrant and Docker.

Developers working on the Intel platform might be already familiar with this approach of creating repeatable development environments. The process is very similar for Power platform, with some minor differences to handle the platform nuances.

The example setup looks like the following.

vagrant_pkvm_docker

The docker container will be created on a virtual machine, and both the docker container and the virtual machine will be created by Vagrant. Using the Vagrant Docker provider, we can create multiple docker containers on same VM or different VMs.

The basic format of the Vagrantfile for creating Docker containers on VMs looks like the following

*******Container Vagrantfile***********

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define "" do |c|
      a.vm.provider "docker" do |d|
         #docker commands for building and running
         d.force_host_vm = true
    
         d.vagrant_machine = ""
         d.vagrant_vagrantfile = ""
       end
    
   end
end

*******Container Vagrantfile***********

The directory structure for my development TP looks like this

~/vagrant-box : contains the Vagrantfile for the VM

~/vagrant-box/docker-wordpress : contains the Vagrantfile for the container, Dockerfile and associated scripts required to build the docker container.

The docker container related files used in this article is available from my github repo – https://github.com/bpradipt/docker-wordpress.git , branch wordpress-ssh. You will be required to change the FROM statement accordingly

The docker container used in this example has ssh installed which allows using ‘vagrant ssh’ seamlessly with containers.

Additionally ensure that the vagrant box you are using have sufficient disk space for creating multiple containers.

Vagrantfiles

Vagrantfile for the VM – DockerVMVagrantfile

[pradipta@voldemort vagrant-box]$ cat DockerVMVagrantfile 
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
 config.vm.provider :libvirt do |libvirt|
       libvirt.host = "my.powerkvm.host"
       libvirt.connect_via_ssh = "true"
       libvirt.uri = "qemu+ssh://root@my.powerkvm.host/system"
       libvirt.management_network_name = "default"
       libvirt.management_network_address = "192.168.122.0/24"
  end

  config.vm.define :test1 do |test1|
    test1.vm.box = "xenial-ppc64le.box"
    test1.vm.box_url = "http:///my.fileserver.com/xenial-ppc64le.box"
    test1.vm.provider :libvirt do |domain|
      domain.memory = 2048
      domain.cpus = 1
      domain.video_type = "vga"
    end
  end
 #Install docker for Ubuntu LE from custom location 
  config.vm.provision "shell", path: "install_docker.sh"
end

install_docker.sh is a simple shell script to download docker for Ubuntu LEĀ from Unicamp repository. You can also install docker from Ubuntu universe repository.

[pradipta@voldemort vagrant-box]$ cat install_docker.sh
#!/bin/bash
RET=`dpkg -s docker-engine 2>/dev/null`
if [ $? != 0 ]
then
 echo deb [trusted=yes] http://ftp.unicamp.br/pub/ppc64el/ubuntu/16_04/docker-17.05.0-ce-ppc64el xenial main > /etc/apt/sources.list.d/xenial-docker.list
 sudo apt-get update
 sudo apt-get install -y docker-engine

 #Add the vagrant user to docker group
 sudo adduser vagrant docker
 #Restart docker
 sudo service docker restart
 #kill all ssh connections from vagrant to the VM
 ps aux | grep 'sshd:' | awk '{print $2}' | xargs kill
fi

Vagrantfile for Docker container – Vagrantfile
This will reference the VM Vagrantfile ie, DockerVMVagrantfile

[pradipta@voldemort docker-wordpress]$ cat Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define "wordpress" do |a|
    a.vm.provider "docker" do |d|
      d.build_dir = "."
      d.build_args = ["--rm=true", "--tag=bpradipt/wordpress"]
      d.ports = ["80:80"]
      d.name = "wordpress"
      d.has_ssh = true
      d.force_host_vm = true
      d.remains_running = true
      d.vagrant_machine = "test1"
      d.vagrant_vagrantfile = "../DockerVMVagrantfile"
    end    
  end
end

Dockerfile

Following is the Dockerfile used

FROM my.private.docker.registry/pradipta/ubuntu_ppc64le
MAINTAINER Pradipta Kumar Banerjee <pradipta.banerjee@gmail.com>
RUN apt-get update 
RUN apt-get -y upgrade
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-client \
mysql-server apache2 libapache2-mod-php5 pwgen python-setuptools vim-tiny \
php5-mysql php5-ldap openssh-server apt-utils

#User config
RUN echo 'root:root123' | chpasswd
RUN adduser vagrant
RUN echo 'vagrant:vagrant' | chpasswd

#SSH configuration
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' \
    /etc/ssh/sshd_config
ADD key/vagrant.pub /home/vagrant/.ssh/authorized_keys
RUN chown -R vagrant:vagrant /home/vagrant/
RUN chmod 700 /home/vagrant/.ssh/
RUN chmod 600 /home/vagrant/.ssh/authorized_keys
RUN mkdir -p /var/run/sshd

RUN easy_install supervisor
ADD ./scripts/start.sh /start.sh
ADD ./scripts/foreground.sh /etc/apache2/foreground.sh
ADD ./configs/supervisord.conf /etc/supervisord.conf
ADD ./configs/000-default.conf /etc/apache2/sites-available/000-default.conf
RUN rm -rf /var/www/
ADD http://wordpress.org/latest.tar.gz /wordpress.tar.gz
RUN tar xvzf /wordpress.tar.gz 
RUN mv /wordpress /var/www/
RUN chown -R www-data:www-data /var/www/
RUN chmod 755 /start.sh
RUN chmod 755 /etc/apache2/foreground.sh
RUN mkdir -p /var/log/supervisor/
EXPOSE 80 22
CMD ["/bin/bash", "/start.sh"]

Creating the VM and the Docker container

[pradipta@voldemort docker-wordpress]$ export VAGRANT_DEFAULT_PROVIDER=libvirt
[pradipta@voldemort docker-wordpress]$ vagrant up --provider=docker
Bringing machine 'wordpress' up with 'docker' provider...
==> wordpress: Docker host is required. One will be created if necessary...
[snip]

==> wordpress: Building the container from a Dockerfile...
    wordpress: Image: b2df10bcbb02
[snip]

    wordpress:   Name: wordpress
    wordpress:  Image: b2df10bcbb02
    wordpress: Volume: /var/lib/docker/docker_1418921657_30078:/vagrant
    wordpress:   Port: 2222:22
    wordpress:   Port: 80:80
    wordpress:  
    wordpress: Container created: 06972a346903bc58
==> wordpress: Starting container...
[snip]

Ssh to the Container

We can directly ssh to the container using ‘vagrant ssh’ since the container image has ssh configured

[pradipta@voldemort docker-wordpress]$ vagrant ssh
==> wordpress: SSH will be proxied through the Docker virtual machine since we're
==> wordpress: not running Docker natively. This is just a notice, and not an error.
Warning: Permanently added '172.17.0.130' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-24-generic ppc64le)

 * Documentation:  https://help.ubuntu.com/

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

vagrant@06972a346903:~$ 

Hope this will be of some help to you in creating development environments on KVM on Power. You can easily extend this example to create multiple interconnected docker containers on same VM or different VMs.

Pradipta Kumar Banerjee

I'm a Cloud and Linux/ OpenSource enthusiast, with 16 years of industry experience at IBM. You can find more details about me here - Linkedin

You may also like...