Add locales to Alpine Linux Docker image

After moving from Debian- to Alpine-based Docker images we bumped into a problem: no localization support in Alpine. It's easier to not rely on it, but we've got some projects that do. I'll explain how to install locales on an Alpine Docker image.

Normally you can use locale-gen to add your required locale. But not for Alpine. Alpine aims for the smallest possible image size and omitting the locales is a quick win. But with musl-locale you can add basic support for locales. It's a locale program for musl libc. That's the C standard library Alpine uses.

First create a Dockerfile:

# Dockerfile
FROM php:7.2-cli-alpine3.11

Let's build and run a container. locale -a should list all available locales.

$ docker build . -t alpine-locale:latest
$ docker run --rm -it alpine-locale:latest locale -a
sh: locale: not found

So no locale command available in Alpine. Let's start fixing it.

musl-locale has some dependencies:

ENV MUSL_LOCALE_DEPS cmake make musl-dev gcc gettext-dev libintl

RUN apk add --no-cache \
    $MUSL_LOCALE_DEPS

Now we can download, compile and install musl-locale:

RUN apk add --no-cache \
    $MUSL_LOCALE_DEPS \
    && wget https://gitlab.com/rilian-la-te/musl-locales/-/archive/master/musl-locales-master.zip \
    && unzip musl-locales-master.zip \
      && cd musl-locales-master \
      && cmake -DLOCALE_PROFILE=OFF -D CMAKE_INSTALL_PREFIX:PATH=/usr . && make && make install \
      && cd .. && rm -r musl-locales-master

Let's check our progress:

$ docker build . -t alpine-locale:latest
$ docker run --rm -it alpine-locale:latest locale -a
C
C.UTF-8

locale -a works but only returns the default language. To make the other locales available MUSL_LOCPATH must be set.

All steps combined:

# Dockerfile
FROM php:7.2-cli-alpine3.11

ENV MUSL_LOCALE_DEPS cmake make musl-dev gcc gettext-dev libintl
ENV MUSL_LOCPATH /usr/share/i18n/locales/musl

RUN apk add --no-cache \
    $MUSL_LOCALE_DEPS \
    && wget https://gitlab.com/rilian-la-te/musl-locales/-/archive/master/musl-locales-master.zip \
    && unzip musl-locales-master.zip \
      && cd musl-locales-master \
      && cmake -DLOCALE_PROFILE=OFF -D CMAKE_INSTALL_PREFIX:PATH=/usr . && make && make install \
      && cd .. && rm -r musl-locales-master

The complete list of available locales:

$ docker build . -t alpine-locale:latest
$ docker run --rm -it alpine-locale:latest locale -a
C
C.UTF-8
de_DE.UTF-8
es_ES.UTF-8
de_CH.UTF-8
ch_DE.UTF-8
ru_RU.UTF-8
nl_NL.UTF-8
sv_SE.UTF-8
en_US.UTF-8
fr_FR.UTF-8
en_GB.UTF-8

It's a limited set of locales and you can't generate specific ones, but it's at least something. And if you need another language you can create a pull request.

Originally published on norday.tech.