php:5.6-apache docker container with GD (and jpeg) compiled

I was trying to get the official php:5.6-apache docker container compiled with GD for a project. GD would install but the JPEG support was missing. I managed to figure out the missing libraries and config in the end.

This is what my docker file looks like now, with the important bits in bold:

FROM php:5.6-apache

RUN apt-get update \
    && apt-get install libpng12-dev libfreetype6-dev libjpeg62-turbo-dev -qy \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install gd

hexo missing the generate and server commands

Today I thought I’d try hexo on a new project. A few minutes in and I’d stumbled across a strange problem that took me 20 minutes too long to figure out.

If I ran $ hexo init my-project I could run $ hexo generate and get a compiled version of a new site just fine. The issue was I wanted to use hexo in an existing git project and so copied across the files I thought I needed manually.

Having moved and merged all the files I ran $ hexo generate but rather than getting a shiny compiled set of .html files, I got this:

$ hexo generate

Usage: hexo <command>

  help     Get help on a command.
  init     Create a new Hexo folder.
  version  Display version information.

Global Options:
  --config  Specify config file instead of using _config.yml
  --cwd     Specify the CWD

Ah, no generate command!! I Googled for the answer but came up short. I resorted to doing a diff on a clean hexo project v.s. my repository. The difference was that my package.json file had no “hexo” property.

A quick copy/paste of the hexo property and I was in business:

$ hexo generate

Usage: hexo <command>

  clean     Removed generated files and cache.
  config    Get or set configurations.
  deploy    Deploy your website.
  generate  Generate static files.
  help      Get help on a command.
  init      Create a new Hexo folder.
  list      List the information of the site
  migrate   Migrate your site from other system to Hexo.
  new       Create a new post.
  publish   Moves a draft post from _drafts to _posts folder.
  render    Render files with renderer plugins.
  server    Start the server.
  version   Display version information.

Global Options:
  --config  Specify config file instead of using _config.yml
  --cwd     Specify the CWD

TLDR: If your hexo generate/server command is missing, make sure package.json contains “{ hexo: { version: “x.x.x” } }”.

Redmine plugin: attach incoming email source to issue

At Copia we use Redmine as a project management tool and a helpdesk. Clients can email in support requests for the team to assign and work on. In general Redmine works well as a helpdesk but occasionally a client will email in something thats easier to understand as a formatted HTML email — this gets lost in translation when Redmine converts it to plain text.

To solve this I’ve written a plugin to attach the HTML parts of the email, as well as the full email source, to the issue when it is created or responded to.

Installation is really simple, just follow the generic plugin installation instructions on the Redmine wiki.

Find out more, and grab the source code on github:

Our office Slack bot for tea and coffee

Who’s turn it was to make the tea was becoming a contentious issue in the office.. and so BevBot was created. BevBot, short for Beverage Bot, lets the team opt-in to a tea or coffee – with the person making the drinks chosen at random at the end of the time limit.

Using coderstephen/slack-client as a base, and building a generic bot framework on top (that I hope to open source in the coming months), BevBot can accept requests for tea or coffee, and manage the round of orders.

The general flow looks like this:
BevBot example

We’ve even plotted the results in ChartBlocks, so we can see who’s drinking the most.

Getting rsync to delete old non-empty directories containing excluded files

For some older projects we’re still deploying code with rsync, its not perfect but it works. Temporary files are excluded using --exclude-from=exclude.txt, this is great until the parent folder of an excluded file needs to be deleted.

For example, say your file structure looks like this:
Rsync delete file structure

And you remove the data/cache directory completely:

$ rm -rf data/cache
$ rsync --exclude="*.tmp" --exclude="data/logs/*.log"

You’re going to get the error “cannot delete non-empty directory: data/cache” because data/cache/config.tmp has not been removed by rsync.

Unfortunately --delete-excluded won’t work because you don’t want to delete the log files and other .tmp files created on the destination.

Fortunately rsync has filters (which include/exclude are shorthand for anyway), with a mode called “perishable”. Perishable excludes behave exactly as required, files are excluded from sync, and aren’t deleted on the destination unless they are in a directory that no longer exists.

The syntax for excluding files becomes:
$ rsync --filter="-,p *.tmp" --filter="-,p data/logs/"

The “-” signifies the filter is to exclude matches. The “p” makes the exclude perishable.

If, like us, you were using --exclude-from for the patterns, you can with this syntax:
$ rsync --filter="merge,p- /home/ideal/scripts/push/excludes/lenta.txt"

This information is all available in the rsync docs under “FILTER RULES”, it just took me a while to figure out the right syntax. Hopefully these snippets help someone out.