Network Favicons

Network Favicons is a simple WordPress plugin that allows blog owners on a multisite network to upload a favicon to the root of their theme’s directory and have automatically be used as the site’s favicon. This requires a one-to-one relationship between blogs and themes, but that could be as simple as creating a child theme for the favicon if you’re already using the same theme on multiple blogs.

I made the theme for my new hosting network, network.joshbetz.com. This is where I’ll be hosting future client websites and I needed the ability to use custom favicons instead of just having my own favicon displayed on every blog.

Note: If no theme is available in a theme’s directory, the site still just use the default one provided at the domain’s root.

View in Plugin Directory Download on Github

Set up VirtualBox for Web Development

I’ve used many different development styles through the years. For a while I was a big fan of using Coda to develop live on the server. Recently I’m using more of Textmate and Transmit1. And, while I still like the how fast I can move while writing changes straight to the server, I don’t necessarily want to be doing anything that could potentially break a client’s website — even for a short time. The solution to this is pretty simple; run a virtual machine that acts just like the remote server. You can make your changes and when you’re sure it’s right, you can make one push up to the live site. This probably seems pretty obvious, but I’m going to talk about how I have my VM configured so that it works even on a strange network.

Goal

We want a virtual machine that has a static address that will work even if we pick up and decide to work out of a coffee shop for a day or, say, a warehouse in Northern California. It needs to act just like a production server, which means it also needs to be connected to the web.

Solution

  1. In Preferences, set up a VirtualBox network. Since this particular network is going to be for servers, we won’t worry about turning on a DHCP server. Screenshot
  2. Create a new VM in VirtualBox. I like Ubuntu, but you can use any distro you want. Use whatever specs work for you. It would be a good idea to mirror the production machine you’ll be working with as closely as possible. Don’t worry about networking on the machine yet — that’s next.
  3. Make sure the VM is not running and open its settings. Go to the network tab and verify that adapter 1 is still set for NAT. This is how the VM will access the internet.
  4. Click over to adapter 2. Check the box to enable the adapter and set it to use the network that we set up in step 1.
  5. Start the VM and open the network configuration file. In the current version of Ubuntu this is at /etc/network/interfaces. Make sure you leave eth0 as a dynamic interface and set eth1 as a static interface for your VirtualBox network. Screenshot
  6. Restart the machine and verify that it can access the internet. Also verify that you can access the machine from your host OS on the IP address you gave it.

Something I like to do, just to make this a little easier to work with is to set that address to a local domain in my hosts file. Something like local.dev seems to be popular, but you can name it whatever you want. Obviously if you name it google.com you’ll need to start using Bing or something. 😉

I realize this was a pretty quick overview of the process, so if there’s anything that was unclear, let me know in the comments or shoot me an email.


  1. Textmate with the Transmit bundle really makes Dropsend amazing. If you don’t know what I’m talking about, look for the Transmit bundle for Textmate and check out the secrets of transmit blog post that Panic wrote a while back. 

On Comments

On a whim, I decided to limit the amount of time the comment form is available on this site. 2 weeks. I saw a tweet from Fred Wilson1 and read the linked article. I continued to read the article that MG2 linked to and found myself rethinking blogs and comments.

This is a place for me to let people know what I think on certain issues when 140 characters isn’t enough, to do product reviews, or write tutorials. I’m not looking for comments from people telling me that my review was super helpful. That’s nice, but send me a note on twitter or send an email. I want comments that add to the article. If I missed a fact or you have an idea on how to do something better, that’s useful. After 2 weeks, the chance of useful comments goes down and the chance of “Good job!” goes way up – especially since I write mostly about technology that could be completely different from one day to the next. And if you really need to talk to me about an article or correct something I’ve said after 2 weeks, feel free to send an email. I’m always willing to have a conversation about the stuff I’m writing here.


  1. It’s important to note that Fred Wilson is an investor in Disqus, which is what I use here. Though, as MG points out in a follow up, he wouldn’t have invested if he didn’t believe in comments online. 
  2. After reading MG’s follow up, I don’t think he’s against comments in general, but doesn’t feel that they’re necessary in his case. I know he made a point of saying that comment systems are a facade, but in the last article he admits that comments can be useful on a case-by-case basis. 

WordPress & Low-Memory

I run a 256mb Cloud Server from Rackspace. As far as web servers go, you’re not going to find anything with less RAM. As long as you don’t have to deal with a ton of traffic, you can make this work pretty well. It’s taken me quite a bit of testing and research to get to where I am right now, so I wanted to share some of the things I’ve done in the never ending process of optimizing servers and increasing speed.

