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 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 {
      # additional servers here

server {
  listen 80;
  rewrite ^/(.*)$1 redirect;

server {
      listen          443;

      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.


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.


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:

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:

  • 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")

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

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

There are lots of other solutions, i.e. and

  • 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 ),