My Little Corner of the Net

Vesta CP

I’ve been running most of my personal sites from a VPS running the Interworx control panel on CentOS for the past several years. After a long, stable run, my operating system reached end of life and it was time to upgrade.

I’m pretty comfortable with the Linux command line, I have a ton of experience configuring Apache, and I’m pretty good at keeping MySQL up and running, so I could probably get away without a control panel. On the other hand, I have very little experience with mail servers and I like the convenience of a point-and-click interface to handle most of my administrative needs. Happy with Interworx, I considered buying a new Interworx license for the new server, but I also wanted to shop the competition a bit as well. That’s when I discovered that there are quite a few open source control panels available.

I started downloading some of the open source panels and installed them on VMWare virtual machines on my laptop to try them out. Most, I found, either had questionable histories in terms of security, didn’t seem to be in active development, or had horrible user interfaces. Others, like ISPConfig, took perceived security a bit too far, forcing PHP into such a small sandbox that much of my code, which follows industry best practices in terms of structure and security, would not work without extensive modification.

I finally tried and settled on Vesta, a relatively new PHP-based control panel launched by a Russian development team in early 2013. Vesta offers the essential features for hosting, like web, database, email, and DNS, without a lot of unnecessary cruft. Installation was easy and while I do think the UI and UX could use a little work, Vesta’s web front-end is cleanly designed and easy to use.

Installation

Vesta is designed to be installed on a “bare metal” server with just an operating system installed. While I chose RedHat-clone CentOS for my server, Vesta will also run on Debian-based systems like Ubuntu. Setup is as easy as downloading a script and running it on the command line; the script then uses the OS’s package manager to download and install all of its components, making it easy to keep things up to date as the OS releases updated packages.

Accounts

Vesta accounts are standard Linux accounts which are created in /home. Each account can host multiple websites and, I believe, accounts can be configured as resellers, so that they can create new accounts as well. Several quotas are enforced, including disk space, number of sites, and number of email accounts per site. You can also manage the account’s shell from the web interface, including a “nologin” option if you want to disable command line access to the account (and allow FTP access only).

Vesta stores all of the config files used by an account in the account’s home directory, symlinking them to the locations where their respective applications expect to see them. This makes backing up a site is a snap—in fact, Vesta backs up every site automatically each night, keeping the last three backups available as a downloadable tar file.

When adding a site, DNS zone is created automatically. You can also specify any number of alias domains and these will be set up automatically as well.

I did not see a way to “jail” (chroot) an account, though this isn’t important to me as I am the only user with direct access to the server.

One thing that bugged me a bit was that vesta’s quota settings did not seem to allow for “unlimited” options. In Interworx I created an “unlimited package” to which I subscribe all of my sites, effectively disabling individual site quotas. In Vesta I simply set all of my limits extremely high, to the point that I should never exceed any of them.

Web

Vesta installs both Nginx and Apache web servers, and is the only control panel I’ve seen that does this. Nginx, known for being extremely fast, sits at the front end and handles most static content while proxying anything it can’t handle to Apache. This helps speed up response times for things like images and CSS files while still allowing most off-the-shelf web software, like WordPress and Drupal, to run without modification, since most of these packages are preconfigured to run on Apache.

There are several options available for Nginx, including the ability to use it as a reverse proxy cache. Caching requires a lot of memory, however, so I wouldn’t recommend trying this on a VPS.

Early on I was having an issue where Apache would keep consuming more and more memory until the server ran out of RAM, at which point MySQL would be shut down. Since MySQL is a requirement of most of my sites, this wasn’t acceptable, so I started trying to tune Apache to avoid it. After several failed attempts (I never did find a definite cause), I switched Apache to use Worker MPM (i.e. threaded processes) and the memory footprint of the server immediately dropped to almost zero. While Worker mode is not compatible with several Apache modules, experience has taught me that it can be a huge help in improving server performance. In fact, it probably negates the benefits of running Nginx now, but I don’t feel like trying to configure Nginx out of the picture.

Database

Vesta installs MySQL by default. It looks like a patch for adding PostgreSQL support is also available, but I haven’t tried it.

PHP

Vesta installs the OS’s PHP packages. By default, it runs PHP under mod_ruid which, by my understanding, is basically a variation of mod_php that runs scripts under the owner’s UID. This can be changed, on a per-site basis, to several other options including straight CGI and PHP-FPM.

