How do I provision a Dockerfile from Vagrant - vagrant

How can I start the provisioning of Docker via an external Dockerfile?
My Vagrantfile looks like this at the moment
Vagrant.configure("2") do |config|
config.vm.box = "precise64"
config.vm.define :server_infrastructure do |t|
end
config.vm.provision "docker" do |d|
d.pull_images "ubuntu"
#how does the below work?
#d.build "new-container-name" "local-docker-file-name"
end
end
Your help is greatly appreciated

An option for the Docker provisioner to build images was added in v1.6.0. Download the latest version from the Vagrant website.
Once you've done that, put a Dockerfile next to your Vagrantfile. Add this to your Vagrantfile:
config.vm.provision "docker" do |d|
d.build_image "/vagrant", args: "-t my-name/my-new-image"
d.run "my-name/my-new-image"
end
Now your Docker image will be built and run with vagrant up.

one workaround is through shell provisioning:
config.vm.provision "shell", inline: "docker build -t username/image /vagrant; docker run -d username/image"

For docker to build an image from a dockerfile, dockerfile in question must be presented in the guest machine and the way to ensure this is to use shared folder feature of vagrant.
By default vagrant mounts your project root folder to the new vm under the name /vagrant. But in your case i suggest you share a different folder and put your dockerfiles there. Also by sharing a different folder you can make sure that your dockerfiles are seen read-only by the guest machine.
Now suppose you create a new folder in your projects root directory named "docker" and put your dockerfiles in it. Now if you mount this folder to your guest machine and point docker to use that file you are all set. if you add these lines to your vagrant file it will work as expected.
config.vm.synced_folder "docker/", "/docker_builds", create: true, mount_options: ["ro"]
config.vm.provision "docker" do |d|
d.build_image "/docker_builds", args: "-t my-name/my-new-image"
d.run "my-name/my-new-image"
end

Related

Create Vagrant VM with an alias

I want to create a couple of Vagrant VM's. Most of them could be Ubuntu 16.04. But I want the VM's to be named as webserver01, webserver02 and webserver03. Basically I want the Vagrantfile for each VM to be inside the directory name I provided above.
Command vagrant init ubuntu/xenial64 might create a new VM but how do I make sure I create three webservers{1..3} as above and run vagrant up command from inside that directory?
I want all the VM's to be in a specific directory so I just open CMD inside that directory and run vagrant up from inside them.
you can spawn as many VMs with the help of loops.
https://www.vagrantup.com/docs/vagrantfile/tips.
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
(1..3).each do |i|
config.vm.define "node-#{i}" do |node|
node.vm.provision "shell",
inline: "echo hello from node #{i}"
end
end
end
you can access any machine from the cli e.g. from the given example in the link you can control node-1 like
vagrant up node-1 && vagrant ssh node-1

Multi-machine Vagrant with Ubuntu - Sinatra & PostgreSQL

I'm stuck again. I need to provision a multi-machine Environment - one VM for a Sinatra app and a second for its PostgreSQL DB.
So far, I've managed to get the Sinatra app up and running in the ubuntu/xenial64 box but the provisioning "breaks" when it hits the configuration for the DB
Vagrant.configure("2") do |config|
config.vm.define "app" do |app|
# Use ubuntu/xenial64 as the virtual machine
app.vm.box = "ubuntu/xenial64"
# Use a private network to connect the VM to the local machine via an IP with an alias
app.vm.network "private_network", ip: "192.168.10.100"
app.hostsupdater.aliases = ["development.local"]
# sync the 'app' directory in the local directory to '/app' on the VM
app.vm.synced_folder "app", "/app"
# Use the provisioning script in envirnonment to provision the VM for a Sinatra environment
app.vm.provision "shell", path: "environment/app/provision.sh"
app.vm.provision "shell", inline: set_env({ DATABASE_URL: "postgresql://myapp:dbpass#localhost:15432/myapp" })
end
config.vm.define "db" do |db|
db.vm.box = "ubuntu/trusty64"
db.vm.host_name = "postgresql"
db.vm.network "private_network", ip: "10.0.2.15"
# db.vm.forward_port 8000, 8000
db.hostsupdater.aliases = ["database.local"]
# db.vm.share_folder "home", "/home/vagrant", ".", :create => true
db.vm.provision "shell", path: "environment/db/provision.sh", privileged: false
end
end
As you've probably guessed, I'm running an external provisioning script for the PG setup. The odd thing is I'm using the script recommended from Postgres' own site here.
In a separate location, I've git cloned that repo and followed the instructions and it works absolutely fine, creating a properly provisioned VM with PG installed.
However, I want to run a single vagrant up command and provisioning both the app and db correctly and have them speak to each other.
I'm (quite clearly) new to provisioning and DevOps as a whole, so would really appreciate some help.
I've uploaded my hilariously broken code here for you kind souls to look over if you feel so inclined.
Vagrant documentation on Multi-machines is quite thin and Google isn't being much help
Thanks!

Vagrant synced_folder /vagrant shared_folder missing

