↓ Archives ↓

Archive → Author

Affordable* Self-Updating WordPress Installs in 5 Minutes

* Cost is as-much-as-you-want with a mininum of €1. Please read my last paragraph about pricing.

I just counted: As it turns out, I am the proud maintainer of 19 different WordPress installations. How did I get here? I have no idea. It probably has to do with some bad life choices. “Let’s just spin up a WordPress for this!” sounded totally doable at the time. But then what?

“Maintaining WordPress installations is educational, fun, and quite easy.”
— said noone ever.

WordPress is brittle. WordPress plugins and themes are often created by folks who are just learning how to code. What you want to do is update WordPress and all plugins and themes *all* *the* *time*. Otherwise, very bad things happen sooner than you may think. Trust me, been there, done that.

The wish list

After a few WordPress installs I had hosted for a friend who promised to “make all updates all the time, of course” got hacked, I started looking for a way to solve this problem once and (hopefully) for all. This is the wishlist I started out with:

  • It should be quick and easy to “spin up a new WordPress”.
  • WordPress installs (including plugins, themes) should update automatically.
  • Sites should be backed up automatically.
  • All plugins and themes should be under version control.
  • Sites should use SSL and I don’t want to be bothered with certificate renewals.
  • It should be affordable – most of the WordPress sites I run are just-for-fun projects that don’t make any money.
  • Nice to have: Easily install plugins on all WordPress installs at once

The solution involves Uberspace, Ansible, Let’s Encrypt, Composer, and Bedrock — a most awesome combination as it turns out.

Here it goes:

1. Get an Uberspace (23 seconds)

This is easy, head to uberspace.de and sign up for an Uberspace.

Uberspace is an awesome command-line powered hosting provider with great features and support which lets you pay what you want (with a minimum of 1 Euro per month).

2. Configure your DNS (49 seconds)

Make note of your IP address(es) within the Uberspace dashboard and edit your DNS records so that your domains point to your Uberspace. Since Uberspace is fully IPv6 ready, you might want to set up both A and AAAA records.

3. Create your Bedrock fork (14 seconds)

Go to my fork of the Bedrock repo on GitHub and fork it yourself.

Bedrock is a Composer-powered WordPress boilerplate. The idea is that you keep your plugins and themes in a Git repo and reference publicly available third party themes and plugins using Composer, a dependency manager for PHP. For every WordPress site, you’ll create a fork of Bedrock. Read this handy guide to learn how to add themes and plugins to your Bedrock WordPress.

4. Install Ansible (42 seconds)

On the Mac with Homebrew, a simple brew install ansible will do. For more ways to install Ansible, see the docs.

Ansible is an IT automation engine (their words, not mine) which is basically scripted multi-server SSH on steroids. In Ansible, you create “playbooks” which are scripts that run stuff on servers.

5. Clone the Uberspace Playbook (13 seconds)

Simply run git clone git@github.com:yeah/ansible-uberspace.git to get the latest and greatest version of my Uberspace Playbook.

This is where the magic happens. The Uberspace Playbook contains all the configurations necessary to set up awesome WordPress hosting on Uberspace.

6. Add your Uberspace as Ansible inventory (2 minutes)

Within your copy of the Uberspace Playbook, copy uberspaces.example to uberspaces and add your Uberspace host and username. You can add as many Uberspaces here as you want. Ansible will install them all together.

Next, copy host_vars/UBERSPACE_NAME.UBERSPACE_HOST.uberspace.de.example to a new file named without the .example suffix and replace UBERSPACE_NAME with your username and UBERSPACE_HOST with your Uberspace host.

Now, edit the file you just created and add the domains you set up previously. Choose an internal name for your WordPress install, modify bedrock_repo to point to your Bedrock fork, and specify the domains (again). If you want to use your Uberspace for other things besides WordPress, add all domains you’re using to the domains section at the beginning and only those which should point to a WordPress instance to the respective domains within wordpress_instances. You can of course have as many domains and subdomains as you want and you can run as many WordPress instances as you want.

7. Run Ansible! (39 seconds)

Within your copy of the Uberspace Playbook, run ansible-playbook --ask-pass site.yml.

That’s it. You’re done. Enjoy your fresh new auto-updating, SSL-encrypted and backed up WordPress by navigating to https://yourdomain.com/wp/wp-admin.

Be sure to check out the Uberspace Playbook’s source code to learn what actually happens in the background.

If you need to add themes or plugins, simply update, commit and push your Bedrock fork and run the playbook again.

8. Hold on a minute and think about pricing