I’ve decided to use mod_fcgid because this is what I have the most experience using and because it works well in the enterprise hosting environment I oversee at work. I did have to tweak the default settings a bit to get the best performance for my server’s resources, but I kind of expect that every server is going to need some degree of customization to balance available resources to desired performance level. With the tweaks in place, my PHP sites load quickly with minimal memory overhead.

CentOS 6 ships with PHP 5.3. After the installation I decided to upgrade to PHP 5.5 using the Webtatic repo. I basically did a “yum erase” on each of the installed “php” packages and installed the equivalent “php55w” package in its place (note that they are not a 1:1 match). So far I have not seen a single issue with this, though YMMV.

DNS

Vesta installs BIND 9 as its DNS server. The Vesta web interface makes it easy to configure manual DNS zones for domains not hosted on the server or for adding adding additional records to hosted domains.

With my old host, I had three IP addresses, one for the server and two to use as “separate” DNS servers. Without getting into the reasons why this is a bad idea, this is how I ran my DNS for the past several years, though it did burn me a couple times. My new host only allows one IP per server, so for a backup DNS I installed PowerDNS on another VPS I have with another provider in another datacenter. With PowerDNS’s MySQL storage engine and the concept of “supermasters” plus a tiny config change to Vesta’s main BIND configuration, the secondary server is updated automatically every time I add or change a domain in Vesta, making my NS2 server truly “set and forget.”

Mail

Vesta uses Exim as its MTA (SMTP) and Dovecot as its MDA (POP3 and IMAP).

Email accounts are configured in the Vesta web interface and can be set up with any number of aliases. Incoming messages can be forwarded elsewhere, with or without a copy being kept, and you can specify an auto-reply message to send when mail is received. RoundCube is installed for webmail.

Vesta will install SpamAssassin and ClamAV (clamd) automatically if a server has more than 3Gb of RAM. Mine does not, so I had to install them manually. SpamAssassin was not a problem, but on my first attempt on building the server, with 512Mb of RAM, I was not able to start clamd. After reconfiguring the VPS to have 1Gb of RAM, I was able to start clamd, but it consumed most of my available memory. At that point, I decided that I didn’t really need to virus scan my email on the server, so I disabled it. I enabled it again after seeing how little memory Apache was using after switching to Worker and I’m now consistently using a bit less 50% of my available memory when the server is at normal load. I could probably switch back to 512Mb, but I don’t plan to. For the email that I’ve received on the new server, only two or three spam messages have made it to my inbox.

What Vesta is missing is an easy way to create email forwarders that aren’t attached to an email account. One of the sites that I’m hosting makes extensive use of these. Fortunately I was able to locate where Exim stores aliases for the domains it manages and I added them all manually. I also tested to ensure that my manual edits would be safe when I make email changes in Vesta and so far they seem to be, but I’m being careful to keep a backup of that file, just in case.

Vesta also doesn’t include a mailing list manager. One of the sites I host relies heavily on mailing lists, currently with Mailman. I tried to get Mailman working with Vesta and thought I had a solution in place, but I ran into some complications when I started moving the lists over. To prevent delays in my migration, I created a subdomain on a cPanel server and used it’s built in Mailman installation to manage the lists for now. I still plan to continue working on getting Mailman running and who knows, I might submit my method to the Vesta team for future implementation if I’m successful.

Conclusion

While I’m not sure that I’d use Vesta as a control panel for hosting paying clients, as it still has some rough edges, I think it will meet my personal needs quite well. The product still has some bugs, but in the month or so since I’ve installed it, I’ve already seen several of them fixed. The development team seems to be focused on making a lightweight control panel that works well on small servers and VPSes, which is nice to see.

Vesta documentation is still somewhat lacking, consisting of mostly just an FAQ page right now. There is a user forum and a bug/feature request tracker, but being a Russian project, many of the posts are in Russian. Still, Vesta seems to be catching on, so it is hopefully only a matter of time before documentation improvements start to be made. Truth be told, I haven’t had much of a need for more documentation, but I’d suspect someone with less Linux administration experience might. The developers do offer paid support plans, but I have not purchased one.

My biggest gripe with Vesta is how it formats lists: lists of users, sites, domains, etc. are extremely verbose with all of the details of the list item presented, making the page difficult to scan or to find the links to administrative actions for a list item. Clicking to do simple, everyday actions, like modifying an email address, often takes several more clicks than seem necessary. I’d much rather see terser lists with clear calls to action, including the option to see more info about a list item when I need to. That said, this is a wart I can live with.

