I'm trying to build a docker container on the fly in a vagrant vm. The Vagrantfile and Dockerfile the container is to be built from are in the same directory, and on the VM, they are both found in the default synced folder /vagrant as expected. Unfortunately, building the container does not work- I get The Dockerfile (Dockerfile) must be within the build context. What is the proper build context in this case? Do I need to copy the Dockerfile somewhere to be able to use it?
Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.provider "virtualbox"
config.vm.box = "ubuntu/trusty64"
config.vm.hostname = "ubuntu"
config.vm.network :private_network, ip: "192.168.0.200"
config.ssh.forward_agent = true
config.ssh.insert_key = false
config.vm.provision "docker" do |d|
d.build_image "/vagrant/Dockerfile"
d.build_args = ['--tag "container"']
d.run "container"
end
end
Output:
$ vagrant provision
==> default: Running provisioner: docker...
==> default: Building Docker images...
==> default: -- Path: /vagrant/Dockerfile
==> default: stdin: is not a tty
==> default: The Dockerfile (Dockerfile) must be within the build context (/vagrant/Dockerfile)
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!
docker build /vagrant/Dockerfile
Stdout from the command:
Stderr from the command:
stdin: is not a tty
The Dockerfile (Dockerfile) must be within the build context (/vagrant/Dockerfile)
The d.build_image "/vagrant/Dockerfile" option should refer to the containing folder of the Dockerfile, in this case:
Vagrant.configure("2") do |config|
config.vm.provider "virtualbox"
config.vm.box = "ubuntu/trusty64"
config.vm.hostname = "ubuntu"
config.vm.network :private_network, ip: "192.168.0.200"
config.ssh.forward_agent = true
config.ssh.insert_key = false
config.vm.provision "docker" do |d|
d.build_image "/vagrant"
d.build_args = ['--tag "container"']
d.run "container"
end
end
Related
This my main Vagrant file
Vagrant.configure(2) do |config|
config.vm.define "app7" do |app7|
app7.vm.synced_folder "/home/behrad/dunro","/var/www/html"
app7.vm.network "forwarded_port", id: "ssh", guest: 22, host: 2222, auto_correct: true
app7.vm.provider "docker" do |docker|
docker.vagrant_vagrantfile = "dev/app7/Vagrantfile"
docker.build_dir = "./dev/app7"
docker.build_args = "-t","dunro/app7:20170701"
docker.name = "app7"
docker.ports = ['80:80']
docker.has_ssh = true
end
end
end
and dev/app7/Vagrantfile
Vagrant.configure(2) do |config|
config.vm.hostname = "app7"
config.vm.provision "file", source: "keys/id_rsa.pub", destination: "/var/www/.ssh/authorized_keys"
config.ssh.username = "www-data"
config.ssh.private_key_path = "keys/id_rsa"
end
The dev/app7/Vagrantfile not working
The dev/app7/Vagrantfile not working
Yes it is not working because its not a valid Vagrantfile.
You have basically instructed vagrant to use host VM so from the main Vagrantfile, you' telling vagrant to look into another Vagrantfile to know the configuration of an host VM (the host VM that will run docker) so at minimum you need to have a config.vm.box settings that will be the base box for this VM
An example of an host VM Vagrantfile will be
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.hostname = "app7"
config.vm.provision "shell", inline: "echo Hello, World"
# make sure to have docker installed on this VM
config.vm.provision "docker"
config.vm.network :forwarded_port, guest: 80, host: 4567
end
This will create a VM based on ubuntu trusty64 (I make sure to install latest version of docker so the main Vagrantfile with docker provider will be able to run correctly)
In this case I can see my inline shell provisioning running, the docker provision will install docker and then after the docker main provider will pull images on this VM
I am trying to install docker on the trusty64 vagrant image:
Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.hostname = "apps.local"
config.vm.provision "shell", inline: <<-SHELL
puppet module install garethr-docker
SHELL
config.vm.provision "puppet"
end
manifests/default.pp
include 'docker'
docker::image { 'ubuntu':
image_tag => 'trusty'
}
And the output of vagrant up :
==> default: Running provisioner: shell...
default: Running: inline script
==> default: Notice: Preparing to install into /etc/puppet/modules ...
==> default: Notice: Downloading from https://forge.puppetlabs.com ...
==> default: Notice: Installing -- do not interrupt ...
==> default: /etc/puppet/modules
==> default: └─┬ garethr-docker (v5.3.0)
==> default: ├── puppetlabs-apt (v3.0.0)
==> default: ├── puppetlabs-stdlib (v4.17.0)
==> default: └── stahnma-epel (v1.2.2)
==> default: Running provisioner: puppet...
==> default: Running Puppet with default.pp...
==> default: Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera defaults
==> default: Error: Syntax error at 'Variant'; expected ')' at /etc/puppet/modules/apt/manifests/init.pp:6 on node carcosa.local
==> default: Error: Syntax error at 'Variant'; expected ')' at /etc/puppet/modules/apt/manifests/init.pp:6 on node carcosa.local
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.
Can someone tell me what am I doing wrong ?
The latest version of puppetlabs-apt module supports only the latest version of puppet
Latest version is compatible with:
- Puppet Enterprise 2016.5.x, 2016.4.x
- Puppet >= 4.7.0 < 5.0.0
- Ubuntu, Debian
If you want to make if work in your example you need to force the installation of a version supported by puppet 3.x (see https://forge.puppet.com/puppetlabs/apt/1.6.0/changelog)
The following Vagrantfile will do the work
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
#config.vm.provision "docker"
config.vm.hostname = "apps.local"
config.vm.provision "shell", inline: <<-SHELL
puppet module install puppetlabs-apt --version 2.4.0
puppet module install garethr-docker
SHELL
config.vm.provision "puppet"
end
If your goal is just to have docker installed on the VM, the easiest is to let vagrant install it. Vagrant has docker provisioner and if not installed it will try to install
This simple Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.provision "docker"
end
will install docker on trusty64 - the provisioner has after many advantages if you want to work with docker images etc ...
I am running Vagrant on Mac OS X. I have created following Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.synced_folder ".", "/vagrant", disabled: true
config.ssh.insert_key = true
config.vm.provider "docker" do |doc|
doc.image = "httpd"
doc.ports = ["80:80"]
doc.name = 'apache'
doc.remains_running = true
doc.has_ssh = false
end end
It is starting, however I can't execute following command:
vagrant docker-exec -dt apache -- /bin/bash
I have also tried to change apache into container ID, but have failed too.
The container is running as I can check it in Virtualbox.
I can only see that I have vagrant docker-logs and vagrant docker-run, but the documentation of Vagrant says that there should be docker-exec.
Any ideas?
-i --interactive is required if you want a bash shell you can type in.
-d --detach will not work for typing either as the process will be in started in the background.
Use vagrant docker-exec -it apache -- /bin/bash
Yep, that is correct. I also know now that you need to do list-commands to see this docker-exec command.
thank you
I'm new to vagrant, using 1.7.4 with VirtualBox 5.0.10 on Windows 7 and trying to figure out how to get it to setup and run docker containers the way I'd like, which is like so:
Start my docker host, which is already provisioned with the latest docker tools and boots with the cadvisor container started - I get this box from the publicly available williamyeh/ubuntu-trusty64-docker
If (for example) the mongo container I'd like to use has not been created on the docker host, just create it (don't start it)
Else, if the container already exists, start it (don't try to create it)
With my current setup, using the docker provider, after the first use of vagrant up, using vagrant halt followed by vagrant up will produce this error:
Bringing machine 'default' up with 'docker' provider...
==> default: Docker host is required. One will be created if necessary...
default: Docker host VM is already ready.
==> default: Warning: When using a remote Docker host, forwarded ports will NOT be
==> default: immediately available on your machine. They will still be forwarded on
==> default: the remote machine, however, so if you have a way to access the remote
==> default: machine, then you should be able to access those ports there. This is
==> default: not an error, it is only an informational message.
==> default: Creating the container...
default: Name: mongo-container
default: Image: mongo
default: Port: 27017:27017
A Docker command executed by Vagrant didn't complete successfully!
The command run along with the output from the command is shown
below.
Command: "docker" "run" "--name" "mongo-container" "-d" "-p" "27017:27017" "-d" "mongo"
Stderr: Error response from daemon: Conflict. The name "mongo-container" is already in use by container 7a436a4a3422. You have to remove (or rename) that container to be able to reuse that name.
Here is the Vagrantfile I'm using for the docker host:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.require_version ">= 1.6.0"
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.hostname = "docker-host"
config.vm.box_check_update = false
config.ssh.insert_key = false
config.vm.box = "williamyeh/ubuntu-trusty64-docker"
config.vm.network "forwarded_port", guest: 27017, host: 27017
config.vm.synced_folder ".", "/vagrant", disabled: true
end
...and here is the docker provider Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.require_version ">= 1.6.0"
VAGRANTFILE_API_VERSION = "2"
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.provider "docker" do |docker|
docker.vagrant_vagrantfile = "../docker-host/Vagrantfile"
docker.image = "mongo"
docker.ports = ['27017:27017']
docker.name = 'mongo-container'
end
end
Well, I'm not sure what had gotten munged in my environment, but while reconfiguring my setup, I deleted and restored my base docker host image, and from that point on, vagrant up, followed by vagrant halt, followed by vagrant up on the docker provider worked exactly like I was expecting it to.
At any rate, I guess this question is already supported by vagrant.
I'm trying to figure out the best development workflow with vagrant and docker running a rails app. In my dockerfile I have this:
FROM quirky/rails:latest
RUN mkdir /opt/app
WORKDIR /opt/app
# Install gems
ADD ./Gemfile /opt/app/Gemfile
ADD ./Gemfile.lock /opt/app/Gemfile.lock
RUN bundle install
# Instal npm packages
ADD ./package.json /opt/app/package.json
RUN npm install
# Expose directories and ports
VOLUME /opt/app
EXPOSE 3000
# Run the web server
WORKDIR /opt/app
CMD rm -f /opt/app/tmp/pids/server.pid && bundle exec rails s
My Vagrantfile looks like this:
config.vm.define "app" do |app|
app.vm.provider "docker" do |d|
d.build_dir = "."
d.link "db:db"
d.link "redis:redis"
d.link "solr:solr"
d.volumes = ["/app:/opt/app"]
d.ports = ["3000:3000"]
d.vagrant_vagrantfile = "./docker/Vagrantfile"
d.remains_running = true
end
end
config.vm.define "db" do |db|
db.vm.provider "docker" do |d|
d.image = "paintedfox/postgresql"
d.name = "db"
d.env = {USER: "vagrant", PASS: "password"}
d.vagrant_vagrantfile = "./docker/Vagrantfile"
end
end
config.vm.define "redis" do |redis|
redis.vm.provider "docker" do |d|
d.image = "dockerfile/redis"
d.name = "redis"
d.ports = ["6379:6379"]
d.vagrant_vagrantfile = "./docker/Vagrantfile"
end
end
config.vm.define "solr" do |solr|
solr.vm.provider "docker" do |d|
d.image = "quirky/solr"
d.name = "solr"
d.ports = ["8080:8080"]
d.vagrant_vagrantfile = "./docker/Vagrantfile"
end
end
Typically if I want to debug something I just stick a debugger statement in the code and I'm running it as a local process and it just hits the breakpoint and brings up pry or whatever the debugger console is. How does this work inside of a container inside vagrant?
This is how I start my dev environment:
vagrant up app --provider=docker
It launches it in the background. There doesn't appear to be a way to launch it and attach to it. Am I missing a command or a flag I can pass in to vagrant?
You are looking for docker exec or nsenter [1]. With one of these tools you can log into the container without SSH and check your logs.
If you want to debug vagrant creating and running the docker-container you can append the --debug flag like so:
vagrant up app --provider=docker --debug
But this won't give you any debug-info from your Vagrantfile directly. If you still want to get debug-messages out of your vagrantfile I recommend you to read about vagrants UI class.
PS: Maybe you simply want puts statements like so: puts "I'm here!"?
PPS: If you want to stick with vagrant and SSH the has_ssh value and a SSH-Server in the container is the way to go.
nsenter/docker exec
Have you tried the has_ssh option for the Vagrand Docker provider? It states that:
If true, then Vagrant will support SSH with the container. This allows vagrant ssh to work, provisioners, etc. This defaults to false
As an aside, I haven't tried this myself. I'm using Docker with a CoreOS image and running docker containers manually (with provisioning).