Slide 1

Slide 1 text

Vagrant for Real

Slide 2

Slide 2 text

Michele Orselli CTO@Ideato _orso_ micheleorselli / ideatosrl [email protected] Riccardo Franconi SW Engineer@Ideato ricfrank ricfrank / ideatosrl [email protected]

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

http://mitchellh.com/the-tao-of-vagrant

Slide 5

Slide 5 text

1) clone repo 2) vagrant up 3) there’s no #3

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

#tips

Slide 8

Slide 8 text

vagrantfile configs vm performance app config tips provision/packaging

Slide 9

Slide 9 text

Portable configuration tips

Slide 10

Slide 10 text

Don’t use local names for your boxes

Slide 11

Slide 11 text

c.vm.box = "hashicorp/precise64"

Slide 12

Slide 12 text

c.vm.box_url = "http://your_box"

Slide 13

Slide 13 text

Avoid absolute paths

Slide 14

Slide 14 text

c.vm.synced_folder “/myProj","/var/www/myProj"

Slide 15

Slide 15 text

config.vm.synced_folder "./", "/var/www/myProj"

Slide 16

Slide 16 text

Move host specific configuration outside Vagrantfile

Slide 17

Slide 17 text

ram: 2048 cpus: 2 ipaddress: 10.10.10.10 vagrantfile-local-config.yml

Slide 18

Slide 18 text

require ‘yaml' _config = YAML.load(File.open(File.join(File.dirname(__FILE__), “vagrantfile-local-config.yml”), File::RDONLY).read) CONF = _config config.vm.provider "virtualbox" do |vb| vb.customize["modifyvm",:id,“--memory", CONF["ram"]] vb.customize ["modifyvm",:id,"--cpus", CONF[“cpus"]] … end

Slide 19

Slide 19 text

As rule of thumb you could assign the half cpus and a quarter of the memory based on your host machine https://stefanwrobel.com/how-to-make-vagrant-performance-not-suck

Slide 20

Slide 20 text

Force a specific provider

Slide 21

Slide 21 text

ENV['VAGRANT_DEFAULT_PROVIDER'] = 'virtualbox'

Slide 22

Slide 22 text

Project’s folders organization

Slide 23

Slide 23 text

project_dir -- vagrant -- project -- Vagrantfile

Slide 24

Slide 24 text

project_dir -- vagrant -- Vagrantfile -- www -- project1 -- project2 -- project3

Slide 25

Slide 25 text

vagrant plugin install HostsUpdater

Slide 26

Slide 26 text

if Vagrant.has_plugin?("HostsUpdater") config.hostsupdater.aliases = ["host1.lo"] else puts "--- WARNING ---"
 puts “You should install HostsUpdater” end

Slide 27

Slide 27 text

VM Performance

Slide 28

Slide 28 text

run tests… still running…

Slide 29

Slide 29 text

mitchellh.com/comparing-filesystem-performance-in-virtual- machines Virtualbox vs VmWare

Slide 30

Slide 30 text

Virtualbox 22 min VmWare 15 min #tip: usevmware

Slide 31

Slide 31 text

Virtualbox 22 mi VmWare 15 min #tip: usevmware +30%

Slide 32

Slide 32 text

use VmWare if you can #tip: usevmware (it will cost you a few $)

Slide 33

Slide 33 text

use nfs if you can #tip: usenfs

Slide 34

Slide 34 text

vagrant plugin install vbguest #tip: vbguest keeps guest addition updated

Slide 35

Slide 35 text

On VM I/O is the bottleneck

Slide 36

Slide 36 text

loading webpages running testsuites are READ heavy

Slide 37

Slide 37 text

move I/O outside shared folders

Slide 38

Slide 38 text

Default provider: virtualbox 3 PHP test suites with unit, functional, integration mix small (sf1): build runs in ~25 sec medium (zf2): build runs in ~2 mins large (sf2): build runs ~ 20 mins

Slide 39

Slide 39 text

I/O: logs, cache #tip: moveiofromshared

Slide 40

Slide 40 text

