Why this tutorial?
I want best of both worlds. I want a development server, running on a Windows machine. I am sure I’m not the first to come to this conclusion. Many developers out there go for Mac OS X or Ubuntu systems. I don’t want that. I want PhotoShop, not GIMP, I want to run any given Windows game or app at any time, so there it is. I also don’t want to bother with Windows-specifics for MySQL, PHP, Apache, Python, because the apps are usually going on a Linux or BSD system anyway.
I have been trying out FreeBSD as a virtual development server for quite some time now. Even though I have been using Windows since my first computer (some try-outs of Mandrake, Slackware, Ubuntu and RedHat as a desktop system aside), Windows just doesn’t fit the needs of a web developer. All open source software is actually made to be running on a Linux or BSD box ideally.
Why I chose FreeBSD over any given Linux flavour is, well, more like a coin-flip than a well-thought decision. I like the idea of a centralized base of source code, and it is very easy to get a clean an solid system without all kinds of programs and files scattered all over the file system. Read this excellent piece on FreeBSD and Linux to know what I’m talking about. Nevertheless, any given Linux might prove to be equally suitable.
Install the base system
I will be assuming you have basic shell knowledge of navigating inside a filesystem and viewing and editing files in a UNIX / Linux environment.
First, lets see what we need. Of course, we need a Virtual Machine. Since Sun’s Virtual Box is free, (you can compile the OSE, or get the binaries under the personal use licence), that seems a sensible choice. You will need a FreeBSD ISO image to get the base system installed. Get an image from FreeBSD.org. Make sure to get a RELEASE tagged version, in my case I took 7.2-RELEASE. You only need the boot-only image, we will pull the rest of the software from inside the installed system.
Whip up a new VirtualBox machine, and pick some sensible values for HD and memory size. I took 20GB and 256MB respectively, but you may find other values more fit. Consider temporarily using a bigger memory reserve (like 1GB) while installing, since you will be doing a lot of compiling. Use Bridged Ethernet as a network interface, so the box will get it’s own IP address in the network your PC is in. Mount the ISO image as a CD in VirtualBox and fire it up. You will get a boot loader for FreeBSD, just pick the default option and let FreeBSD start up. Follow the instructions for configuring your keyboard and locale. Pick the “expert installation” from the menu. I know, you are not an expert, neither am I, but we aren’t installing a insurance company server here, are we? 😉
In the following screens, choose A (for defaults) Q to reserve HD space, again choose A (for defaults) Q to reserve default partition space, pick the standard option as MBR. In the following menu, set “FTP” as your installation media and choose a nearby FTP server from the list. Choose minimal install from the main menu. When asked, try DHCP configuration for your network device, and choose a sensible hostname (e.g. mybsd). When done, you will be asked to set last options, choose no, use right mouse click on the CD icon of VirtualBox to unmount the cd, and exit install. The system now reboots the installed system.
You will get a login prompt, where you can log in as root without a password. Be sure to change the password directly after logging in, so you won’t have an open system. Do this with the command
Install the ports tree
The ports tree in FreeBSD is a huge collection of installation instructions for all kinds of software. These installation instructions are put together in make files, which usually fetch the source for the application from a ftp site, extract, compile and configure it, and put standard configuration files in place. These make scripts are made to be aware of already installed software, and check for dependencies before install. So, that is pretty convenient. This ports tree is centrally maintained, and gets updated through CVS. The tool you need for this is csup, and a config file called a “supfile”. This config file is, how convenient, available in /usr/share/examples/cvsup/ports-supfile:
cd ~ cp /usr/share/examples/cvsup/ports-supfile . ee ports-supfile
You will now open an editor called “ee” to edit the file. This editor is prepackaged and a bit more friendly than the alternative (*cough* vi *cough*). In the file, navigate to the
*default host=CHANGE_THIS.FreeBSD.org line. Replace the CHANGE_THIS.FreeBSD.org with an appropriate mirror from the CVSup mirror list. Now navigate to line that says “ports-all” and put a comment mark (
#) in front of it. We don’t need all of the ports. In my ports-supfile, all ports for specific languages (like chinese and arabic), and all ports for x11 (the X Window server) are commented out, the rest is included. You should comment out lines you don’t need, as opposed to deleting them, so you can easily change your mind later.
Save the file and exit by pressing [ESC] and hitting “aa”. Now execute
csup ports-supfile now to update the ports collection. The ports tree will be downloaded. In the mean time, we are going to config some other things.
Exploring the system
Open a second terminal by pressing ALT+F2. You can login as root with your freshly configured password. Execute the script “adduser” to create a new user for your system. Name this user whatever you want, you will be using this as your regular user. The default options are all ok, so you hit [Enter] on all the options except “invite user to other groups”. You can add the user to an existing group named “wheel” to make the user suitable for changing to root using “su”. With the su (switch user) command, you can change your session to another user’s, which is typically useful if you’re logged in through ssh and you need to get root privileges.
Test the user by opening a third terminal using Alt+F3, and login with your just created credentials. If you have done it right, and you didn’t forget the password you just entered twice (:P), you will be logged in as a regular user. Close the session by hitting CTRL+D or typing logout. Do the same on the second terminal. It is never a good idea to leave root sessions open, even though it is a local server, it’s just a good practice to close root sessions you are not using.
A little heads-up here: FreeBSD is organized around a very simple basic principle. Everything that is not “core” system, goes into /usr/local/. All config files go into a folder called “/etc” for the base system, and “/usr/local/etc” for non-base software (i.e., software you install yourself). Binaries (executable files) go into /bin for the base system, and in/usr/local/bin for your own installed software. Check this out after you install software, or while you’re waiting when software is compiling. For more information on this, read the FreeBSD handbook. (Yes, you can read it online, Yes it is very n00b-friendly)
So, if all is well, and you have a relatively good internet tube, downloading your ports tree is about finished by now.
Installing applications from the ports tree
One of the first things I would want, is a bash shell for both my root and my regular user. To install it, go to
/usr/ports/shells/bash and type
make install clean. The “make” command is a utility that reads a Makefile and executes different sets of “targets” from it. These targets are built such, that they depend on other, more “atomic” targets. Much to read and to tell about this (for example a great tool to automate deployment of sites, think about it), but that’s for another occasion. In this particular case, “install” and “clean” are the two targets we want make to be executing. The “install” target will download the source packages, and install these, and the “clean” target will clean up all the stuff that is not necessarily needed after an install. (Note: There is a package manager available in FreeBSD, with which you can download and install binary packages. I am not really a fan of this, since it doesn’t give you the fine-grained the ports do. If you prefer to be up and running quickly, however, you could consider using the package installer
While installing, you might see something scrolling by you want to read. This is where the ever mysterious “scroll lock” button actually gets a function! WOW :o, you never thought that you might actually find out some day what that button originally was used for, huh? There you go, you can lock the scrolling of on-screen text with it, and navigate up and down to read the text. That is great 🙂 And by the way something I find myself doing on windows and putty screens more and more… without the expected result, unfortunately…
While installing, various config screens of the dependencies of bash will pop up, we’ll figure out a solution for this later. When done installing, be sure to edit ~/.bashrc and add the line
export EDITOR=ee. This sets the default editor to ee for actions which invoke an editor, like chsh. Yes, this will come in play pretty soon. Log out and log back in again to enable this “rc” script of bash, so ee will actually be your default editor.
To enable bash as your default shell now, execute the chsh (change shell) command for both root and your regular user. Edit the line that says Shell= … and replace the given shell with /usr/local/bin/bash. Exit and save the file, log out and back in again to see if anything has changed.
Now, we will install some stuff from the ports tree. I am assuming you would like Apache, PHP and MySQL installed. Nevertheless, if you like any other piece of software is needed, roughly the same instructions apply.
First, you need to figure out what the package is named. There is a very simple utility available called “whereis“, which will point out any location the given pattern occurs in, in either your binary folders, or your ports tree. You can use wildcards, so for example, whereis mysql* would render a list of available mysql-server and mysql-client versions in the ports tree.
We’ll start with apache. I prefer apache 2.0, since it is just the version I am most familiar with. You could go for apache 2.2, however, as you will see when executing whereis apache*. I have a simple script which I use to configure dependencies of a package to install. As you might have experienced while installing bash, it is quite annoying that the config screens pop up every now and then for most of the dependencies. You can put the following script in /root/bin:
#!/usr/local/bin/bash cwd=`pwd` make config for i in `make all-depends-list`; do cd $i make config done cd $cwd
Give this script some nifty name like ports_config.sh and make a symlink to this script in /root/bin, called “ports_config”:
cd ~/bin ln -s ports_config.sh ./ports_config chmod 755 ./ports_config
I use symlinks for this, so I can easily change the implementation of the script without the need to change the extension of the script. Say I want to make a cool python implementation for the script, I can easily do so, by adding a ports_config.py in /root/bin and relinking the ports_config link to the python script, without the need of getting rid of the habit of typing ports_config.sh
Now return to /usr/ports/www/apache20 and execute the script. Various config screens will popup for each of the dependencies of apache. After choosing the appropriate installation options, run make install clean and go make yourself a cup of coffee. With this info, I think you will be able to install php5 and mysql likewise. I’d advice to first install mysql51-server, and then php5-pdo_mysql, since php5-pdo_mysql depends on php5, php5-mysql and php5-pdo, so you don’t need to explicitly install those. Don’t forget to run the ports_config script before installing each, and choose both the CLI and Apache module version for php5. Don’t get “trigger happy” when seeing the config screens. Read options, and only leave options you don’t know or don’t understand to their defaults.
After installation, you can edit /etc/rc.conf.local to add the following lines:
sshd_enable=YES httpd_enable=YES mysqld_enable=YES
to enable the ssh, httpd and mysql daemons respectively in the “rc” scripts. These rc scripts are executed on startup of the system (specifically “init”), and need these variables set to fire up the servers. Moreover, if you now run /usr/local/etc/rc.d/apache2 start it will actually do something, namely starting up apache. This is quite different from a lot of Linux, so this might save you some time if you are used to other init strategies.
Typically, you will need to modify /usr/local/etc/apache2/httpd.conf to fit your needs first, but I am assuming you either know how to do that, or you have another source that tells you how 😉 The logs are kept in /var/log/apache2. Test the server by surfing to the IP address of the box in your host Windows machine. If you haven’t done something horribly wrong, you should get the standard test page.
If you payed careful attention, you would have seen a line saying you need to add some lines to the httpd.conf at the end of the php5 module installation, to make PHP working. I prefer to keep the httpd.conf as clean as possible, so I created /usr/local/etc/apache2/Includes/php.conf which contains the line:
I don’t use the phps format to display php source ever, so I didn’t add that line. All files in /usr/local/etc/apache2/Includes/ are included in the httpd.conf.
Create a file “inf.php” in /usr/local/www/data/ and put the line
<?php phpinfo(); ?>
in it to test the PHP installation. Of course you need to restart apache to enable the changes just made to the configuration. Do this again with the rc script, /usr/local/etc/rc.d/apache2 restart, and navigate to the IP address of your server (if you don’t know this, execute the ifconfig command from the console and look for the IP address there) and see if the inf.php script actually gives the PHP info page. You will notice the php installation is quite bare, so any extra modules needed need to be installed from the ports tree. One of the obvious misses is PCRE, but you might like gd, mcrypt, and mb support. You know how to build these now, so go ahead. Explore the ports tree to find if you’d like to install any other php module as well. Don’t forget to restart the apache server after installing new modules.
The mysql server is open to root from the localhost by default. I’d say you’d like a password for that, so change it with a query after logging in mysql with the mysql command line tool:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '[password]'; FLUSH PRIVILEGES;
Log out from mysql and try logging in with your new password. You could grant privileges to a user on your host machine, so you can easily connect with any desktop client you might use. You could also add a user you’d use in your php applications. This is all mysql specific and I am assuming you either know how to do this, or know how to find out how to do this. If not, you can of course ask here. Someone might actually help 😛
Now you would like to have samba installed, to easily access your server from the host machine. Go to the /usr/ports/net/samba3 dir and install the port. After installation, you need to add the samba_enable=YES line to /etc/rc.conf.local. Add your own user to samba by executing
smbpasswd -a you where “you” needs to be replaced with your regular user’s username, and -a stands for “add”. Fire up the samba server by calling, how very surprising, /usr/local/etc/rc.d/samba start. Check out if your FreeBSD server is now accessible at it’s IP address in Windows by going to \22.214.171.124\, and type in your user’s username and password. You should see your home directory appearing under your own user’s name, and you can put files here.
To sum up
You now have a very cool development environment available. Of course, there’s a lot to be done to get actually to developing on this box, but the basics are there. If you have any basic knowledge of how to configure Apache in Windows, you now know how to find the config files in FreeBSD, so don’t think it will be all that different! Also, you are the master-creator of this machine, so you can configure it any way you like. Be creative!
Some final tips
- You can install almost everything you can think of through the ports, even things like PEAR distributed applications, such as phpunit, phpdocumentor, and stuff like that.
- Read the FreeBSD handbook. At least scan through it one quick time. It is very explanatory and a very easy read.
- Replace the standard “Right CTRL” button for VirtualBox’s input grabber with F12, or some other button you probably won’t use. Unfortunately VirtualBox doesn’t support keyboard combinations for this…
- Use putty for easy access to the machine, so you don’t need to get in and out of the virtualbox screen.
- You might want to install webmin. It is a handy web based tool for people who aren’t used to working with shells.
- If you have trouble installing ports, read the Makefile or Makefile.doc (if available) for available options. Try to update the ports tree using csup and cleaning the port and installing it again before googling (it might save you a lot of time searching for non-problem), and then google for the exact error message. Chances are someone already had the same problem you had, and has got a solution from someone.
- Make snapshots in VirtualBox of your system before installing software you don’t know well, or to try out things like deleting the entire /root partition.
- Never forget to backup your data regularly, both to your host machine and outside. FreeBSD is very stable, but you might not always be 😉
I hope you had fun reading this, and actually tried it out. Of course, I am open to comments, suggestions and questions as always. Also of course, anything you do based on this tutorial is at your own risk 😉
Have fun developing on your cool new V-FAMP d:)b
09/17/2009- I found a blogpost covering [url=http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-virtualbox-1865.html]the installation of VirtualBox for FreeBSD[/] a bit more in detail. ↩
I found out later that there is a port available “lang/php5-extensions” which is actually what is called a “meta port” enabling you to quickly choose and install the available php5 extensions, with the defaults being the defaults normally shipped with php5. ↩