So far, after some tweaking, Vesta seems like a pretty good panel. It will be interesting to watch as it progresses over the next few years, I think it has a lot of potential.

M.T.A.

“Why’s it called a CharlieTicket?” I asked of the ticket I bought so that the troop could ride the “T” into Boston earlier this week, proving that while I may have grown up in Massachusetts, I am not a Bostonian.

Local TV Nightly Sign-Off

It’s hard to believe that, back when I was in high school (though I know that really was a long time ago now), local television stations didn’t broadcast 24-hours a day. Here’s a nightly sign-off clip from WOKR (now 13-WHAM) in Rochester, recorded in 1992, that I stumbled upon on YouTube. The recognizable voice of Don Alhart provides the voiceover.

Why I Shop at Wegmans

In Rochester we basically have two options when it comes to grocery shopping: the Buffalo-based Tops and the locally based, family-owned Wegmans. While Wegmans is a market leader in innovative convenience and prepared food items, for regular grocery items, the stores are pretty much the same. Tops often has some good “stock-up” deals like 10 jars of spaghetti sauce for $10 and, until recently, most Wegman’s stores have seemed cleaner and more modern, but dollar for dollar, it doesn’t seem to make much difference where I shop. So why, when I drive past a Tops store twice almost every day, do I often go out of my way to shop at Wegmans?

Today I ran into the Pittsford Wegmans store for a few things. As I was coming out, I made eye contact with on of the stores “Helping Hands” (the employees who fetch carts and help people load their cars) who looked like he may have been one of the Lost Boys. He was bundled up in a rain coat as he returned a bunch of carts to the store.

This employee could have just turned around and went back outside and I would have thought nothing of it. The store was packed, the line of available carts was about half of what it should have been, and he probably had several more trips to make. But he didn’t. Instead he stopped and said “have a nice day, sir.” Then, as he noticed me taking my bags out of the cart (I only had two, so it was easier to leave the cart in the store and carry the bags to my car), he walked over to me and said “let me get that for you,” taking the cart from me. “Thank you,” I said. “You’re welcome. Have a nice day,” he replied as I walked outside.

That’s when it hit me. The whole reason I go to Wegmans is for the people. I have, on occasion, shopped at Tops without anyone in the store saying a word to me, not even the cashier ringing me up. At Wegmans everyone is friendly and will go out of their way to help you.

Wegmans has consistently made the top ten of Fortune‘s “Best 100 Companies to Work For” list for many years, but they don’t need a prestigious award to show that they care for and about their employees. It is evident in the way that every employee treats every customer.

Mac OS X: Automating Tasks on Sleep

I’ve been playing a lot lately with AppleScript and the Mac Automater app, both of which can do some pretty cool stuff. This gave me an idea: wouldn’t it be great if I could close certain applications when my commuters go to sleep?

I have a handful of programs that I run on both my MacBook and Mac Pro desktop at work, using file syncing tools like Dropbox or BTSync to keep the data files up to date on both machines. This generally works great, except that I have to remember to close the programs when I switch machines, otherwise I sometimes end up with unexpected results like locked files or, in some cases, data loss. I’m not so good at this and Apple doesn’t appear to provide a way to do it for me.

It didn’t take long, however, to find a free third-party utility that does. Sleepwatcher is a small daemon process that monitors the sate of your system and kicks off a shell script when certain system events occur. It can monitor for events such as sleep and wake up, display sleep and dimming, and even system idle (a specified period with no keyboard or mouse activity) and power status (when a MacBook switches from AC to battery power and vice-versa). It can also prevent the machine from sleeping based on the result of a script or it can run a script when another process prevents the system from sleeping. Sleepwatcher can be run as a system process (always running in the background, even when no users are logged in), as a user process for individual logged-in users, or both.

Before we get too far along, it should be noted that this may not be the best approach for all applications. The method I’m about to describe works best with applications that save their data files automatically, and exit without user intervention. While the applications will be shut down in a clean manner, you may have unexpected results if the application prompts you to save or to confirm that you really want to quit.

It is also very important to note that you should be extremely careful when implementing these scripts. An improper configuration could render your machine unable to sleep, wakeup, or even boot, so be sure to carefully test your scripts before enabling them to run automatically.

Installing Sleepwatcher from the developer’s site is a bit tricky as it comes with no installer and assumes some knowledge of the Unix command line. A much easier way to install it is to use a package manager such as Homebrew (I believe MacPorts can also install Sleepwatcher, but I’ve only done it with Homebrew). If you aren’t familiar with Homebrew, it is definitely worth checking out.