Hi I'm trying to provision my box using vagrant and ansible but I always encounter /vagrant/ansible/playbook.yml is missing. It's looking for a /vagrant directory. When I ssh inside my box the /vagrant does not exist. I'm not sure what happen but what I did was to sync all my local copy into a specific folder location inside my box. Below is a sample implementation I did
Vagrant.configure("2") do |config|
config.vm.define "ans", primary: true do |ans|
ans.vm.box = "ubuntu/xenial64"
ans.vm.network "forwarded_port", guest: 80, host: 8080
ans.vm.network "private_network", ip: "10.8.9.20", auto_network: true
ans.vm.synced_folder ".", "/var/www/"
ans.vm.hostname = "my_project"
ans.vm.provision "pre-build", type: "shell", :path => "ansible/bootstrap.sh"
ans.vm.provision "ansible_local" do |ansible|
ansible.playbook = "ansible/playbook.yml"
end
end
end
I'm getting an error in the ansible.playbook = "ansible/playbook.yml" it seems this line is looking under /vagrant folder which does not exist. What will be the workaround or fix for this? My playbook exist in this location /var/www/ansible/playbook.yml inside the box
By default, vagrant automatically add a shared folder from your current directory with /vagrant folder on the VM.
Because you have added
ans.vm.synced_folder ".", "/var/www/"
the current folder shared folder has been replaced from /vagrant to /var/www (you can easily verify that by removing the line from your vagrantfile)
do you really need to sync the whole current folder with /var/www ideally you would have your project files in a subdirectory that you will share in /var/www like
ans.vm.synced_folder "html/", "/var/www/"
and push all your html/csss/js files under the html folder (feel free to rename project or something else) and you'll not need to sync all the vagrant scripts and provisioning script with your web server folder.

Using SaltStack grains file with Vagrant

I would like to use minion.d/*.conf to provision a vagrant machine.
Here is my Vagrant configuration:
Vagrant.configure("2") do |config|
## Choose your base box
config.vm.box = "precise64"
## For masterless, mount your salt file root
config.vm.synced_folder "salt/roots/", "/srv/salt/"
## Use all the defaults:
config.vm.provision :salt do |salt|
salt.minion_config = "salt/minion"
salt.run_highstate = true
salt.grains_config = "salt/minion.d/vagrant.conf"
end
end
After provisioning the Vagrant machine, I have errors with rendering SLS files since the minion.d/*.conf files are not being copied to the guest machine under :
/etc/salt/minion.d/
Should I make a sync config in the Vagrant configuration to co ?
Have you just tried mounting a synced folder to /etc/salt/grains?
## For masterless, mount your salt file root
config.vm.synced_folder "salt/roots/", "/srv/salt/"
config.vm.synced_folder "salt/grains.d/", "/etc/salt/grains.d/"
#Utah_Dave's solution will work just fine, or you can do the following (which is how I run it).
Filesystem:
/dev
Vagrantfile
salt-minion.conf
salt/
top.sls
my-awesome-state/init.sls
pillar/
top.sls
my-awesome-pillar.sls
Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.box = "mafro/jessie64-au-salt"
# salt config directory & shared dir in /tmp
config.vm.synced_folder ".", "/srv/salt"
# setup the salt-minion
config.vm.provision :salt do |salt|
salt.minion_config = "salt-minion.conf"
end
end
salt-minion.conf
file_client: local
id: awesome
file_roots:
base:
- /srv/salt/salt
pillar_roots:
base:
- /srv/salt/pillar
Vagrant's implementation of salt.grains_config doesn't copy the file to the /etc/salt/minion.d folder as you might expect. Instead it copies the file to /etc/salt/grains.
To get the salt-minion to read this new grains file, you just need to add the following to your minion configuration:
/etc/salt/minion
include:
- /etc/salt/grains

How to run provision.sh on vagrant with docker provider

I have used vagrant successfully on many clouds now.
I have decided to try something with docker, but I am probably missing something very basic as I am failing tremendously.
I wrote this vagrant file:
Vagrant.configure("2") do |config|
config.vm.synced_folder "../synced_folder", "/vagrant"
config.vm.provision "shell" do |s|
s.path = "provision.sh"
s.privileged = false
end
config.vm.provider :docker do |docker, override|
docker.image = 'ubuntu'
end
end
this configuration worked for me for other clouds (if I add specific cloud details to it of course).
my provision.sh file simply has echo "hello world"
my synced_folder has a dummy file..
I have verified that ubuntu image is working fine in docker. docker seems to be working fine.
When I run vagrant up --provider docker I get the following
The container started either never left the "stopped" state or
very quickly reverted to the "stopped" state. This is usually
because the container didn't execute a command that kept it running,
and usually indicates a misconfiguration.
If you meant for this container to not remain running, please
set the Docker provider configuration "remains_running" to "false":
config.vm.provider "docker" do |d|
d.remains_running = false
end
I do not see the hello world print out.
I have found a lot of Q&A regarding this error, but nothing I could use to resolve my problem.
What am I doing wrong?
So I have been missing something very fundamental.
The solution I found is easy. Use this amazing contribution from:
https://github.com/bubenkoff/vagrant-docker-example
The important thing to note here is the Dockerfile - which defines the SSH connection in the container. Without the SSH it simply won't work.
However - another tacit fact people are missing - docker uses a socket which requires permissions, however runnign sudo vagrant up --provider will not resolve the issue. in order to run without problems you should sudo su - first OR add your user to docker group.
Read more about that: https://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo
So to summarize:
clone the git repository
sudo su -
vagrant up --provider docker
==> machine is up and running perfectly..
Been experiencing the same and following https://github.com/mitchellh/vagrant/issues/3951 for a while. Looks like this is to be fixed by the upcoming minor release of Vagrant.
config.vm.provider :docker do |docker, override|
docker.image = 'ubuntu'
end
You are missing a command here, you need a command to run the container. something like this:
config.vm.provider :docker do |docker, override|
docker.image = 'ubuntu'
docker.run = 'ubuntu'
end
Or you can do something like this:
config.vm.provider :docker do |docker, override|
docker.image = 'ubuntu'
docker.cmd = ["/usr/sbin/sshd", "-D"]
end

Resources