Somewhere around the Java 8u92 versions, the official Docker images for Java started providing Alpine variants of the base images. I believe the benefits of that option are smaller footprint and smaller security attack surface.

Both are fantastic benefits, but there’s some gotchas if you’re used to a Debian (or similar) base image.

Doesn’t include curl or wget

For the reasons above, the Alpine variant doesn’t come with curl or wget. Avoid the temptation to use apk to install those packages and instead take this as a reminder to better leverage Docker.

The ADD Dockerfile instruction already supports source files retrieved via URL. So rather than using RUN to issue a curl/wget, just add a file from a URL natively, such as

ADD https://somehost/somefile.zip /tmp/somefile.tgz

useradd is adduser

If your Dockerfile or scripts are using the command useradd (from Debian land), then use adduser instead. BUT, check out the next couple of sections.

Default system user has no shell

Creating a system user with

adduser -S sysuser

will result in a user than can’t be used with an su -c invocation since no shell is configured by default. Instead explicitly set a shell, such as

adduser -S -s /bin/sh sysuser

Use su to drop privileges

Since sudo isn’t installed by default and we want to minimize adding more packages (to lower security exposure), then use su instead. To run a command as a system user (with an explicit shell configured as above), use something like

su -c "command" sysuser

Don’t use an extra dash in su

Originally I was putting a dash before the username when invoking su thinking that it was a definitive way to tell it where the command ending, like

su -c "command" - sysuser

It turns out giving the dash disables propagation of the environment variables, which is bad since Docker containers use environment variables to pass inputs.