Installing Umbrella App Dependencies in Jenkins Pipeline Build

I have an Elixir Umbrella application that I’m trying to build a CI/CD pipeline for using Elixir 1.9 Releases. I’m using Jenkins Pipelines with a Dockerfile agent to setup the build environment and getting the following error when I run mix deps.get in the Docker agent:

+ echo install dependencies
install dependencies
+ mix deps.get
==> trumpet
Could not find Hex, which is needed to build dependency :ecto_sql
Shall I install Hex? (if running non-interactively, use "mix local.hex --force") [Yn] ** (Mix) Could not find an SCM for dependency :ecto_sql from MyProject.MixProject

My Dockerfile looks like this:

FROM ubuntu:16.04

# install basic tooling
RUN apt-get update && apt-get install -y wget curl apt-transport-https locales
RUN rm -rf /var/lib/apt/lists/* && \
    localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
ENV LANG en_US.utf8

# install node & npm
# https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-16-04#how-to-install-using-a-ppa
RUN curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh && \
    bash nodesource_setup.sh && apt-get install -y nodejs && \
    apt-get install -y build-essential

# install yarn
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -y yarn

# install erlang solution repository
RUN wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb && \
    dpkg -i erlang-solutions_1.0_all.deb
RUN apt-get update && apt-get install -y esl-erlang

# install elixir
RUN apt-get install -y elixir

# install hex
RUN mix local.hex --force

# install rebar
RUN mix local.rebar --force

and my Jenkinsfile like this:

pipeline {
    agent {
        dockerfile {
            reuseNode true
            args '-v $HOME/.mix:/root/.m2'
        }
    }
    stages {
        stage('Build') {
            environment {
                MIX_ENV = credentials('mix-env')
            }
            steps {
                sh """
                    echo 'install dependencies'
                    mix deps.get
                    mix deps.compile                    
                """
            }
        }
    }
}

Am I missing some piece of Elixir/Erlang configuration to get this working? Or is the issue more with some esoteric feature of Jenkins that I’m not familiar with yet?

When Jenkins runs the job in the docker container, is it using the same user as the one that where running mix local.*?

1 Like

When Jenkins runs the job in the docker container it’s done as root. Take a look at this log output:

Step 14/14 : RUN echo "Docker User: $(whoami)"
 ---> Running in 963c70139e3b
Docker User: root
Removing intermediate container 963c70139e3b
 ---> fdb91e4127b0
Successfully built fdb91e4127b0
Successfully tagged f811e94e0138b353336c113072f07cdd39dd8fe5:latest
[Pipeline] dockerFingerprintFrom
[Pipeline] }
[Pipeline] // stage
[Pipeline] sh
+ docker inspect -f . f811e94e0138b353336c113072f07cdd39dd8fe5
.
[Pipeline] withDockerContainer
Jenkins does not seem to be running inside a container
$ docker run -t -d -u 112:116 -v $HOME/.mix:/root/.m2 -w /var/lib/jenkins/jobs/trumpet/branches/master/workspace -v /var/lib/jenkins/jobs/trumpet/branches/master/workspace:/var/lib/jenkins/jobs/trumpet/branches/master/workspace:rw,z -v 

You can also see closer to the bottom that it’s running the container with the jenkins user provided by the -u flag:

ubuntu@ip:~$ id jenkins
uid=112(jenkins) gid=116(jenkins) groups=116(jenkins),999(docker)

I added a log line in my Jenkinsfile as well and the user that’s running the steps in there is jenkins:

+ echo User jenkins
User jenkins
+ echo install dependencies
install dependencies
+ mix deps.get
==> trumpet
Could not find Hex, which is needed to build dependency :ecto_sql
Shall I install Hex? (if running non-interactively, use "mix local.hex --force") [Yn] ** (Mix) Could not find an SCM for dependency :ecto_sql from Trumpet.MixProject

Presumably everything should be working fine.

I was able to find a solution in this SO post: https://stackoverflow.com/a/46958152, thanks to you pointing me in the right direction about the users not being the same. After following the solution, which is basically modifying my root agent to look like this:

    agent {
        docker {
            image 'ubuntu'
            args '-u root:sudo -v $HOME/workspace/myproject:/myproject'
        }
    }

the pipeline successfully completed. I appreciate the help!

2 Likes