Add locales to your 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. Search for “how to use locale gen” and you will find enough information for every distro, 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. Because we use a lot of PHP I use the PHP Alpine images as an example, but this will work for every Alpine based image. I’ve tested with Alpine 3.8, 3.9, 3.10 and 3.11.
# 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 which can be found in the README.
...
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 build and run a container to 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 and returns the available locales, but that’s only the default language. Which is not useful because it’s English and we already had that one. To make the other locales available MUSL_LOCPATH
must be set.
...
ENV MUSL_LOCALE_DEPS cmake make musl-dev gcc gettext-dev libintl
ENV MUSL_LOCPATH /usr/share/i18n/locales/musl
...
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
Let’s check 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.