Search code examples
linuxnode.jsjenkinsdockerlocale

Broken encoding in npm test output triggered by Jenkins running in docker


I've been with a big headache for months. We're working with a continuous integration pipeline and one of the steps is an automated test triggered by npm test, which will take place inside a jenkin's slave running in a docker container, Jenkins itself is in another container. During the builds the output is displaying broken like this:

[email protected] node_modules/node-schedule
��������� [email protected]

By googling it I found this is an issue caused by not setting the locale in the unix system. I tried adding Environment variables in the Dockerfile but still no luck yet. Also tried running locale-gen and I get command not found error:

 RUN locale-gen ${LANGUAGE}

When I try installing it I get no candidate package found.

RUN apt-get install locales

Here is the slave's Dockerfile.

# NODEJS SLAVE
# Pull base image.
FROM node:0.10.42

ENV LANG_WHICH en
ENV LANG_WHERE US
ENV ENCODING UTF-8
ENV LANGUAGE ${LANG_WHICH}_${LANG_WHERE}.${ENCODING}
ENV LANG ${LANGUAGE}
RUN dpkg-reconfigure --frontend noninteractive locales \
  && apt-get update -qqy \
  && apt-get -qqy install \
    language-pack-en \

RUN apt-get install -y nano openssh-server openjdk-7-jdk \
  && apt-get -y upgrade

EXPOSE 8080

<... ssh stuff...>

COPY package.json /src/package.json
RUN npm install -g npm

# Standard SSH port
EXPOSE 22

CMD ["/usr/sbin/sshd", "-D"]

And this is the Jenkins master's container Dockerfile

# JENKINS MASTER
# Set the base image to Ubuntu
FROM jenkins:latest

ENV LANG_WHICH en
ENV LANG_WHERE US
ENV ENCODING UTF-8
ENV LANGUAGE ${LANG_WHICH}_${LANG_WHERE}.${ENCODING}
ENV LANG ${LANGUAGE}
RUN localedef en_US.UTF-8 -i en_US -fUTF-8
RUN dpkg-reconfigure --frontend noninteractive locales \
  && apt-get update -qqy \
  && apt-get -qqy install \
    language-pack-en \

USER jenkins
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8

COPY plugins.txt /usr/share/jenkins/plugins.txt
COPY executors.groovy /usr/share/jenkins/ref/init.groovy.d/executors.groovy

RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt

Can anyone provide some guidance on solving this problem?

UPDATE:

I was able to use locale-gen by altering the base image to ubuntu:xenial. But that didn't worked either. It seems that jenkins connects to the slaves through a non-interactive shell and that causes it not to load the required configurations (/etc/profile and /etc/default/locale). I also tried adding:

USER jenkins
RUN echo "export=LC_ALL=en_US.UTF-8" >> /etc/.bashrc

But that didn't worked either. HERE is the full Dockerfile that I'm using right now.


Solution

  • When I had a similar issue once, I ended up using all solutions I could find together.

    Using the below worked for me, it's possible that not all of them are needed but once I had it working I didn't want to touch it anymore to try.

    RUN echo "en_US UTF-8" >> /etc/locale.gen
    RUN dpkg-reconfigure locales
    RUN locale-gen en_US.UTF-8
    RUN localedef -c -i en_US -f UTF-8 en_US.UTF-8
    ENV LANG en_US.UTF-8
    ENV LANGUAGE en_US:en
    ENV LC_ALL en_US.UTF-8
    

    The complete Dockerfile can be found at https://github.com/evolution7/nodejs-bower-grunt