Quickly Cleaning Up Docker Images from the Command Line

One of the things I find quite annoying is cleaning up Docker images on a development machine, such as my laptop. Over time, they tend to accumulate as you experiment with things, clogging up your machine. It’s really handy to have a quick and easy way to get rid of them. As I typically work from the command line, I wanted a way to do it there, and so I created a shell alias that does it in combination with fzf.

Here it is:

alias docker-rmi-interactive="docker images | sed -E 's%([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+).*%\\1:\\2 \\3%g' | tail -n +2 | sort -r | fzf -d' ' -m --with-nth=1 | cut -d' ' -f2 | xargs -t docker image rm"

The sed command takes docker images with a separated name, version, and image ID and combines them together in the form namespace/imagename:version suitable for display to fzf, with fzf then passing the image ID to docker image rm. You can multi-select images from fzf using the <Tab> key; if you want to modify any of the fzf options you can of course take a look at its man page.

Hope it helps!

Switching between 'Soft' and 'Hard' wrapping in vim

One of the things I sometimes find quite frustrating about vim is that the standard textwidth and wrap options imply assumptions about whether a text-style file (.txt, .md, READMEs, etc.) have “hard” carriage returns (where paragraphs are wrapped with actual carriage returns) or “soft” (where paragraphs are wrapped dynamically by the editor). When you create your own files, you’ll probably have your own preference for which of these you do, but when you are working with files that come from others, it’s very useful to have the ability to quickly switch between them.

To help address this problem, I’m constructing a new Vim plugin - vim-wrapping-softhard. The README should hopefully be self-explanatory in installing and using it.

FZF and zsh plugin released

If you’re anything like me, you like fzf, you like zsh, and you oh-my-zsh’s z plugin.

However, although the z plugin does a great job of allowing you to switch between frequently-used directories just by typing z *somedirectorysubstring*, it doesn’t really easily allow you to browse those directories, with partial-string search.

I’ve written a zsh plugin which brings together the z plugin and fzf to allow you to easily browse recently used directories at any point on the command line. It’s hosted on GitHub - find out more there.

Working around Docker's COPY command copying as root using GNU M4

I’ve been working with Docker a lot recently, and have been switching to non-root users within the Dockerfile using the USER instruction (not for security reasons, but in order to test software not as root). As a result, I’ve been suffering a little from this issue - essentially, files copied into a Docker image using ADD or COPY are copied with the owner as root, irrespective of the ownership outside the Docker image. According to this comment, this behaviour in Dockerfiles won’t change, at least in the near future.

Irrespective of the merits of this, I needed a solution. There is an (inelegant) way to work around this, which is to switch to root, copy the file in, change its ownership, and switch back to a regular user. I could do this directly inside the Dockerfile, but this requires a lot of extra boilerplate code bulking out the Dockerfile.

As a result, I turned to an ancient templating technology to make my Dockerfile more manageable - m4. I’ve created an m4 macro file which can be included in a Dockerfile. The full version (called docker-copy-as-user) is on github, but a small flavour is:

define(`COPYASUSER',
`USER root
COPY $1 $2
RUN chown testuser $2/$1
USER $3
')

A file that contains this macro can be included in a Dockerfile (which I now like to call Dockerfile.m4) with the incantation include(`docker-copy-as-user'). This can then be used by including the ‘meta-instruction’ COPYASUSER filename target/dir user-to-own-it. For example, Dockerfile.m4 might look like:

FROM ubuntu:15.04

RUN useradd -ms /bin/bash testuser
USER testuser
WORKDIR /home/testuser

COPYASUSER externalfile.zip /tmp testuser
RUN unzip externalfile.zip

This can then be pre-processed before you run docker build with:

m4 -I directory/where/docker-copy-as-user/is Dockerfile.m4 > Dockerfile

Note: I am very much a newbie to both Docker and m4. Please don’t read the above as being the optimal answer. In particular, your final (processed) Dockerfile still ends up pretty bulky, so this will still have performance implications due to the number of layers. I’d be glad to hear any suggested improvements.

Getting the Logitech Presenter R800 Working with QuickTime Player on the Mac

Based on my previous post about getting my Logitech R800 presenting tool working with Keynote using Karabiner, I’ve now spent some time extending my private.xml to add support for QuickTime Player also. It now supports (inside QuickTime Player):

  • Left: Rewind the video at various speeds.
  • Right: Fast-forward the video at various speeds.
  • “Start presentation”: Go into fullscreen.
  • “Blank presentation”: Pause/play presentation.

This is very useful when giving a “live” demo from a QuickTime video, as you can pause/play/rewind etc. all from the presenter tool.

subscribe via RSS