While the kind folks at Uberspace do allow you to pay as little as €1 for an account, a generous offer like that is not sustainable. Uberspace recommends that you pay between €5 and €10 per month which is still a great deal given the flexibility and support you’re getting.

If you’re making money from the sites you’re hosting, you may consider paying more than that and therefore help keep Uberspace a place that’s affordable for everyone. If you can’t afford more than €1, that’s fine, too.

Just be sure to play fair and pay what you think is right.

Send email attachments to ownCloud

Three years have passed since my article about sending email attachments to Dropbox. A lot of stuff happened since then. For instance, since the end of safe harbor, we don’t trust U.S. based cloud providers as much as we (maybe) used to.

So, here’s an update on how to automatically save mail attachments (e.g. invoices and receipts) in a specific folder in ownCloud. The basic idea is to set up a billing@example.com email address and store all received PDF files in ownCloud.

So here, we go. We’re still using Uberspace for this because we still like it – even after three years. But again, you should be able to adapt this for any Linux based setup.

Configuring qmail and reformime

At Uberspace, you get an unlimited number of email addresses out of the box. Your primary is composed like this:


Where username is your Uberspace username and hostname is the host your account is hosted on. What happens to emails coming this way is governed by a small file named ~/.qmail. In much the same way, you can use any email address that follows this format:


Where foo can be anything you like. To specify what should happen with emails coming in via this address, you can create a file called ~/.qmail-foo.

So, for instance, if you want all email PDF attachments sent to peter-owncloud@phoenix.uberspace.de to appear in ownCloud, create a ~/.qmail-owncloud file with the following content:

| /usr/bin/reformime -X /bin/sh -c "if [ "\${FILENAME#*.}" == "pdf" ]; then curl -X PUT -u username:password \"https://owncloud.example.com/remote.php/webdav/email-inbox/$(date +%Y%m%d%H%M%S)_\$FILENAME\" --data-binary @- ;fi"

Yep. That’s one single line. It uses reformime to extract all file attachments and then uploads those that end in .pdf to the email-inbox/ folder in your ownCloud.

Of course, it will be a good idea to create a separate user in your ownCloud which only has (create only) access to your email-inbox/ folder and use its credentials for the curl above.

Other than that, you’re all set. Now redirect your billing@example.com address to peter-owncloud@phoenix.uberspace.de and use that for services that send you invoices!

Raspberry Pi Chromium Kiosk Mode for Geckoboard (+ VNC)

This is just a quick brain dump for my (seemingly working) setup involving a wall-mounted screen, a Raspberry Pi, Raspbian, Chromium, and VNC with the goal of displaying a simple web site (e.g. a Geckoboard).

It’s quite simple actually. First, let’s install the necessary packages:

sudo apt-get install x11vnc vim unclutter chromium x11-xserver-utils ttf-mscorefonts-installer

Second, set up x11vnc, so you can vnc into the machine from time to time to do stuff. This can be done by creating a file called /etc/X11/Xsession.d/72x11vnc with the following contents:

x11vnc -display :0 -forever -http -o /home/pi/x11vnc.log -loop -usepw -vencrypt only -sslonly -ssl SAVE &

In order to make all this work, also execute the following commands and follow the instructions:

sudo chmod 755 /etc/X11/Xsession.d/72x11vnc
x11vnc -sslGenCA
x11vnc -sslGenCert server
x11vnc -storepasswd

Now, you should be able to access your Raspberri Pi using a browser via https://your-ip:5900/. (A Java-based VNC viewer will open.)

Lastly, edit /etc/xdg/lxsession/LXDE/autostart and add the following:

@xset s off
@xset -dpms
@xset s noblank
@chromium -kiosk -incognito http://what-you-want-to-display/...

Also besure to to comment/remove the screensaver in that file!

That’s it. Just reboot the Pi and you should see your web site after boot.

Update: Also installing ttf-mscorefonts-installer makes Geckoboard look nicer. (Hat tip to the folks at Geckoboard!)

Send E-Mail attachments to Dropbox

At Planio and LAUNCH/CO, we receive a lot of PDF receipts for things we purchase online or services we use regularly. I want all those files to go directly into a designated folder in my Dropbox and I don’t want to look at them until the end of the month when I zip everything together and send it to our accountant.

For this purpose, I have been using a service called send to dropbox for a while until it started getting unreliable. Soon it didn’t upload any of the e-mails anymore without even supplying an error message and I ended up fiddling with my e-mail attachments by hand again. Not very funny.

So, I hacked together something that “works for me” (TM) and doesn’t rely on an external service. Well, in fact, I am still relying on Uberspace to host this, but (a) I could easily do this everywhere else and (b) it’s a huge improvement over send to dropbox which felt more like a blackbox.

This is how it’s done on Uberspace, but really the instructions are very much applicable to any Linux based setup.

Download and Setup Dropbox Uploader

Dropbox Uploader is an awesome little shell script written by Andrea Fabrizi which can be used to upload files to Dropbox from the command line. It is very handy since it has no dependencies except for curl. For my purpose, it needed a little tweaking since it would not accept files from standard input, so I forked it and am currently waiting if my pull request is being merged. I will update this article as soon as it does, since I have no interest in maintaining the fork. Andrea seems to be doing an awesome job with this.

So open a shell on your Uberspace and do the following:

mkdir -p ~/opt
cd ~/opt
git clone git://github.com/yeah/Dropbox-Uploader.git
mkdir ~/bin
ln -s ~/opt/Dropbox-Uploader/dropbox_uploader.sh ~/bin/

This installs the latest version of Dropbox Uploader in ~/opt/Dropbox-Uploader and creates a handy symlink to it in ~/bin which should be in your PATH already.

To verify if that last assumption is true (and to authenticate Dropbox Uploader), simply run


It should lead you through the process of creating your own Dropbox App and authenticating your copy of Dropbox Uploader against it. If asked for the Access Level I’d opt for App folder since this won’t give the app access to your entire Dropbox. Your credentials are stored in ~/.dropbox_uploader which is 600 by default, but if you’re a bit paranoid like me, App folder is still the safer bet.

If you’d like to test Dropbox Uploader, perform a simple upload like this:

echo "hello dropbox world?" | dropbox_uploader.sh upload - hello_world.txt

A file called hello_world.txt should magically appear in your Dropbox. Does it work? Yay! Then here comes the fun part…

Configuring qmail and reformime

Again, it should not be hard to adapt this to other MTAs, but since Uberspace uses qmail (or netqmail to be more specific) this tutorial is written for that.

At Uberspace, you get an unlimited number of e-mail addresses out of the box. Your primary is composed like this:


Where username is your Uberspace username and hostname is the host your account is hosted on. What happens to e-mails coming this way is governed by a small file named ~/.qmail. In much the same way, you can use any e-mail address that follows this format:


Where foo can be anything you like. To specify what should happen with e-mails coming in via this address, you can create a file called ~/.qmail-foo.

So, for instance, if you want all e-mail PDF attachments sent to peter-dropbox@phoenix.uberspace.de to appear in your Dropbox, create a ~/.qmail-dropbox file with the following content:

| /usr/bin/reformime -X /bin/sh -c "if [ "\${FILENAME#*.}" == "pdf" ]; then ~/bin/dropbox_uploader.sh upload - \"\$FILENAME\";fi"

Yep. That’s one single line. It uses reformime to extract all file attachments and then uploads those that end in .pdf to your Dropbox using Dropbox Uploader.

Try it out. It should already work. There’s nothing else to do.

Update: We don’t trust Dropbox much anymore since the whole NSA stuff and the end of safe harbor agreement. The above also works great with ownCloud though, too.

VPN (IPsec) tunnel between a pfSense 2.0 router and a FRITZ!Box

We have a pfSense 2.0 router at our coworking space which is hooked up to a pretty fast VDSL line so I thought it would be a fun idea to connect my home network (where I’m using a FRITZ!Box 7390) to the work LAN using a secure and permenent VPN tunnel.

Doing a quick Google search yields results for the 1.2 version of pfSense which is outdated and does not use DynDNS hostnames for both ends, so I did a quick writeup of my own.


First things first, create permanent hostnames for your pfSense and your FRITZ!Box. If your DSL provider has assigned permanent IP addresses, that’s fine. If they didn’t you’ll probably need something like DynDNS. Last time I checked, you could still get free accounts, otherwise it’s just a few bucks a year – probably a good investment. You’ll need to configure both the pfSense and the FRITZ!Box to update your DynDNS hosts whenever their IP address changes, but that’s pretty straight forward so I won’t cover it here. Fun fact: you can add CNAME records to your company domain pointing to your DynDNS host, so it looks even more professional. We use vpn.launchco.com for instance – how cool is that?

You’ll also need two different primary subnets for your networks, i.e. if your home network lives in, which is the standard network a FRITZ!Box uses, your work network has to use something else, like, which is by the way the standard that pfSense uses – so you should be safe if you’re like me a big fan of sticking with sensible vendor defaults.

Now, with the permanent hostnames and subnets in place, let’s get down to business.

Setting up pfSense

We’re using IPsec, so let’s head to VPN -> IPsec first and click the [+] icon on the bottom right to add a new phase 1 entry.

Fill the form in accordance to what you see on the following screenshot:

Screenshot of pfSense configuration phase 1 entry

Obviously, replace your-fritz.dyndns.org with the permanent hostname assigned to your FRITZ!Box as well as your-pfsense.dyndns.org with the one on your pfSense box. The Pre-Shared Key should be a long random string. Don’t worry, you won’t have to remember it. You’ll just save that in the FRITZ!Box later and then you can forget about it.

Next up, we need a phase 2 entry. For that, click the [+] icon next to a label that says Show 0 Phase-2 entries and fill the form like below:

Screenshot of pfSense configuration phase 2 entry

Here, you just need to make sure that you replace with the actual subnet your FRITZ!Box uses. Again, if you’ve sticked with the default when setting up the box, this setting should be right for you.

That should be it for the pfSense. After saving it’ll probably ask you to apply or reload the configuration. This is safe to do now.

Setting up the FRITZ!Box

Now, let’s finish this by configuring a VPN entry in your FRITZ!Box. From my perspective, this part is much easier, because I’m just pasting code instead of fiddling with screenshots – yay!

Fire up your favorite text editor and paste the following code:

Make the necessary modifications according to the comments in the file. Then, open the FRITZ!Box configuration interface in your browser and head to Internet -> Freigaben -> VPN, use the browse button to select the file you just created and click on VPN-Einstellungen importieren.

That’s it – you’re done. In my first trials I had to go back to the pfSense interface and navigate to Status -> IPsec to click on a small [>] (“play”) button to get things rolling. Maybe you need this, maybe it just works without it.

Getting the connection up after a restart of either of the two routers sometimes fails which is most probably due to the fact that DynDNS updates have not yet propagated when the VPN tries to connect. In this case, just be patient; both boxes will keep retrying to open VPN connections and you can always stop/start on both ends yourself. Once a connection is made, the tunnels are usually stable and rock-solid. Enjoy!

Remove diacritics (Umlauts, Accents, Special characters) in JavaScript

So I recently found myself generating permalinks in JavaScript again which can be fun and painful. It seems to be less painful if you just ignore anything that’s not [a-zA-Z0-9] and replace it with a hyphen -.

However, this starts looking ugly rather quickly if you’re from Germany or France for instance, where use of umlauts and accents is very common. Something really nice like
J'ai montré les éléphants à ma sœur
becomes something really ugly like

So as Holger pointed out, I needed a diacritics table which I found here. After some modifications for the German language (e.g. ä -> ae, ß -> ss), I came up with this.

It’s still heavily based on what lehel built, so thank him, not me. I just wanted to put my improved version here, so I don’t forget it.

Update: I have created a Gist for this over at Github so we can continue to update it there…

How to build an 8 TB RAID5 encrypted time capsule for 500 Euros

So I wanted to buy a NAS that can act as a time capsule for Apple computers and run a proper Linux at the same time. I also wanted to be able to run the occasional Windows or Linux VM and I wanted to have a lot of storage. As I knew the thing was going to be in our coworking space, it also needed to have disk encryption.

Here’s how I built this for just under €500.00 using standard components and free open source software.

Selecting the hardware components

I found the HP ProLiant MicroServer (see Review and more Picures) to deliver great value for the price. At the time of writing, you can buy it for €209.90 if you’re in Germany like me.

The N36L (which I bought) comes with a single 250GB hard drive which obviously did not meet my “a lot of storage” requirement. So I bought 4 identical Seagate Barracuda Green 2000GB SATA drives which would add another €229.92 to the bill if you bought them today. I am not an expert in hard drives, but the Seagate Barracuda brand was familiar and “Green” sounds good as well.

If you don’t want your new server to host virtual machines at some point, you can probably get out your credit card and check out right now. If you’re like me though, you’d add another 2 bars of 4GB Kingston ValueRAM PC3-10667U CL9 (DDR3-1333) to your cart. The two of them together are just €44.24, so it’s no big deal anyways.

All components together will set you off €484.06. The rest is based on open source software (Debian mostly) which is free as in beer. More about that after the break.

Continue reading →

Are you stuck in Debian/MySQL/Charset/Collation hell?

So while Debian still hasn’t changed the MySQL default caracter set and collation to utf8, we all know that the first thing to do on a vanilla Debian MySQL installation is to add the following utf8.cnf file to /etc/mysql/conf.d/:


However, if for some reason you didn’t do that and have used software which hasn’t been consistently explicit about character sets and collations, you end up with a nice mess of character sets and collations.

There is a great post on serverfault which helps you out. It comes down to one command which will take some time based on the size of your database:

mysql -B -N --user=user --password=secret -e "SELECT DISTINCT \
TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;' ) FROM \
information_schema.COLUMNS WHERE TABLE_SCHEMA != 'information_schema';" \
| mysql --user=user --password=secret


And of course you need to alter the defaults for existing databases as well:

mysql -B -N --user=user --password=secret -e "SELECT DISTINCT \
utf8_unicode_ci;' ) FROM information_schema.SCHEMATA where SCHEMA_NAME \
!= 'information_schema';" | mysql --user=user --password=secret

First steps with Chef

Today, Jens and I got to play with Chef which supposedly is the hot sh$&!t when it comes to infrastructure automation and such. Installing your own Chef server seems hard at first but will work in the end.

If you’re using Debian, the APT sources will save you some headaches. Just add

deb http://apt.opscode.com/ squeeze main

to your /etc/apt/sources.list and do something like

wget -qO - http://apt.opscode.com/packages@opscode.com.gpg.key | sudo apt-key add -
sudo apt-get update

to be sure to be getting what you asked for. Then, a little sudo apt-get install chef will do the trick to set up a client and sudo apt-get install chef-server will supercharge your node with a fully blown chef server, including but not limited to CouchDB, Solr, RabbitMQ and other fancy stuff. (You’ll want to do this on two different nodes, so use Virtual Box or something.)

After you’ve set up two nodes like that, try following the rest of the instructions in this tutorial and do the first cookbook example, then you’ll have come as far as we have today.

I will update this post as we dig deeper – hopefully later this week.

SEO-friendly Affiliate Cookies powered by mod_rewrite

So you want to run an affiliate or partner program, like for example the Planio Partner Program. Good idea. Happy customers who recommend your service to their friends are the best marketing you can get. Why not reward your customers and make them even happier?

From a technical point of view, an affiliate program is nothing fancy at first glance:

  1. give your customer a link with a unique token
  2. once a visitor signs up, check if a token is present and look up the respective customer
  3. reward them!

However! There’s some technical pitfalls.

Keep track of the token

This is a rather easy one: of course, you have to remember the token throughout entire visits. You can’t expect a visitor to turn into a paying customer right on the first page. They will check out your site, visit a couple of pages, and maybe even come back another day to buy your product. You still want to reward your affiliate, so cookies will be your single option.

Don’t mess with Google

We’ve learned this the hard way with Magpie and it took us quite some time to recover our page rank, so be sure to read this! Google does not like duplicate content. If you’re copying what others write on the Web or if you have a lot of pages with similar or even identical content, Google’s algorithms will classify your site as spam. What does this have to do with your affiliate program? Well, all those referral links are different because of the token, yet they will most certainly render the same content.

So what can you do? Redirect. Don’t let your app render a page if the request URI contains an affiliate token. Redirect to the actual page using status code 301 (moved permanently). This way, Google will know that the link is still valid (and thus you will get most of the link juice from referring sites), but that its location has changed.

How to implement?

For a long time, we did this within in our application. Rails makes it really easy using before_filter, so it’s no big deal. However, your setup may be more complex. Maybe you have multiple apps on subdomains or sub-URIs and maybe they run on different frameworks. Just think of your corporate blog, most of the time it’s a WordPress. But you’d still want to reward your affiliates if they send you traffic via a link to a great blog post you’ve written, right?

For Planio, we moved the redirection and cookie part to the Web server. Below is a short and sweet Apache config snippet which works really well for us:

# affiliate cookie
RewriteCond %{QUERY_STRING} (.*)ref=([a-zA-Z0-9]{6})(&(.*))?
RewriteRule ^(.*)$ $1?%1%4 [CO=affiliate:%2:.plan.io:43200,R=301,L]

It does everything for us, so our apps don’t have to worry:

  • detect a token in a request URI (we use a ref= query param with a 6 character token)
  • set a cookie named affiliate using the token value which is valid for all our subdomains and for 30 days
  • redirect to the same page using 301, removing the ref parameter and keeping all other query parameters intact (this is great for other tracking stuff, like the params you can generate for Google Analytics)

In the end, we just need a one-liner in our signup code that reads the cookie, finds the affiliate and associates the affiliate with the newly created account.

Update: Thomas points out that you could tell Google to ignore certain query params and avoid 301 redirects using canonicals. He also claims that Google would be my friend. Not so sure about the last one, though 😉

I hope this was useful to you. Do you run affiliate programs for your products? What are your experiences? How did you implement them? I look forward to your thoughts in the comments!