Software Maniacs blog » Ubuntuhttps://softwaremaniacs.org/blog/category/ubuntu/en/2012-05-26T01:22:39.580000-07:00ManiacIvan Sagalaev on programming and web developmenthttp://softwaremaniacs.org/media/sm_org/style/photo.jpgSM.Org software update 2012
2012-05-26T01:22:39.580000-07:00https://softwaremaniacs.org/blog/2012/05/23/smorg-update-2012/en/Over the course of a few recent weeks I updated this site to a more modern software and revised some previously made choices. This one was loooong overdue considering that I still ran Ubuntu 9.10 before the update meaning that the system was almost 3 years old. Here are some ...
<p>Over the course of a few recent weeks I updated this site to a more modern software and revised some previously made choices. This one was loooong overdue considering that I still ran Ubuntu 9.10 before the update meaning that the system was almost 3 years old.</p>
<p>Here are some mostly useless but probably fascinating notes about it.</p>
<p><a name=more></a></p>
<h2>Core system upgrades</h2>
<p>Running a comparatively low-load site I had a luxury not to plan for complex procedures minimizing downtime. What I did was just SSHing on the host and running <code>do-release-upgrade</code> under "screen" five times in a row. <a href="http://library.linode.com/troubleshooting">Linode's upgrade docs</a> were holding my hand during the process.</p>
<p>Currently the site runs on Ubuntu 12.04 "Precise" and 3.0 Linux kernel. It's good to have modern packages!</p>
<p>Notable moments (read: long downtimes) during the upgrades:</p>
<ul>
<li>
<p>Ubuntu's integrated mail stack was good back then and these days it's just wonderful! Upon installing a single package "mail-stack-delivery" you get yourself a completely set up mail server that can send mail, accept mail from outside and that provides an IMAP interface to your mailbox. It even does necessary SSL key generation magic for me, so I can do authorization from my mail client securely.</p>
</li>
<li>
<p>What I struggled with during all the mail upgrades was Yandex' anti-spam software that relies on manual creative editing of /etc/postfix/master.cf. I still use it simply because it <em>works</em> but I should probably look for some more actively supported solutions eventually.</p>
</li>
<li>
<p>Postgres updated to 9.x. Database conversion went without a hitch. The only problem was that now Ubuntu seems to be not as conservative in memory settings as it was before so Postgres refused to run due to low memory on my machine (756M) until I reduced the amount of "buffers" (I have no idea what it is). Seems to run pretty smooth so far :-).</p>
</li>
<li>
<p>The default Python is now 2.7. The change reminded me harshly that I was stupid enough to install some non-debianized Python packages into the system directory of which Ubuntu hadn't a faintest idea. As a result new Python didn't see them. I'm still trying to figure out how best to solve this (more on that later).</p>
</li>
<li>
<p>The longest downtime was caused by upgrading Django to the newest trunk version. I neglected it for the time long enough for many DeprecationWarnings to become exceptions. Spent some quality time refreshing my code base. One thing remaining unresolved is that now Django <em>insist</em> on <code>MEDIA_URL</code> and <code>STATIC_URL</code> to have different values. I have no idea why it has to be a hard requirement. My problem is that I don't use uploaded media and hence probably shouldn't use <code>MEDIA_URL</code> at all. Except that my forum mutants are generated on the server using an <code>ImageField</code> which does use <code>MEDIA_URL</code> for storage. Still, nothing what I can't deal with in due time, just have to figure out the best way.</p>
</li>
</ul>
<h2>New web stack</h2>
<p>I moved from the old "lighttpd + FastCGI with flup" setup to the new one with "nginx + uwsgi". For some personal, completely subjective reason which I don't even remember anymore I always preferred lighttpd over nginx. However this was the case where the best maintainer won. It seems that nginx is more actively developed and uwsgi has most mind share. I also suspect all this is old news to everyone except me :-). But what actually bought me was the built-in support for uwsgi in nginx. I love integrated solutions! It means that I will have to write less of stupid glue-code in files that I will later forget.</p>
<p>The config file for nginx turned out to be much simpler than the one for lighttpd. It looks like it was specifically designed for the kind of tasks that web server admins do rather than being not-exactly-Turing-complete Perl-like code that happen to cover most use-cases with the enough amount of regexps.</p>
<p>OK, I just have to show you an example. Here's what I needed to do to handle some legacy redirects with lighttpd (heavily stripped and simplified):</p>
<pre><code>fastcgi.server = (
"/fcgi" => (
(
"socket" => "/var/run/sm_org/fcgi.socket" ,
"check-local" => "disable",
)
)
)
url.redirect = (
"^/soft/tags/(.*)" => "/soft/tagsfield/$1",
)
url.rewrite-once = (
"^(/soft/tags/)(.*)" => "$1$2",
"^/(.*)$" => "/fcgi/$1",
)
</code></pre>
<p>I don't even mind the infamous rewrite hack to connect the FastCGI backend (got used to it). But having a redirect <em>and</em> a corresponding no-op rewrite to make the former work… Seriously? (Before you ask, there <em>is</em> a reason why those redirects are not handled by Django code.)</p>
<p>Here's the nginx version that simply looks like a thing like that should look:</p>
<pre><code>server {
server_name softwaremaniacs.org;
rewrite ^/soft/tags/(.*) /soft/tagsfield/$1 permanent;
location / {
include uwsgi_params;
uwsgi_pass unix:/var/run/uwsgi/sm_org.socket;
}
}
</code></pre>
<p>The uwsgi part of the story however wasn't that bright. What inspired my to try it out was this <a href="http://tghw.com/blog/multiple-django-and-flask-sites-with-nginx-and-uwsgi-emperor">article about running multiple sites under uwsgi "Emperor mode"</a>. But since I don't run multiple sites I decided to run it first in a <em>simple</em> way.</p>
<p>With only one site to run I ditched the idea of having a separate upstart config for the master uwsgi process and a separate config for a site. Instead I put all the parameters in the upstart script itself as arguments to the uwsgi command.</p>
<p>Then I spent some time figuring out why it simply didn't run. Turns out that uwsgi no longer supports <code>--module</code> argument contrary to the statement that the config file keys are equivalent the command line arguments. The fact that <a href="https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/uwsgi/">Django uwsgi doc</a> also refers to <code>--module</code> didn't help. Neither the fact that upstart has no diagnostics whatsoever (or I couldn't find one). </p>
<p>So I reconfigured everything toward the Emperor mode.</p>
<p>Then I spent some time trying to convince nginx running under "www-data" to talk to uwsgi running under my local user. Yes, this is uncommon, but solving <em>that</em> problem was way out of scope of my intentions. Anyway, apparently there's the wonderful <code>chmod-socket</code> option in uwsgi that solved it. Also I could probably use a TCP socket (by the way, does anyone know what's the practical difference and why everyone seems to prefer using unix sockets?)</p>
<p>Then I spent some time looking helplessly at nginx complaining that it doesn't get data from the backend and uwsgi writing some logs that didn't seem to have anything to do with it. Apparently the important line in those logs was: </p>
<pre><code>-- unavailable modifier requested: 0 --
</code></pre>
<p>… which means "you don't have uwsgi-plugin-python installed". Obvious, right? :-)</p>
<p>Now, I don't exactly blame Ubuntu (or Debian?) maintainers who, after splitting uwsgi functionality into plugins, didn't think it necessary to include or recommend a single one of them to make uwsgi, you know, <em>useful</em>. Neither do I blame uwsgi maintainers for this cryptic error message. And neither do I blame myself for overlooking a warning in the <a href="http://projects.unbit.it/uwsgi/wiki/Quickstart">uwsgi Quickstart guide</a> that would solve my problem. </p>
<p>What I blame is the whole way of setting up computer software that we established over the last century. The culture of making every imaginable little thing configurable first, then forcing multitude of users to solve a few similar configuration task a million times over… But that's just frustration so please don't mind me!</p>
<p>OK, here are my uwsgi configs in case you wondered (but please use official docs whenever you can).</p>
<p>The upstart script responsible for running the uwsgi Emperor <code>/etc/init/uwsgi.conf</code>:</p>
<pre><code>start on runlevel [2345]
stop on runlevel [06]
exec /usr/bin/uwsgi \
--emperor /etc/uwsgi/apps-enabled \
--uid maniac \
--gid maniac
</code></pre>
<ul>
<li>You <em>do</em> want to run the Emperor mode even if you have only one backend simply because then you can restart it gracefully without using <code>sudo</code>. Just chmod your site config to own it yourself.</li>
<li>You'll probably want to use "www-data" for uid and gid, though I personally find it more convenient to run my code under my local user.</li>
</ul>
<p>The config describingn instance of the site backend <code>/etc/uwsgi/apps-available/sm_org.ini</code>:</p>
<pre><code>[uwsgi]
master = 1
chdir = /home/maniac/sm_org
module = wsgi
processes = 5
max-requests = 1000
plugins = python
socket = /var/run/uwsgi/sm_org.socket
chmod-socket = 777
</code></pre>
<ul>
<li>I have no idea why you need the "master" option but it seems that everyone uses it. Let's keep everyone happy!</li>
<li><code>chdir</code> into the project's directory is needed because my code does relative imports of project apps located in that directory. Yours probably does it too.</li>
<li><code>module = wsgi</code> means the <code>wsgi.py</code> in the project directory that <a href="https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/">exports Django wsgi app instance</a>. In your case it might be called <code>projectname.wsgi</code> if you follow current Django project layout.</li>
<li><code>plugins = python</code> is what makes uwsgi actually run Python code. You can skip "http" that some docs suggest here if you don't use your uwsgi backend as an HTTP server.</li>
<li><code>chmod-socket = 777</code> is what allows my "www-data" owned nginx talk to the "maniac" owned uwsgi backend. You might not need it if you run them both under the same user or use a TCP socket.</li>
</ul>
<h2 id=virtualenv>virtualenv</h2>
<p>I have one unresolved question right now. OK, there's actually more than one but this one occupies me most: to use or not to use <a href="http://www.virtualenv.org">virtualenv</a>. </p>
<p>Here are my thoughts:</p>
<ul>
<li>
<p>I'm not a hosting company working for external clients so I don't run multiple sites with different set of packages. This is not my use-case for virtualenv. I'm quite happy maintaining my whole Django codebase using the trunk version of Django.</p>
</li>
<li>
<p>I cannot rely only on system Python packages simply because some of them Ubuntu doesn't provide. <a href="http://pypi.python.org/">PyPI</a> is <em>the</em> place where all new packages live now and I want to use it conveniently.</p>
</li>
<li>
<p>Installing packages with pip into the system site-packages is broken and out of the question. This is where the idea of using virtualenv comes up. But probably I could just tell pip to use a specific installation directory? I couldn't find the option for it.</p>
</li>
<li>
<p>What I don't like about virtualenv is that it makes my life harder. I should either "activate" my single environment all the time or use explicit paths everywhere to run commands. If this is how everyone does this then the world definitely gone mad :-). I'd rather keep my current way with tweaking PYTHONPATH . But then I'll still have the problem of pip trying to install everything in site-packages :-(.</p>
</li>
</ul>
<p>What a man to do?Attitude towards competitors
2011-03-03T12:33:54.266000-08:00https://softwaremaniacs.org/blog/2011/03/03/competitors-attitude/en/Christian Giordano, designer at Canonical: We just noticed MacOSX Lion is likely to give it a try on merging the traditional scrollbars with the overlaid ones. From the few screenshots we saw, it looks like a quite different solution. What else can we say, good luck to them and may ...
<p><a href="http://design.canonical.com/2011/03/introducing-overlay-scrollbars-in-unity/">Christian Giordano, designer at Canonical</a>:</p>
<blockquote>
<p>We just noticed MacOSX Lion is likely to give it a try on merging the traditional scrollbars with the
overlaid ones. From the few screenshots we saw, it looks like a quite different solution. What else
can we say, good luck to them and may the best win!</p>
</blockquote>
<p><a href="http://www.engadget.com/2011/03/02/live-from-apples-ipad-2-event/">Steve Jobs, CEO of Apple</a>:</p>
<blockquote>
<p><img alt="" src="http://www.blogcdn.com/www.engadget.com/media/2011/03/20110302-10175350--img4510.jpg"></p>
<p>Everyone's got a tablet. Will 2011 be the year of the copycat?</p>
</blockquote>
<p>This attitude of Apple is exactly what keeps me with less arrogant guys all these years…