(not going to finish) Production web serving with Cygwin - PHP, Ruby on Rails & ColdFusion


Note: I'm not going to finish this article as ultimately I ran into problems with Cygwin so migrated to running all Windows-native tasks. Still, in its raw state someone might find some use out of it.

Web development is an interesting field. Many of the technologies you try or wish to use work best with a specific requirement, for example despite attempts to the contrary ASP simply works best on Windows with IIS. Another example of this notion that has become rather common of late is that Ruby on Rails and its related tools really work best on UNIX-like operating systems and doesn't work as well on Windows.

For those "stuck" with Windows for their production web serving there is, however, a work-around called Cygwin, a UNIX compatiblity layer for Windows that has been around since the mid 90's so is very mature and well supported. Cygwin provides the best of both the UNIX world with a robust platform for running many UNIX-only tools, while still providing the Windows foundation which is often needed for e.g. proprietary database drivers. Read on as a give a full list of what you need to install, and how to configure, all of the tools necessary for a pretty comprehensive web development production environment.

Installing Cygwin

The first step is to obtain the Cygwin installer executable from Run the cygwin.exe program when you download it and you'll see something like the following:
Following through the prompts you'll want to first "Install from Internet" to download all of the required files and install them immediately. On the next screen you'll pick where to install Cygwin, whether to install it for all users or just yourself and whether to make data files use the UNIX or DOS/Windows format - I only ever change the directory path and leave the others at the defaults; the next screen asks where you want to keep the downloaded files, I recommend a sub-directory of where you're installing the main Cygwin system, just to keep them close at hand. The next two screens will ask for your network settings (most people can leave the defaults) and then to pick the Cygwin server to obtain all of the files from - I suggest going through the list and trying some to see how fast they are before picking a favorite.

The next screen is where all the fun is - you get to pick what software to install. I recommend clicking the "View" button to make the list change to a plain list of all of the available software, and maximizing the window, as it can be confusing to work out what category certain apps are in.
Here are the packages we are going to need, besides the basics:

  • apache2
  • gcc
  • gcc-g++
  • gnupg
  • ImageMagick
  • nano
  • curl
  • mhash
  • openssh
  • ruby
  • subversion
  • unzip
  • wget
  • whois
  • make
  • openssl-devel
  • ping
  • bison
  • flex
  • libmcrypt
  • libmcrypt-devel

ssh-host-config -y
Give a password
ntsec tty

make -f Makefile.cygwin
make -f Makefile.cygwin install

Ruby on Rails

ruby installed via cygwin
download rubygems
ruby setup.rb
gem install --remote --include-dependencies rails
gem install --remote --include-dependencies mongrel
gem install --remote --include-dependencies mongrel_cluster
gem install --remote --include-dependencies capistrano
gem install --remote --include-dependencies image_science
gem install --remote --include-dependencies hpricot

SQL Server

dmckenna@websrv /home/dmckenna/ruby-dbi
$ mkdir /lib/ruby/site_ruby/1.8/DBD

dmckenna@websrv /home/dmckenna/ruby-dbi
$ mkdir /lib/ruby/site_ruby/1.8/DBD/ADO

dmckenna@websrv /home/dmckenna/ruby-dbi
$ cp lib/dbd/ADO.rb /lib/ruby/site_ruby/1.8/DBD/ADO

Why I don't use Cygwin for SFTP


In the UNIXy (UNIX, BSD, Linux, OSX) world secure file transfers have been the norm for years, thanks in part to the standardization of SSH as the security protocol due to both its simplicity and power. Windows, on the other hand, has never featured security as a very important feature, evidenced by the ellaborate routes someone must take to handle SSL in IIS.

As a stop-gap measure many people have started to use the UNIX compatibility layer Cygwin, which is a wonderful system that lets you run and/or compile UNIX software on Windows. One of Cygwin's many available software packages is OpenSSH, the defacto standard SSH daemon in the UNIXy world, so by using Cygwin you can set up SSH for your Windows server. There's just one problem - it doesn't work well.

