11

I'm trying to get a new jenkins pipeline together to test new pull requests to our code. I'm using docker with the ubuntu:14.04 image to simulate our production environment.

Here is a minimum working example:

#jenkinsfile
stage('Checkout and provision'){
docker.image('ubuntu:14.04').withRun('-u root'){
    checkout scm
    sh 'chmod -R 770 ./'
    sh './init-script.sh'
    }
}

and

 #init-script.sh
 sudo add-apt-repository ppa:ondrej/php
 sudo apt-get update -y
 sudo apt-get dist-upgrade -y
 sudo apt-get install \
    apache2 \
    php \
    php-mysql \
    php-xml \
    libapache2-mod-auth-mysql \
    libapache2-mod-php \
    php5-curl \
    zip \
    htop \
    supervisor \
    mailutils \
    git \
    build-essential -y
 sudo apt-get autoremove -y

And the /etc/sudoers file for the container is as follow:

#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults:jenkins !requiretty

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

jenkins ALL=(ALL:ALL) NOPASSWD:ALL

The problem I'm having is that docker is not running as root as I'm used to and instead retaining the user id of the jenkins user from the host machine. This makes it difficult to sudo.

I've tried adding the jenkins user to the containers /etc/passwd file and running chmod against that file but don't even have the permissions to do either of these from the jenkinsfile.

With this configuration I should be the root user. However, I either see Error: must run as root if I don't use sudo or sudo: no tty present and no askpass program specified if I do.

Is there a correct way to deal with this situation? Ideally from the jenkinsfile; I'd like to avoid creating an additional Dockerfile if possible as this will be a further differentiator between testing and production.

  • Mind sharing your jenkinsfile and unit.sh ? Sounds mainly à guess at this point ... – Tensibai Apr 3 '17 at 20:22
  • This is sort of a stringy question trying to make people solve your homework. There are really jenkins forums for that kind of thing. Your question should really be asked in a form that can be found in a google search when having similar problem and be useful to someone other than yourself to be a good question for this site. – Jiri Klouda Apr 4 '17 at 5:49
  • I've been googling this for days and I've trawled the Jenkins docs. I'm yet to find a solution. If there is terminology that I'm missing to find the answers I need then please let me know. I've updated the question to make it clearer what I'm asking but I don't agree that this is 'stringy' or 'homework'. – tobassist Apr 4 '17 at 8:41
  • I've updated the question with a minimal example – tobassist Apr 4 '17 at 9:32
  • 1
    Maybe this can be of help: wiki.jenkins-ci.org/display/JENKINS/Docker+Plugin (I think -u root when you're not root doesn't work, it change the username but not the userid). You'll have to prepare your image with a jenkins user allowed to sudo passwordless. – Tensibai Apr 4 '17 at 9:49
12

So after a debug session in chat what is needed is to allow the user running jenkins to be able to sudo docker passwordless on the docker host.

A typical sudoers file on ubuntu could be in /etc/sudoers.d/jenkins

jenkins_user ALL=(ALL) NOPASSWD:ALL

Be warned this allow jenkins_user to run as root without password any command, a better file should be:

jenkins_user ALL=(ALL) NOPASSWD:/full/path/to/docker
jenkins_user ALL=(ALL) NOPASSWD:<other needed command to be run as root>

This will allow to start the container as root and as such it gives all rights within the container itself by running as uid 0.

Useful resources used aside:

2

It's actually a bad idea to run Docker as root. What you should do instead is add the Jenkins user to the Docker group. sudo usermod -aG docker jenkins. That will avoid opening needless security holes and allow Jenkins to do all that it needs to do with Docker, including running as root inside the containers. I do this regularly with my builds, using this as a sample:

stage ('Build Docker Image') {
  steps {
    script {
      // Build the Docker image for compiling
      dockerImage = docker.build("myapp:v1")
    }
  }
}
stage ('Run UnitTests') {
  steps {
    script {
      dockerImage.inside("-itu root") {
        sh(script: "nosetests app-test.py --verbose")
      }
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.