Assuming that you have Homebrew installed and working correctly, installing Sleepwatcher is as easy as running the following command in a terminal window:

brew install sleepwatcher

Homebrew will download and install Sleepwatcher at /usr/local/sbin/sleepwatcher. Note the followup instructions that Homebrew provides after installation, as we’ll get to them in a moment. Once the installation is is done, I recommend reading the man page, as it is the best way to get to know everything Sleepwatcher can do:

man sleepwatcher

Now it’s time to write a sleep script. As we’ll find out in a moment, Sleepwatcher looks for user scripts named ~/.sleep and ~/.wakeup and system scripts named /etc/rc.sleep and /etc/rc.wakeup. Since we want to close programs that are running under our own UID, let’s choose the local user option.

First, create a file named .sleep in your home directory using your editor of choice (mine is vi for this kind of stuff):

vi ~/.sleep

Then add the following to the file (in this example, I’m going to close the program KeePassX, my password manager, using AppleScript):

#!/bin/bash
osascript -e 'tell application "KeyPassX" to quit'

If you want to close additional applications, simply add another osascript command for each additional application.

Why use AppleScript instead of something more bash-like, such as kill? AppleScript works inside the application, telling it to do a clean exit, such as if I pressed Comand-Q to close it myself. This allows the program to make sure files are saved and everything is in order before the process ends. Kill simply aborts the running process, regardless of what’s happening, which could result in data loss and other instabilities, which we’re trying to prevent in the first place.

After the script is saved, you’ll need to give it execute premissions:

chmod 700 ~/.sleep

New we’re ready to test the script. Enter the following in a terminal window to start Sleepwatcher:

/usr/local/sbin/sleepwatcher --verbose --sleep ~/.sleep

You won’t see anything happen; in fact, it will look like the terminal is hanging. Make sure KeePassX (or whatever program you added to the .sleep file) is running and then close the lid of your MacBook (or go to Apple Menu > Sleep if you aren’t on a MacBook). Wait until the computer’s power light starts to slowly blink on and off, and then wake it by opening the lid and/or pressing the power button. The computer should resume exactly as you left it except that your target application should no longer be running. If anything went wrong, check the terminal window where you ran Sleepwatcher, it should show any errors that occurred. Press Control-C to stop Sleepwatcher.

Now it is time to configure launchd to run Sleepwatcher at startup or login. To do this, we need to add a plist file to our user or system’s LaunchAgents directory. Sleepwatcher comes with sample plist files that handle the four use cases mentioned above: user sleep, user wakeup, system sleep, and system wakeup.

If you only need support for sleep and wakeup, you can simply symlink the sample files to the proper LauchAgents directories. For this activity we only need to set up the user LaunchAgent since we aren’t using any system scripts:

ln -sfv /usr/local/Cellar/sleepwatcher/2.2/de.bernhard-baehr.sleepwatcher-20compatibility-localuser.plist ~/Library/LaunchAgents/

Then we tell launchd to load the configuration:

launchctl load ~/Library/LaunchAgents/de.bernhard-baehr.sleepwatcher-20compatibility-localuser.plist

Although not required in this example, to install the system agent, do the following:

sudo ln -sfv /usr/local/Cellar/sleepwatcher/2.2/de.bernhard-baehr.sleepwatcher-20compatibility.plist /Library/LaunchAgents/
sudo launchctl /Library/LaunchAgents/de.bernhard-baehr.sleepwatcher-20compatibility.plist

Note that you’ll need to be an administrator of the machine to install the system agent.

That’s about all there is to it! Sleepwatcher is now running in the background waiting for your computer to go to sleep. When they system does, Sleepwatcher will kick off your .sleep script and, when the system resumes, Sleepwatcher will run your .wakeup script (if you create one). And, since you also added the plist file to your LaunchAgents directory, launchd will find it and start Sleepwatcher every time your machine starts up or whenever you log in.

If you want to script other events, such as system idle or power status, you’ll need to make a copy of the sample plist file(s) and edit them by hand. Understanding the plist file format should be fairly straightforward if you compare the sample with the options described on the man page. Xcode features a graphical plist editor, but plists are simple XML files, so you can edit them in any text editor if you prefer.

Do you have a creative use for Sleepwatcher? Let me know about it in the comments.

<