I work mainly with WordPress which puts somewhat of a limitation on what we can do. For example, if you start looking for ways to speed up Apache, one of the first things you’ll find is to turn off .htaccess. While we could do that, it would take more modification of core WordPress than I’m really willing to handle. If I’m going to be modifying anything, I’d rather have it be my web server configuration.

The main problem is that Apache really isn’t made for such harsh conditions. If you’re running a server with 4GB of RAM, you have some room for bloated software. This first tip can help speed up any web server though, and that’s installing nginx as a front-end to Apache. You could also use lighttpd, but I’ve read more about nginx and since that’s the solution I went with, that’s what I’ll document here.

Nginx is far more efficient at serving static files than Apache is. The reason we’re not going completely away from Apache is that it’s easier for most people to work with to serve the dynamic requests. So we want any static resources to be served by Nginx, and everything else can get passed through to Apache. And we’ll move Apache to port 81 and make sure it can’t be accessed from outside the server. That way, all the requests can be served instantly to Nginx and back across the web to our user.

One thing you’ll want to do before you install Nginx is turn off KeepAlive in the Apache configuration. Since Nginx will be the front-end, we’ll let that handle the KeepAlive requests.

I have a pretty simple Nginx configuration in nginx.conf

user www-data;
worker_processes 4;

error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
# multi_accept on;
}

http {
include /etc/nginx/mime.types;

access_log /var/log/nginx/access.log;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;

gzip on;
gzip_disable "MSIE [1-6].(?!.*SV1)";

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

And then the virtual host for this site looks like this:

server {
listen 80;
access_log /var/log/nginx/joshbetz.com.access.log;
server_name joshbetz.com;
root /var/www/joshbetz.com;

location / {
#root /var/www/joshbetz.com;
index index.html index.php;
error_page 404 = @dynamic;
}

location ~ .php$ {
proxy_pass http://localhost:81;
proxy_buffering on;
proxy_buffers 12 12k;
proxy_redirect off;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location @dynamic {
proxy_pass http://localhost:81;
proxy_buffering on;
proxy_buffers 12 12k;
proxy_redirect off;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location ~ /.ht {
deny all;
}
}

There’s a lot of research and trial & error involved in building this, but the basic idea is that we want to serve any static files directly, but anything that ends in .php should be forwarded on to Apache. You’ll notice the proxy_pass http://localhost:81; directive.

On that note, we’ll want to make sure Apache is listening on port 81. In ports.conf, you’ll need to change the NameVirtualHost and configure it to listen only internally with these lines.

NameVirtualHost *:81
Listen 127.0.0.1:81

Make sure you change any named virtual host that is specified for port 80 to port 81.

Restarting Apache and Nginx should give a speed increase, but there’s still one more thing to make sure the site stays fast. First of all, make sure the mpm module you’re running is prefork. Then change the prefork configuration in apache2.conf. Look for the line that specifies the mpm_prefork_module and change it to something like the following

StartServers 1
MinSpareServers 1
MaxSpareServers 5
MaxClients 50
MaxRequestsPerChild 500

Apache processes are big, and if you let them run forever they’ll become more and more bloated. What we’re doing here is limiting the amount of Apache processes that can run and making sure they don’t last for too long. With MaxRequestsPerChild set at 0, the Apache processes can last forever. Setting it closer to something like 500 is good for an application like WordPress that may or may not be super awesome at managing memory.

Test your configuration

Sometimes it’s hard to tell if changes to your configuration had any effect, or more importantly, will last. Running Apache Bench can give you some insight into these questions.

After I make a change I like to restart Apache and Nginx and load a few pages to see what the experience is like. Then I’ll run Apache Bench. I don’t always run it. Something that’s important to learn about the web and user-experience in general is that if it feels right, it’s probably right. The more you deal with interfaces and user interactions, the more you’ll learn what’s good and what’s not. If it feels fast enough for you, it’s probably fast enough for most people. That being said, Apache Bench can expose problems that you might not have discovered otherwise so it’s good to run sometimes.

I usually run it with the same settings, but it doesn’t hurt to experiment.

ab -n 100 -c 10 http://site.to.test/

With the configuration I’ve gone over in this article, I get ~54 requests/second on a clean WordPress install with the default Twenty Eleven theme. With my custom theme, which is pretty heavy and occasionally makes requests for my twitter feed, etc. and actual posts to load I can get ~18 requests/second.

My configuration isn’t perfect, so if you see something that looks wrong or have an idea on something I should do different, let me know, I’d love to talk.

Resources