понедельник, 23 сентября 2013 г.

vagrant mac os x делаем доступную виртуалку на 80 порту

Web Development on Port 80 and 443 in Vagrant

In this post I'm going to talk about using port 80 and 443 for web development on a Mac running 1 or more virtual machines under Vagrant.

Why use port 80 and port 443?

Port 80 is the standard port for HTTP and 443 is the standard port for HTTPS. While other ports can be used, they're non-standard, and some (if not most) webapps make assumptions about those port numbers. You can really get burned on matters of HTTP redirection, such as when a form is submitted or when redirection from HTTP to HTTPS happens. While applications can certainly be built to take the port numbers into account, many are not.
Unfortunately, it's not a simple matter of telling configuring your Vagrant instance to listen on ports 80 and 443. Any port under 1024 requires the program to be running as root. And running an app as the root user is generall y never a good idea.

Can I forward ports from the Vagrant instance?

Why yes, you can! It's as simple as putting these lines in your Vagrantfile:
config.vm.forward_port 80, 8080
config.vm.forward_port 443, 8443

Wait, those are ports 8080 and 8443!

Yes, they are. Remember what I said about needing to be the root user? But, under Mac OS/X we can forward ports 80 and 443 to ports 8080 and 8433. The trick is to use the ipfw utility which comes with OS/X and is used to manage its built in firewall.
Here's a "quick and dirty" way to do it from the command line:
sudo ipfw add 100 fwd 127.0.0.1,8080 tcp from any to me 80
sudo ipfw add 101 fwd 127.0.0.1,8443 tcp from any to me 443
From that point on, attempting to connect to http://localhost/ and https://localhost/ will be forwarded by ipfw to ports 8080 and 8433, which will be received by Vagrant which will in turn forward any traffic sent there to ports 80 and 443 on its virtual machine.
Until you reboot, at least.

Is there a way to make this forwarding permanent?

Yes, there is. It involves setting up a service through OS/X that is started at bootup.
The first step is to set up a plist in the file /Library/LaunchDaemons/org.dmuth.ipfw.plist:
xml version="1.0" encoding="UTF-8"?>
 
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>org.dmuth.ipfw</string>
    <key>Program</key>
    <string>/sbin/ipfw</string>
    <key>ProgramArguments</key>
    <array>
      <string>/sbin/ipfw</string>
      <string>-q</string>
      <string>/etc/ipfw.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true>
  </true></dict>
</plist>
This will tell the machine that there is a new service which, when started, tells ipfw to load firewall rules out of the file /etc/ipfw.conf. That means we next need to populate /etc/ipfw.conf as follows:
#
# Flush all of our pre-existing rules.
#
flush
 
#
# Forward port 80 to our Vagrant instance.
#
add 100 fwd 127.0.0.1,8080 tcp from any to me 80
 
#
# Same deal for port 443
#
add 101 fwd 127.0.0.1,8443 tcp from any to me 443
Now we just need to enable the service. Run this on the command line
sudo launchctl load -w /Library/LaunchDaemons/org.dmuth.ipfw.plist

That was a lot of work!

It sure was. But it can be automated. This is the part where you should read my Chef 101 article because things like the above can be completely automated. In fact, I created a cookbook for the above. It can be installed with the following Chef command:
sudo chef-solo -c ./config.rb -o mac-os-x-ipfw