Running Trac using nginx and supervisord

The mission is to run trac using nginx and keeping tracd alive using supervisord.

First the nginx configuration. The http://trac.edgewall.org/wiki/TracNginxRecipe site was a really good starting point.

Nginx is working as a proxy to port 3050 on localhost. If the payload on the tracd is too much it is easy to add addional servers with for example port 3051, 3052, .... Because we want to use only ssl all http traffic is redirected to https.

upstream trac_example_org {
      server  127.0.0.1:3050;
      # additional servers here
}

server {
  listen 80;
  server_name example.org;
  rewrite ^/(.*) https://example.org/$1 redirect;
}

server {
      listen          443;
      server_name     example.org;

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

      ssl                  on;
      ssl_certificate      /etc/nginx/ssl/exampleorg_cert.pem;
      ssl_certificate_key  /etc/nginx/ssl/exampleorg_privatekey.pem;
      keepalive_timeout    70;
      add_header           Front-End-Https    on;


      location / {
              proxy_pass      http://trac_example_org;
              proxy_set_header Host $host;
      }
}

Now we have to run tracd on port 3050 only visible for localhost. For this I use a shell script with all data needed. This includes the trac folder and an htpasswd file for authentication. The hostname=localhost setting keeps tracd only listening on localhost.

#!/bin/bash

exec /usr/local/bin/tracd --hostname=localhost -p 3050 --pidfile=/var/run/tracd.3050 --protocol=http \
  /srv/www/trac/trac -s --basic-auth="trac,/srv/www/trac.htpasswd,Example"

Now keep this script alive using supervisord. I run trac with the user trac.

[program:trac]
command=/var/www/trac-run.sh
user=trac
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/trac.log
redirect_stderr=true

For questions or improvement please leave a note in the comments.

Geolocation and IPv6

A few weeks ago I added an IPv6 tunnel to my router at home. Now I had my first problem with a site using IPv6: The Google play store.

With IPv6 I was located in the US and I could only add a delivery address in the US. I found no option to change my location to another country.

Google is using IPv6 for a lot of services. Someone has to start using IPv6 and we all expect from Google to be first on new technologies. The problem is not the usage of IPv6 itself. The Google play store uses geolocation to locate the customer and there is no (obvious) option to change the location.

MaxMind is the only service I found for locating an IPv6 address and they locate me in the US (of cource because of my tunnelbroker HE).

The solution for me was to use a computer at work to buy me a Nexus device. My employer is testing IPv6 but for now we only have IPv4. And we will get a IPv6 address clearly located in Germany.

A lot of services out there use geolocation to locate their visitors. Especially services restricted to specific countries. The obvious candidates Hulu and Netflix don't use IPv6 yet. I am curious to see their solution on this problem.

So please, if your service is only using geolocation for convenience please add an option to choose the country.

Further reading: http://stackoverflow.com/questions/1162675/geolocation-with-ipv6

AwesomeWM config snippets

My favourite windowmanager is awesomewm. I use it on all my workplaces (notebook, desktop, at work).

Some changes from my config

  • bind ctrl-alt-l to lock screen
awful.key({ "Mod1", "Control" }, "l",
  function () awful.util.spawn("xscreensaver-command -lock") end)
  • (simple) battery widget using Vicious .
baticon = widget({ type = "imagebox" })
baticon.image = image(beautiful.widget_bat)

batwidget = widget({ type = "textbox" })
vicious.register(batwidget, vicious.widgets.bat,
function (widget, args)
      return "<b>" .. args[1] .. "</b>"
end, 10, "BAT1")

Other battery widgets with Vicious: http://git.sysphere.org/vicious/tree/contrib

  • Volume widget using Vicious
volicon = widget({ type = "imagebox" })
volicon.image = image(beautiful.widget_vol)
volwidget = widget({type = "textbox", name = "volwidget"})

function volume(command,widget)
      if command == "update" then
              local fd = io.popen("amixer sget Master")
              local status = fd:read("*all")
              fd:close()

              local volume = tonumber(string.match(status, "(%d?%d?%d)%%"))

              if (string.find(status, "off", 1, true)) then
                      ret = "<b>Muted</b>"
              else
                      ret = "♫ <b>" .. volume .. "</b>"
              end
              widget.text = ret
      elseif command == "raise" then
              awful.util.spawn("amixer set Master 3%+ &")
              volume("update",volwidget)
      elseif command == "lower" then
              awful.util.spawn("amixer set Master 3%- &")
              volume("update",volwidget)
      elseif command == "toggle" then
              awful.util.spawn("amixer set Master toggle &")
              volume("update",volwidget)
      end
end
volume("update",volwidget)
-- Autorefresh every minute
awful.hooks.timer.register(60, function () volume("update", volwidget) end)

There are lots of other solutions, i.e. http://awesome.naquadah.org/wiki/Farhavens_volume_widget and http://jasonmaur.com/awesome-wm-widgets-configuration/

  • register audio keys on notebook keyboard (using the volume function above)
awful.key({}, "XF86AudioMute", function () volume("toggle", volwidget) end ),
awful.key({}, "XF86AudioRaiseVolume", function () volume("raise",volwidget) end),
awful.key({}, "XF86AudioLowerVolume", function () volume("lower",volwidget) end ),