The problem with SSH, or indeed any UNIXy compatibility layer, on Windows is the age old problem that the traditional UNIXy file & directory security system is completely different to what Windows provides.

UNIX file security is based on setting the Read, Write and eXecute (thus RWX) status on any given file for both you (aka the User), anyone in your Group (or more specifically the file's assigned group) and the Other users on the computer (thus UGO). As an example, if your file is set to allow all three (UGO) to Read & Write to the file then anyone who has access to the machine can open & change the file. A common way to list these settings is in the form of octal values - Read is 4, Write is 2 and eXecute is 1, with the numbers added together for each user type, so the common setting of U=RWX,GO=RX becomes 755.

Windows file security is based on Access Control Lists (ACLs), which are basically lists of individual users and groups and their associated permissions. Rather than restricting you to only assigning permissions at three levels (UGO) you are completely open to decide what groups and users can do what to your files. This gives a great amount of flexibility as you can more easily mix 'n match security groups and group memberships. An example might be allowing both the Executive and IT groups could read a reports directory but only Accounting to modify files there.

As you can guess there's going to be issues trying to superimpose the UNIX UGO-style permissions on top of Windows' ACLs, and there are.

When you install Cygwin first it grabs a copy of the current users & groups settings from Active Directory (or your local computer, if you aren't in a domain) and saves them out as /etc/passwd and /etc/group in the standard UNIX format.

The first issue with this system is that every time the user groups and user accounts change you have to re-import the accounts settings. While, yes, you can create a cron event to automate this, the problem gets worse ...

The next issue is that it doesn't correctly handle the user's primary user group, mainly because Window's doesn't have such a thing, so instead it assigns all users to an invalid group. Now, on top of having to automate synchronizing with the Windows accounts system you have to work out how to put users into their proper groups so that their files are properly acessible.

There's another problem: when you log in through sftp any files uploaded have the file permissions set incorrectly. Thankfully there's a way of fixing this using a kludge to override the sftp defaults, but who likes kludges?

The problem gets worse with directories: all directories created are assigned the default usergroup listed, and coupled with the file permissions problem it leaves your directory structure so that only the original user can view files in the new directory. And no, there's no way to fix it using SFTP, you need to log in with a full shell session to run chown on the directory in question - not something you want your average non-technical designer doing on your production web server.

So, combine the four problems above and you end up with a really messy system that ultimate simply doesn't work cleanly.

It is for the above hassles that at work we've paid hard cash for Vandyke's VShell ssh server, which works wonderfully well by the way.

MySQL + Rails on Cygwin tip


Here's a really quick tip for anyone using Rails on Cygwin. If you want to connect to a MySQL database the understood practice is to compile MySQL and go through the hassle of getting it all working within Cygwin itself. After what I've gone through with it all, the best way of getting this combination to work is to:

  • Install MySQL under Windows itself rather than Cygwin.
  • Make sure that the MySQL binaries are in your system path under Windows and, if installing via SSH, restart the Cygwin SSH service so that your login will be able to see the new path.
  • When installing the MySQL gem (gem install mysql) select the mswin32 option rather than the pure Ruby option.
  • Now, when you define your database connections just give the machine's IP address instead of saying "localhost" and it'll work great!

After wasting several days getting it all to work the "proper" way, the above is a much cleaner solution.

Compiling software is a pain - Cygwin, PHP, MySQL


I'm working on a lengthy article explaining how to install a bunch of web server software in Cygwin and I've found that I have to manually compile several key pieces. While I'm not unwilling to do this, the sheer hassle of having to go back 'n forth testing different configuration and installation options is a pain. Why on earth PostgreSQL can be available through the Cygwin installer but MySQL isn't is beyond me, likewise for PHP - every Linux distribution on the face of the planet includes them so why can't Cygwin? I've easily lost over a day of work due to this, a day that I could have spent designing a new system in Ruby on Rails that I've been tasked with.


Subscribe to Cygwin