Musings from an east coast software developer, writer and reader.

From the Blog

For the past year or so I have been using nginx as a proxy in front of my Apache instances on the server that runs this blog, and a few other websites that I manage. The virtual machine itself is running an older LTS version of Ubuntu, and most of the applications on here are a traditional LAMP setup with a few C/C++ testing tools scattered around. For the most part it is operating as web server with a small work load. But as I’ve been adding a few more services running in the background I have noticed a little slowdown with WordPress.

There are some obvious advantages to this set up: Nginx can serve up all of the static content very, very quickly without having to send it down to the Apache instances to process. This frees up those daemons to only serve application logic, which in this case is the WordPress PHP application, but would work for nearly anything that you have set up with it. I will give you a quick example of the configuration that I have set up for this site.

This is the main configuration file for the Nginx application. Most of the commands here I have plucked from various tutorials across the internet, specifically dealing with the gzip settings, and as you can see there are a few connection and process related settings. These can all be tweaked at your desire, but I find that they work best on my low load cloud virtual server. The information to note here is the location of the proxy server (127.0.0.1:8080) that the requests will be sent to, as well as some folders for errors, logs, etc. These are all standard with the Nginx installation from aptitude and should be modified to suite you. Note the section where we include any scripts that are in /etc/nginx/sites-enabled/* which is similar to the set up of the Apache portion of the LAMP stack.

/etc/nginx/nginx.conf

user  op;
worker_processes  2;
 
error_log  logs/error.log warn;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
 
pid        logs/nginx.pid;
 
events {
    worker_connections  1024;
}
 
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
 
    access_log  logs/access.log  main;
 
    gzip on;
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_min_length 1100;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_buffers 16 8k;
    gzip_disable "MSIE [1-6].(?!.*SV1)";
    gzip_vary on;
 
    include /etc/nginx/sites-enabled/*;
 
    server {
        listen       80 default;
        access_log  logs/host.access.log  main;
 
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
 
        location / {
                 include /etc/nginx/proxy.conf;
                 proxy_pass http://127.0.0.1:8080;
        }
    }
}

This configuration file sets up the particular domain inside of the Nginx proxy. It covers both the fully qualified domain name and the alias, and provides the root directory for serving up the static content. If there is content that you do not want to be served up (e.g. you have a public folder) make sure to point this only to your assets directory. We set up the path for logs to be written to (you’ll have to mkdir -p those directories) as well. The real gem here is the regular expression that specifies what static content will not get fielded off to the apache daemons. Obviously you can make any corrections here that you see fit. When you are done set up a symbolic link in /etc/nginx/sites-enabled/.

/etc/nginx/sites-available/thoughtlessbanter.com

server {
 server_name www.thoughtlessbanter.com thoughtlessbanter.com;
 root /path/to/thoughtlessbanter.com/;
 
 access_log /var/log/nginx/thoughtlessbanter.com/access.log;
 error_log /var/log/nginx/thoughtlessbanter.com/error.log warn;
 
 location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
              access_log off;
              expires 30d;
 }
 
 location / {
              include /etc/nginx/proxy.conf;
              proxy_pass http://127.0.0.1:8080;
 }
}

This little tidbit is necessary to send over the header information from the HTTP client to the Apache daemon. These proxy settings, with this configuration set up, will affect every single web request, so be careful with what you modify here. There are additional parameters involving the maximum size of a payload, send, connect, and read timeouts, etc. These can all be looked up with a quick Google search and modified freely.

/etc/nginx/proxy.conf

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

Last you’ll need to modify your virtual host for all of the websites to now accept the connection on the new port, 8080, which is were Nginx will proxy the requests to. Be sure to set the server alias for both the fully qualified domain, and the shortened one. I am not an Apache configuration guru here, so some of the other options may not be applicable, but they seem to do the job for me. Most of my domains are further configured appropriately in the .htaccess in the document root directory.

/etc/apache2/sites-available/thoughtlessbanter.com

<VirtualHost *:8080>
              ServerAdmin jb@thunkbrightly.com
              ServerName thoughtlessbanter.com
              ServerAlias www.thoughtlessbanter.com
              DocumentRoot /path/to/thoughtlessbanter.com
              <Directory />
               Options FollowSymLinks
               AllowOverride All
              </Directory>
              <Directory /path/to/thoughtlessbanter.com>
               Options Indexes FollowSymLinks MultiViews
               AllowOverride All
               Order allow,deny
               allow from all
              </Directory>
 
              ErrorLog /var/log/apache2/thoughtlessbanter.com-error.log
              CustomLog /var/log/apache2/access.log combined
</VirtualHost>

When you have made all of the changes feel free to restart the services and test your website. Once all the instances are bounced you should be able to point the browser to the location and still bring up your website. If you check the logs located in /var/log/nginx/ and /var/log/apache2/.log you should be able to see your static content requests hitting nginx, and being served up right from there. The apache daemons will now only serve the application logic.

Let me know what you think. I’m sure I’ve made a few mistakes.

I have been using WordPress for many years now. I firmly believe that there is no better software available, free or paid, for rolling your own blog. The guys over at Automattic are an amazing bunch of people for giving away free software that might otherwise cost thousands of dollars. But with all of that said I feel that there is a big gap that the blogging community must hurdle in order to become, well, more conjoined. When I am bored I tend to click around the Internet, read some blog posts, and occasionally comment on the ones that I feel are worthy. I have found that there is some great great commenting software out there that allows tracking of comments from site to site, but the same can’t be said for blogging.

Now, I may have missed the memo, but what blogging really needs is a centralized hub where I can easily search, comment and publicize the authors that I think are making strides in the vast online writing community that is the blogosphere. Up until this point I have had to keep a list of bookmarks for the blogs that I want to frequent, but why is that? Just as I am able to log on to Digg.com and given stories that I would like to read, I should be handled blog articles that are automatically aggregated utilizing the XML-RPC ping protocol that WordPress has seemingly kept infamous. I believe that the WordPress.com community is a step in the right direction when it comes to a blog community, but I do not want to be limited to having to open a blog on their host in order to be listed there. Part of the reason I love WordPress (the software) is that I like the freedom I am given when I am able to run my own host.

Well, those are just some thoughts of mine. I am sure that someone, somewhere, has been thinking the same thing that I have and is probably already hard at work on the next big thing when it comes to blogging communities. I just have not found anything that comes close to my vision of what the ideal would be. Someone surprise me.