class AppKernel extends Kernel { public function getCacheDir() { if (in_array($this->environment, array('dev', 'test'))) { return '/dev/shm/appname/cache/' . $this->environment; } return parent::getCacheDir(); } public function getLogDir() { if (in_array($this->environment, array('dev', ‘test'))) { return '/dev/shm/appname/logs'; } return parent::getLogDir(); } } #tip: moveiofromshared

Slide 41

Slide 41 text

class AppKernel extends Kernel { public function getCacheDir() { if (in_array($this->environment, array('dev', 'test'))) { return '/dev/shm/appname/cache/' . $this->environment; } return parent::getCacheDir(); } public function getLogDir() { if (in_array($this->environment, array('dev', ‘test'))) { return '/dev/shm/appname/logs'; } return parent::getLogDir(); } } #tip: moveiofromshared

Slide 42

Slide 42 text

class { public function { { } public function { { } } #tip: moveiofromshared +13-16%

Slide 43

Slide 43 text

I/O: increase realpath cache #tip: realpathcache

Slide 44

Slide 44 text

realpath_cache_size = 4096k realpath_cache_ttl = 7200 php.ini #tip: realpathcache

Slide 45

Slide 45 text

realpath_cache_size realpath_cache_ttl php.ini #tip: realpathcache +7%

Slide 46

Slide 46 text

I/O: move DB on RAM #tip: moveiofromshared if you use sqlite move it on /dev/shm

Slide 47

Slide 47 text

vagrant plugin install vagrantcachier #tip: vagrantcachier

Slide 48

Slide 48 text

if Vagrant.has_plugin?("vagrant-cachier") config.cache.scope = :box config.cache.synced_folder_opts = { type: :nfs, mount_options: ['rw','vers=3','tcp','nolock'] } end #tip: moveiofromshared Vagrantfile

Slide 49

Slide 49 text

if config.cache.synced_folder_opts type: mount_options: [ end #tip: moveiofromshared Vagrantfile +30% for reprovisioning a box with git, php apache, mysql

Slide 50

Slide 50 text

use cachefilesd for nfs #tip: cachefilesd

Slide 51

Slide 51 text

#tip: cachefilesd - name: Install cachefilesd apt: pkg=cachefilesd state=present - name: Enable cachefilesd lineinfile: dest=/etc/default/cachefilesd line=“RUN=yes” - name: Start cachefilesd service service: name=cachefilesd state=restarted

Slide 52

Slide 52 text

#tip: cachefilesd config.vm.synced_folder "../", "/var/www", id: “vagrant-root”, type: “nfs”, mount_options: ['rw','vers=3','tcp','fsc'] Vagrantfile

Slide 53

Slide 53 text

#tip: cachefilesd config.vm.synced_folder mount_options: [ Vagrantfile -15% +10%

Slide 54

Slide 54 text

Application Management

Slide 55

Slide 55 text

How to access mysql

Slide 56

Slide 56 text

- name: add mysql user mysql_user: name=ideato host='%' password=ideato priv=*.*:ALL,GRANT login_user=root login_password= - name: config bind address to allow remote remote connections lineinfile: dest=/etc/mysql/my.cnf state=present regexp='bind-address = 127\.0\.0\.1' line='bind-address = 0\.0\.0\.0' backup=yes - name: restart mysql service: name=mysql state=restarted

Slide 57

Slide 57 text

- name: Install phpmyadmin apt: pkg=phpmyadmin state=present - name: Include phpmyadmin in Apache config lineinfile: dest=/etc/apache2/apache2.conf line="Include /etc/phpmyadmin apache.conf" notify: restart apache

Slide 58

Slide 58 text

- name: adminer clone git: repo=https://github.com/vrana/adminer.git dest=/var/www/adminer version=v4.2.1 accept_hostkey=true - name: adminer compile command: php compile.php chdir=/var/www/adminer creates=/var/www/adminer/adminer-4.2.1.php

Slide 59

Slide 59 text

Permissions management in shared folders

Slide 60

Slide 60 text

config.vm.synced_folder "../", "/var/www", id: "vagrant-root", owner: "vagrant", group: "vagrant", mount_options: ["dmode=777,fmode=777"]

Slide 61

Slide 61 text

Use host ssh keys

Slide 62

Slide 62 text

config.ssh.forward_agent = true

Slide 63

Slide 63 text

ForwardAgent yes check ssh config file in your host machine

Slide 64

Slide 64 text

Provisioning

Slide 65

Slide 65 text

to phansible or not to phansible? #tip: provisioningtpls

Slide 66

Slide 66 text

• quick and easy way to start • they’re general • old platforms are not supported • a lot of a good ideas you can steal from • on the long run move to your own template #tip: provisioningtpls

Slide 67

Slide 67 text

#tip: provisioningtpls if which('ansible-playbook') config.vm.provision "ansible" do |ansible| ansible.playbook = "ansible/playbook.yml" ansible.inventory_path = "ansible/inventories/dev" ansible.limit = 'all' ansible.extra_vars = { private_interface: "192.168.33.99", hostname: "default" } end else config.vm.provision :shell, path: "ansible/windows.sh", args: ["default"] end

Slide 68

Slide 68 text

can you assume everyone in your team have the same version? #tip: provisioningtpls

Slide 69

Slide 69 text

#tip: provisioningtpls if which('ansible-playbook') config.vm.provision "ansible" do |ansible| ansible.playbook = "ansible/playbook.yml" ansible.inventory_path = "ansible/inventories/dev" ansible.limit = 'all' ansible.extra_vars = { private_interface: "192.168.33.99", hostname: "default" } end else config.vm.provision :shell, path: "ansible/windows.sh", args: ["default"] end

Slide 70

Slide 70 text

the provisioning tool is a moving part: wanna update? be careful #tip: provisioningtpls

Slide 71

Slide 71 text

create Vagrant indipendent provision scripts #tip: provisioningtpls

Slide 72

Slide 72 text

#tip: provisioningtpls config.vm.provision :shell, :path => "scripts/bootstrap.sh", :args => "/var/www" config.vm.provision :shell, :path => “scripts/provision.sh", :args => "/var/www"

Slide 73

Slide 73 text

you’re in control of provisioning command you can perform additional checks on host machine #tip: provisioningtpls

Slide 74

Slide 74 text

Distributing VMs

Slide 75

Slide 75 text

provisioning does not create immutable vm by default eg: package update on LTS #tip: packaging

Slide 76

Slide 76 text

live on the edge and fix provision script use stable package repositories #tip: packaging

Slide 77

Slide 77 text

https://speakerdeck.com/mitchellh/vagrant-usage-patterns Create and distribute your own VM #tip: goldenimage

Slide 78

Slide 78 text

No content

Slide 79

Slide 79 text

Questions? https://joind.in/talk/view/14548