Blog

  • Have you fallen prey to misconfiguring Nginx?

    Ever googled for Nginx configuration? For example, how to redirect http://www.example.com to http://example.com? I have, and guess what, most of the top results are wrong or inefficient. All of these are documented in a Pitfalls page on the Nginx wiki. I’m just going to point out the parts of my config I’ve optimized recently with great help from the Nginx wiki.

    Redirect from www to non-www

    Nginx wiki recommends using return, but the version in Ubuntu 10.04 doesn’t seem to support it, so I use this:

    rewrite ^ //nigelb.me$request_uri? permanent;

    Static files

    Set the Expires and Cache-Control headers with the expires header. Another thing I do is turn off access log for static files.

    location ~ ^/(img|js|css)/ {         expires 30d;         access_log off; }

    Running PHP with Nginx

    Most PHP applications only have an index.php file that needs to be executed, everything else is usually an include.

    location ~ index.php$ {         include fastcgi_params;         fastcgi_pass    unix:/tmp/php.socket; }

    Remember to place your root directive outside any location block. Then, you can add another route for static files, just so that Nginx can serve them instead of that request going to PHP.

    location ^~ /pub/ { }

    By no means are these meant to be authoritative, and newer versions of Nginx lets you use try_files instead of some of what I’ve done.

    TL;DR: Use the Nginx Wiki. RTFM.

    Update: Lyz pointed out that the default config file that come with the CentOS packages on the Nginx website put root inside the location block instead of outside. She’s just helped me verify that and I verified the same problem with the Ubuntu packages from the Nginx website.

  • Screwups are important

    At my day job, one of the tasks that Kiran and I have to do frequently is to watch the job posting on the HasGeek Job Board and reject the ones that don’t conform to our Terms of Service. Last night, Kiran pinged me on IRC with a link to a job that he wanted me to knock off. Usually, I use phpmyadmin to do this, but I thought I’d turn it into a bash script and started writing a mysql update query.

    Head in Hands by Alex E Proimos on Flickr

    In retrospect, that’s probably my first mistake right there. Production server is really not the right place to have done this and I don’t even know why I thought it was a good idea. I wrote the query and executed it. Suddenly, I realized that I screwed up. I had that sinking feeling where you know exactly what went wrong and that it’s entirely your fault. I forgot the WHERE clause in the query and managed to reject every job in the job board. Thankfully, there was a backup handy, from about 10 minutes earlier too. Because of the power outages in North India and the fact that our servers are hosted by E2E Networks in Delhi, I had set up hourly backups earlier in the day. Quickly, I brought down apache and started restoring from the backup. In about 10 minutes from executing the wrong query, we were back and running.

    We had two things to take away from this mistake – modifying the database directly should stop, and hourly backups are a good. We don’t have a lot of data yet, and hourly backups don’t take a lot of time. I spent all day today writing code so that we don’t touch the database manually ever for this. There’s been a plan to write this code for months, but true motivation came in the form of this embarrassing mistake. Most of us hate admitting our mistakes, but when working on servers, it is essential we move to a culture of blameless post-mortems to fix broken systems and ensure the same mistakes aren’t repeated or at least occur less frequently.

  • Getting myself to use j,j,k, and l in vim

    I’ve been using vim for a while now, I guess about 2 years? Heck, I’m even writing this post in vim (yay, jekyll!). After all this, I was using arrow keys for moving around in vim. I thought, they worked for me, until I recently read a blog post about vim One of the suggestions in there was to map the arrow keys to in normal mode and insert mode. I’ve tried it out for a week now, and I wonder, how did I ever use the arrow keys; h, j, k, and l make so much more sense)

    If you’ve always wanted to get rid of your arrow key habit, add this to your .vimrc!

    nnoremap <up> <nop> nnoremap <down> <nop> nnoremap <left> <nop> nnoremap <right> <nop> inoremap <up> <nop> inoremap <down> <nop> inoremap <left> <nop> inoremap <right> <nop> 

    The one place where I used arrows was for vim completion with ^N and ^P. Quickly, I learned that ^N and ^P can replace the arrow keys there too! It’s still not yet muscle memory, but pretty close.

  • Geektionary, Julython, and BrowserID

    It’s been quite a while since I blogged, more than 6 months or so. Between a family emergency in December, then switching to a Macbook since Jan, and then jekyll not working properly on it (entirely due to my lack of ruby knowledge/experience), I never found the time. Hopefuly, I’ll have more time in the coming weeks (yeah, right :P). On Sunday, I noticed Julython pop up in my twitter feed. It’s an event about encouraging developers of all skill levels to try and work on their pet project (s) just a little each day, in this instance specific to python-related projects. This reminded of a project I started a while back to get a hang of MongoDB called Geektionary. I spend some time plotting and it seems like a perfect fit to do a Julython project. I get to learn lots of new things and start a project from scratch to finish on my own.

    At work, we use Flask all the time, but we have our own boilerplate for our Flask apps. For Geektionary, I’m using the large app how-to on the Flask wiki. I made some modification to that example and already got something basic up and running. The change I’ve made is to change how configuration is handled, I’ve always liked to have a base settings file, and then a local file overriding it. Thanks to Julython, I think I’ll be working on Geektionary a little bit each day to make a final product that allows login with BrowserID and all that jazz 😉

    Speaking of BrowserID, another thing I want to do over this July, if I have time, is to port mkelly’s django-browserid to Flask. It is non-trivial because I need to support multiple DB backends somehow. I have a basic idea of what I want to do in my head, I’m just hoping to find some time to punch it out into code.

  • Switched to Clang

    A recent conversation in #devtools

    <nigelb> My current build segfaults when I touch the webconsole. <robcee> that's no good <nigelb> That's counter productive when I'm patching the webconsole. <robcee> are you on linux? <nigelb> Ya. <robcee> are you building with clang? <nigelb> No I'm not. <nigelb> gcc forever <3 . a little while later . <nigelb> Wait, that's a gcc bug? <msucan> yes <nigelb> Sadness. <nigelb> gcc </3 <nigelb> its time to move on. <robcee> it was a good run 

    So, yeah, I’ve switched to clang on Ubuntu. A quick rundown of what I did for any Ubuntu or other Linux users. The instructions are pretty much the same as what ehsan posted for Mac, except I didn’t install clang system-wide.

    So, here’s what I did.

    mkdir clang cd clang svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm cd llvm/tools svn co http://llvm.org/svn/llvm-project/cfe/trunk clang cd ../../ mkdir build cd build ../llvm/configure --enable-optimized --disable-assertions make 

    This got the clang binary in Release/bin. I use ZSH, so I added that folder to my $PATH variable like so

    export PATH=$PATH:$HOME/clang/build/Release/bin 

    The last bit is to add the following to your .mozconf

    export CC=clang export CXX=clang++ 

    Note – If you’re working on Ubuntu 10.04 with gcc version 4:4.4.3–1ubuntu1, it might be essential to use clang and not gcc. As of now the segfaults are attributed to gcc. For more details, see bug 694594