vagrant-lxc 0.5.0 and beyond
Last week I was able to release vagrant-lxc 0.5.0 and on this post you’ll get to know about some cool new stuff and the upcoming work I have in mind to reach what I believe would be a nice 1.0.0 milestone.
This release it mostly related to the “user experience” of using the plugin. Apart from some highlights you’ll get to know below, there are a few small things that makes people’s lives a bit easier:
- Forwarded ports collision detection - the plugin no longer keeps silent about forwarding ports that are already in use by the host.
- The plugin now errors if required dependencies are not installed - no more
silent errors or stacktraces if the
lxcand / or
redirpackages are not installed.
- Support for
redirlogging to syslog - some people got bitten by
redirissues this so I thought it would be nice to have this in places
Support for a
sudo wrapper script, aka no more
If you are using the plugin from within a VM on a Windows / Mac host you probably
haven’t suffered from the pain of typing in your password quite a few times during the day while using
the plugin. While there are certainly smarter ways to work around that, I ended
up adding support for a wrapper / proxy script that allow us to add a single passwordless sudo
entry on our
/etc/sudoers for the plugin to use when
sudo is required.
As stated on the the README, right now the script I’m using is really dumb AND INSECURE but it does the trick. It’s basically a ruby script that acts as a proxy for executing the commands:
#!/usr/bin/env ruby exec ARGV.join(' ')
With that in place we can then add a single entry to our
like the one below:
And tell vagrant-lxc to use it on our
# Protip: Drop this into your ~/.vagrant.d/Vagrantfile to apply the configuration to all vagrant-lxc VMs Vagrant.configure("2") do |config| config.vm.provider :lxc do |lxc| lxc.sudo_wrapper = '/usr/bin/lxc-vagrant-wrapper' end end
That’s it, no more typing in your password when using vagrant-lxc boxes :)
Since user namespaces will be supported at some point, I’m not willing to give much attention on improving this for now and this is the reason I’m not bundling this with the plugin. Feel free to submit a Pull Request in case you have a better idea of doing this, I’ll be more than happy to review it ;)
“Promiscuous” port forwarding
On my very first vagrant-lxc post
I showed an example of a
Vagrantfile that could be used for setting up a VirtualBox
VM between Mac / Windows hosts and vagrant-lxc containers but because vagrant-lxc < 0.5.0
used to bind forwarded ports with
redir only to
127.0.0.1 there was no easy way of
hitting the guest container directy from the host machine. Starting with 0.5.0 that set
up now works out of the box because the port forwarding will work for any of the
configured VBox IP.
Vagrant.configure("2") do |config| config.vm.box = "quantal64" config.vm.define :vbox do |vb_config| # Exposes access to the container vb_config.vm.network :forwarded_port, guest: 8000, host: 8080 vb_config.vm.network :forwarded_port, guest: 2221, host: 2000 end config.vm.define :lxc do |lxc_config| # Exposes a web server and SSH access lxc_config.vm.network :forwarded_port, guest: 80, host: 8000 lxc_config.vm.network :forwarded_port, guest: 22, host: 2221 end end
So using a Vagrantfile similiar to the one above you should be able to SSH into
vbox VM, bring up the
lxc container and hit a web server running on the
container on port
http://localhost:8080 from your host or SSH
directly into the guest container from your host with
ssh vagrant@localhost -p 2000.
Prior to 0.5.0 the provided customizations
and shared folders bind mounts where passed in as
-s parameters to
While that was working fine, it was a PITA to debug which of the configurations
were giving us a bad time because it made us look into Vagrant debug logs to find
out exactly which arguments were being passed in.
Starting with 0.5.0 those customizations are writen out to the container configuration
file (usualy kept under
/var/lib/lxc/<container>/config) prior to bringing
it up with
A side effect of that is that in case the container is not able to boot, you can
start the container on the foreground with something like
lxc-start -n $(cat .vagrant/machines/<machine-name>/lxc/id)
and replicate vagrant-lxc’s behavior. With that you’ll be able to find out more
information on why things are not working and you’ll be able to tweak the Vagrantfile
/ lxc config file in order to track the issue down.
You can also benefit from this if you want to enable LXC Upstart Jobs
for your vagrant-lxc containers on a real server. Although the VM won’t be provisioned
automatically and ports won’t be forwarded like it normally would when using
shared folders should work just fine and you can easily set up some shared socket
for communication between the host and the guest container to avoid the need of using
To better understand the new port forwarding, upstart and debugging capabilities
check out the Asciicasts below. To save you some wait time, I’ll use the setup
described on this gist
with the VBox VM
already running and the inner vagrant-lxc container
created. The VBox VM has Nginx
installed and is configured
to use proxy
/unicorn requests to a Ruby Rack
“Hello world” application
running behind an Unicorn Server
listening on an UNIX socket shared
between the VBox VM and vagrant-lxc container.
I’ve had some trouble recording the Asciicast in one go, so I had to split it into 2 recordings
Part I - Debugging and port forwarding
Part II - vagrant-lxc container upstart and shared folders
How does vagrant-lxc 1.0 look like?
I’ve been asking myself that question for a while now and I think I have a good
list of things to accomplish to reach 1.0. I believe the plugin is pretty stable
at this point (at least for myself) and most of the pain points from the initial
releases have been sorted out (like
sudoing and forwarded ports collision detection)
so I might slow down a bit and focus on other projects for a while.
Of course the list is subject to change but here’s what I have in mind:
- First class networking support, allowing configuration for both public and private networks.
Extract port forwarding with
redirout to a separate plugin.
- Write documentation for using the plugin on at least 2 distros other than Ubuntu and Debian (and probably do some internal changes along the way to make things smoother).
- Find ways of leveraging lxc-clone / BTRFS.
- Add support for VirtualBox-like snapshots and ephemeral containers.
If you can think of something else or have any suggestion feel free to reach out ;)
UPDATE: Please check out this other post to find out more about my latest plans regarding 1.0