Nginx is my project management software.
Apr. 13th, 2009 12:46 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
As a web developer, I tend to have a lot of projects just hanging around on my hard drive, waiting for me to pay attention to them. And one of the things that becomes onerous over time, especially if you’re like me and a bit undisciplined about the whole folders, projects, and so on thing of keeping stuff in the right places, is keeping track of where all of them are.
Most of my projects are individual web emplacements: wordpress designs, or extensions of the narrator software package I wrote and have been using to deploy my stories since 1994 or so. (It’s been through three languages in that time– started as Perl, was re-written as Python, briefly converted to Ruby, and now is back to Python again.) But how to keep track of them all?
I decided to experiment with Nginx, a popular and powerful reverse proxy engine. A reverse proxy accepts connections from the outside world as if it were your head webserver, and then forwards those requests to the appropriate server. Nginx (pronounced “Engine X”) is also capable of acting as a high-performance webserver in its own right, so it can serve media files out, and it uses a PCRE engine with variable substitution and a limited conditional language allowing you to make content delivery decisions based on header information long before you invoke the machinery of a heavy back-end like PHP, Django, or Rails.
I would call the experiment a modest success. My idea is eventually to have the ElfSternberg.com website front-ended with nginx and running a number of different back-ends, such as the wordpress install with Apache, other dynamic content via Django or Rails, and static content via Nginx itself.
One thing I did after installing Nginx on my dev box was to write a little CGI script that looked at the configuration file and generated a local index of projects. My Nginx configuration file is reasonably regular, and looks like this with one proxy_pass command per line for the location section:
location ~ /projects/so2006/(.*) { proxy_pass http://127.0.0.1:8001/$1; break; } # Steppin' Out to Stop Domestic Violence location ~ /projects/pw2007/(.*) { proxy_pass http://127.0.0.1:8002/$1; break; } # Pendorwright 2007 location ~ /projects/kk2006/(.*) { proxy_pass http://127.0.0.1:8004/$1; break; } # Karen Keiser 2006 location ~ /projects/sp2006/(.*) { proxy_pass http://127.0.0.1:8005/$1; break; } # Sound Podcast Production & Consulting location ~ /projects/ssb2007/(.*) { proxy_pass http://127.0.0.1:8006/$1; break; } # Shay Schual-Berke 2006 location / { proxy_pass http://127.0.0.1:81; } # Home
This makes writing a script to spew out all of my projects in a nice, clean table a trivial job of parsing the configuration. As a benefit, it also analyzes the output of netstat and determines whether or not or or more servers Nginx is expecting to proxy might be down. Decorating the table with something from the Open Source Web Design project is left as an exercise.
#!/bin/env python import re import sys from subprocess import Popen, PIPE re_match = re.compile(r'^\s+location \~ (.*?)\s*\{.*http://([^\:]+)\:(\d+)/.*#([^#]+)$') loc = open('/etc/nginx/nginx.conf') ns_match = re.compile(r'^tcp\s+\d+\s+\d+\s+(0.0.0.0|127.0.0.1):(\d+)') output = Popen(["netstat", "-an", "--protocol=inet"], stdout=PIPE).communicate()[0] ports = [] for proc in output.split('\n'): g = ns_match.match(proc) if not g: continue ports.append(int(g.group(2))) projects = [] for line in loc: g = re_match.match(line) if not g: continue (loc, site, port, proj) = g.group(1, 2, 3, 4) loc = loc.replace('(.*)', '') proj = proj.strip() projects.append((proj, loc, site, port, bool(int(port) in ports))) print "Content-Type: text/html\r\n\r\n" print "<html><body><table>" for i in projects: print ('<tr><td><a href="%s">%s</a></td><td>' '<a href="http://%s:%s">Direct link</a></td><td>%s</td></tr>') % ( i[1], i[0], i[2], i[3], (i[4] and '<span style="color: green">Up</span>' or '<span style="color: red">Down</span>')) print "</table></body></html>"This entry was automatically cross-posted from Elf's technical journal, ElfSternberg.com
no subject
Date: 2009-04-13 09:19 pm (UTC)...or am I going to have to read through that code to figure it out? :)
no subject
Date: 2009-04-14 12:01 am (UTC)I clicked on your C10K link above, and was reminded of my days of network programming, not least because at the top of the list of C++ implementations is ACE, a package I worked on with Douglas Schmidt and others way back in the early nineties when we were using it as the core of our mobile radio network control software.