Vagrant | Boxes | Docs
CM for VM-based Development Environments
Why not docker container?
Docker designed for single process; nosystemd
, etc.
Why notdocker-machine
VM?
Vagrant does synched folders, whereasdocker-machine mount
fails @ Win/WSL.
Vagrant Project is a Vagrant box. It is created at the host.
- Best practice is to build each project at its own directory,
with its ownVagrantfile
, and use (git) versioning.
- Best practice is to build each project at its own directory,
Vagrant box is a VM, configurated per (ruby)
Vagrantfile
, and run as
a guest machine on a Vagrant-supportedprovider
(hypervisor or similar),
such as VirtualBox, Hyper-V, Docker, AWS EC2, .... The list is growing.Many current boxes @
generic/...
, from Roboxes.org; Packer project.Namespaced (MAKER/BOX) per Vagrant repo:
username/boxname
Stored globally for current user.
- An immutable initial image usable by multiple projects;
modifications per project are orthogonal to other projects.
- An immutable initial image usable by multiple projects;
Some Vagrant boxes support Hyper-V
provider
,
but VirtualBox is its most supported.
Integrates with Packer, for creating new boxes.
Install (Git-for-Windows) shell.
- @
mintty
, some vagrant commands fail.
Commands
Ad hoc
# Verify (List Commands)
vagrant
# Init (creates VagrantFile)
vagrant init
# Add the Box (Download box image)
vagrant box add $_MAKER/$_BOX
# Start/Boot the VM/OS [per specified provider]
vagrant up [--provider=hyperv|virtualbox|vmware|libvirt|docker|...]
Configured
# Create(Download)/Start/Boot the image/VM/OS
vagrant up
# (Re)Provision (if up already)
vagrant provision
# Restart [+(Re)Provision]
vagrant reload [--provision] [--debug]
# Login
vagrant ssh
@ box
vagrant@$_BOX:~$ # In the box!
# CTRL+D to exit, or ...
vagrant@$_BOX:~$ logout
Connection to 192.168.1.23 closed.
# SSH config (if issues)
vagrant ssh-config
# Box ...
vagrant box add|remove|prune|list|...
VM per se
# VM commands (pause|resume|stop)
vagrant up|suspend|resume|halt
# Terminate VM (Removes @ Hyper-V)
vagrant destroy
# Remove the (downloaded) Box
vagrant box remove
Project Setup (Getting Started)
- Run as Administrator (console with elevated privileges).
Work from a per-project folder
# Create/GoTo new project dir
mkdir $_PROJECT; cd $_PROJECT
If using mintty
, then subshell per winpty bash
command,
else can't hide password on SMB connect; error message:
"Error! Your console doesn't support..."
Select a Vagrant Box
generic/ubuntu1604
Roboxes.org
Configure
Vagrantfile
(Hyper-V specific)
# if Vagrant API Version: "2"
Vagrant.configure("2") do |config|
# Base box
config.vm.box = "generic/ubuntu1604"
# @ Hyper-V
config.vm.provider "hyperv" do |h|
# VM name
h.vmname = "vagrant.generic.ubuntu1604"
# Improve spin-up time
h.enable_virtualization_extensions = true
# h.differencing_disk = true # depricated
h.linked_clone = true
end
# Network
config.vm.network "public_network"
# Synched Folder(s)
# Disable (SMB) a Synched Folder (default @ Hyper-V)
config.vm.synced_folder ".", "/vagrant", disabled: true
# Enable (SMB) a Synched Folder (required @ Hyper-V)
config.vm.synced_folder ".", "/vagrant"
# Upload file(s) to guest (VM)
config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
# Run host script(s) @ guest (VM)
config.vm.provision :shell, path: "bootstrap.sh"
end
-
Box path must be absolute; host path can be relative (to project Vagrantfile
root).
# Enable (SMB) a Synched Folder (required @ Hyper-V)
config.vm.synced_folder ".", "/vagrant"
# Synch AWS-creds folder @host to @box
config.vm.synced_folder "./../../.aws/", "/home/vagrant/.aws"
# ... + create [Abs/Rel]-host-path, owner, group, mount options
config.vm.synced_folder "/abs/path/foo/", "/home/vagrant/foo", create: true,
owner: "vagrant", group: "vagrant", mount_options: ["uid=1000", "gid=1000"]
Providers: hyperv
| virtualbox
| vmware
| libvirt
| docker
| ...
Provisioners: shell
| file
| docker
| ansible
| chef_...
| puppet_...
| ...
# Shell Provisioner :: Run script(s) @ box, @ up
# Inline (type:shell, key:inline, val:"...")
config.vm.provision "shell", inline: "echo hello"
# External script(s); path rel to project Vagrantfile
config.vm.provision "shell", path: "test1.sh"
# External script(s); run as "vagrant" user (default is as "root")
config.vm.provision "shell", path: "test2.sh", privileged: false
# expect: '/home/vagrant/vagrant-shell.ran2'
# Guest script; if script is already @ guest
config.vm.provision "shell",
inline: "/bin/sh /path/at/guest/guest.sh"
# Named provisioner (name:bootstrap)
config.vm.provision "bootstrap", type: "shell" do |s|
s.inline = "echo foo"
end
# Define, for multiple provisioners (Chef uses)
config.vm.define "web" do |web|
web.vm.provision "shell", inline: "echo bar"
end
config.vm.provision "shell", inline: "echo baz"
# ... @ `vagrant up`, the run order: hello, foo, baz, bar
# File Provisioner :: Upload file(s) to guest (VM)
# will CREATE (sub)folder(s) @ box, if not exist
config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
config.vm.provision "file", source: "~/Vagrant/test/foodir", destination: "root.newfoodir"
config.vm.provision "file", source: "~/Vagrant/test/foodir", destination: "$HOME/remote/sub.newfoodir"
- File Provisioner (based) uploads are run as the SSH user (per
vagrant ssh-config
), or as PowerShell user. Best practice is to script the uploads using Shell Provisioner, explicitly setting the privileged:
boolean thereof.
-
# Config for "public" or "private" IP address
# (Meanings vary per provider; both functioned @ Hyper-V)
config.vm.network "public_network"
# Let DHCP server provide IP address
config.vm.network "private_network", type: "dhcp"
# Static IP
config.vm.network "private_network", ip: "192.168.1.55"
# Port forwarding
config.vm.network "forwarded_port", guest: 80, host: 8080
# Specifiy Interface (Adapter; no effect @ Hyper-V)
config.vm.network "public_network", bridge: "en1: External-GbE"
# Synch folder(s); @host, @box
config.vm.synced_folder ".", "/vagrant" # "default"
Hyper-V requires explicitly enabling synch, even for the "default" synched folder, which is the above. SSH uploads may fail without it.
If Synch Folder(s) enabled, then @ vagrant up
...
==> web: Preparing SMB shared folders...
...
web: Username:
web: Password (will be hidden):
...
If console has no tty
(fix mintty
@ winpty bash
)
an error is reported, but the process continues.
Error! Your console doesn't support hidden ...
...
Tips & Tricks @ Hyper-V
Vagrant uses SMBv1
; check if enabled (PowerShell)
# Vagrant uses SMBv1; check if enabled
Get-SmbServerConfiguration
mintty
, some vagrant commands fail.# Verify (List Commands)
vagrant
# Init (creates VagrantFile)
vagrant init
# Add the Box (Download box image)
vagrant box add $_MAKER/$_BOX
# Start/Boot the VM/OS [per specified provider]
vagrant up [--provider=hyperv|virtualbox|vmware|libvirt|docker|...]
# Create(Download)/Start/Boot the image/VM/OS
vagrant up
# (Re)Provision (if up already)
vagrant provision
# Restart [+(Re)Provision]
vagrant reload [--provision] [--debug]
# Login
vagrant ssh
@ box
vagrant@$_BOX:~$ # In the box!
# CTRL+D to exit, or ...
vagrant@$_BOX:~$ logout
Connection to 192.168.1.23 closed.
# SSH config (if issues)
vagrant ssh-config
# Box ...
vagrant box add|remove|prune|list|...
# VM commands (pause|resume|stop)
vagrant up|suspend|resume|halt
# Terminate VM (Removes @ Hyper-V)
vagrant destroy
# Remove the (downloaded) Box
vagrant box remove
Work from a per-project folder
# Create/GoTo new project dir
mkdir $_PROJECT; cd $_PROJECT
If using mintty
, then subshell per winpty bash
command,
else can't hide password on SMB connect; error message:
"Error! Your console doesn't support..."
Select a Vagrant Box
generic/ubuntu1604
Roboxes.org
Vagrantfile
(Hyper-V specific)# if Vagrant API Version: "2"
Vagrant.configure("2") do |config|
# Base box
config.vm.box = "generic/ubuntu1604"
# @ Hyper-V
config.vm.provider "hyperv" do |h|
# VM name
h.vmname = "vagrant.generic.ubuntu1604"
# Improve spin-up time
h.enable_virtualization_extensions = true
# h.differencing_disk = true # depricated
h.linked_clone = true
end
# Network
config.vm.network "public_network"
# Synched Folder(s)
# Disable (SMB) a Synched Folder (default @ Hyper-V)
config.vm.synced_folder ".", "/vagrant", disabled: true
# Enable (SMB) a Synched Folder (required @ Hyper-V)
config.vm.synced_folder ".", "/vagrant"
# Upload file(s) to guest (VM)
config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
# Run host script(s) @ guest (VM)
config.vm.provision :shell, path: "bootstrap.sh"
end
Box path must be absolute; host path can be relative (to project
Vagrantfile
root).# Enable (SMB) a Synched Folder (required @ Hyper-V) config.vm.synced_folder ".", "/vagrant" # Synch AWS-creds folder @host to @box config.vm.synced_folder "./../../.aws/", "/home/vagrant/.aws" # ... + create [Abs/Rel]-host-path, owner, group, mount options config.vm.synced_folder "/abs/path/foo/", "/home/vagrant/foo", create: true, owner: "vagrant", group: "vagrant", mount_options: ["uid=1000", "gid=1000"]
Providers: hyperv
| virtualbox
| vmware
| libvirt
| docker
| ...
Provisioners: shell
| file
| docker
| ansible
| chef_...
| puppet_...
| ...
# Shell Provisioner :: Run script(s) @ box, @ up
# Inline (type:shell, key:inline, val:"...")
config.vm.provision "shell", inline: "echo hello"
# External script(s); path rel to project Vagrantfile
config.vm.provision "shell", path: "test1.sh"
# External script(s); run as "vagrant" user (default is as "root")
config.vm.provision "shell", path: "test2.sh", privileged: false
# expect: '/home/vagrant/vagrant-shell.ran2'
# Guest script; if script is already @ guest
config.vm.provision "shell",
inline: "/bin/sh /path/at/guest/guest.sh"
# Named provisioner (name:bootstrap)
config.vm.provision "bootstrap", type: "shell" do |s|
s.inline = "echo foo"
end
# Define, for multiple provisioners (Chef uses)
config.vm.define "web" do |web|
web.vm.provision "shell", inline: "echo bar"
end
config.vm.provision "shell", inline: "echo baz"
# ... @ `vagrant up`, the run order: hello, foo, baz, bar
# File Provisioner :: Upload file(s) to guest (VM)
# will CREATE (sub)folder(s) @ box, if not exist
config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
config.vm.provision "file", source: "~/Vagrant/test/foodir", destination: "root.newfoodir"
config.vm.provision "file", source: "~/Vagrant/test/foodir", destination: "$HOME/remote/sub.newfoodir"
- File Provisioner (based) uploads are run as the SSH user (per
vagrant ssh-config
), or as PowerShell user. Best practice is to script the uploads using Shell Provisioner, explicitly setting theprivileged:
boolean thereof.
# Config for "public" or "private" IP address
# (Meanings vary per provider; both functioned @ Hyper-V)
config.vm.network "public_network"
# Let DHCP server provide IP address
config.vm.network "private_network", type: "dhcp"
# Static IP
config.vm.network "private_network", ip: "192.168.1.55"
# Port forwarding
config.vm.network "forwarded_port", guest: 80, host: 8080
# Specifiy Interface (Adapter; no effect @ Hyper-V)
config.vm.network "public_network", bridge: "en1: External-GbE"
# Synch folder(s); @host, @box
config.vm.synced_folder ".", "/vagrant" # "default"
Hyper-V requires explicitly enabling synch, even for the "default" synched folder, which is the above. SSH uploads may fail without it.
If Synch Folder(s) enabled, then @
vagrant up
...==> web: Preparing SMB shared folders... ... web: Username: web: Password (will be hidden): ...
If console has no
tty
(fixmintty
@winpty bash
)
an error is reported, but the process continues.Error! Your console doesn't support hidden ... ...
Tips & Tricks @ Hyper-V
Vagrant uses SMBv1
; check if enabled (PowerShell)
# Vagrant uses SMBv1; check if enabled
Get-SmbServerConfiguration