Skip to content
Justin SilverTECHNOLOGY, TRAVEL & EVERYTHING IN BETWEEN

Technology / Linux

Alpine Linux PHP + iconv fix

April 26, 2021

To use PHP with iconv on Alpine Linux - in a Docker container for example - you need to use the preloadable iconv library, which was previously provided with the gnu-libiconv package, but was removed after Alpine v3.13. After recently rebuilding an Alpine image and running a PHP script that required iconv, I saw the following error:

Notice: iconv(): Wrong charset, conversion from `UTF-8' to `UTF-8//IGNORE' is not allowed

To work around it I installed the gnu-libiconv package from the v3.13 repo. For my projects I went ahead and exported the preloadable binary once it was built as well so that I could just COPY it into the image instead of building it - in my case it's only for Alpine after all.

You can do this by using an Alpine image tag of alpine:3.13 to add gnu-libiconv and compile /usr/lib/preloadable_libiconv.so, then copy it to a volume to save the binary once the container exits - the output folder is called ./out in this example.


% docker run -v $(pwd)/out:/out -it alpine:3.13 \
/bin/sh -c 'apk add --no-cache gnu-libiconv && cp -f /usr/lib/preloadable_libiconv.so /out/preloadable_libiconv.so'
      
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
(1/1) Installing gnu-libiconv (1.15-r3)
Executing busybox-1.32.1-r6.trigger
OK: 8 MiB in 15 packages

% ls -la out/preloadable_libiconv.so                                                                                                                             
-rw-r--r--  1 justin  staff  1005216 Apr 23 14:32 out/preloadable_libiconv.so

Once you have the prebuilt binary you can use COPY in your Dockerfile to use it without needing to build it.



# copy preloadable_libiconv.so from prebuilt
COPY /rootfs/usr/lib/preloadable_libiconv.so /usr/lib/preloadable_libiconv.so
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php

If you prefer to install the older package that includes the preloadable binary in a different Alpine Dockerfile you can specify an older repository in a RUN command, like so:


FROM wordpress:5.7.1-php7.4-fpm-alpine
# ... some config
RUN apk add --no-cache \
    --repository http://dl-cdn.alpinelinux.org/alpine/v3.13/community/ \
    --allow-untrusted \
    gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php

Conversation 2

Sebastian MendelJuly 21, 2021
What about `COPY --from=alpine:3.13 /usr/lib/preloadable_libiconv.so /usr/lib/preloadable_libiconv.so`
Justin SilverJuly 21, 2021
I don't think that will work because gnu-libiconv isn't installed by default so the file will be missing from the base alpine:3.13 image. You could use a build stage in the Dockerfile to do something similar though. [text] FROM alpine:3.13 AS iconv-build RUN apk add --no-cache gnu-libiconv FROM alpine:latest COPY –from=iconv-build /usr/lib/preloadable_libiconv.so /usr/lib/preloadable_libiconv.so ... [/text]