5

Hi Stack Overflow community!

I have a maven - java project which needs to be build with jenkins pipelines. To do so, I've configured the job using the docker image maven:3.3.3. Everything works, except for the fact that I use ru.yandex.qatools.embed:postgresql-embedded. This works locally, but on jenkins it complains about starting Postgres:

2019-02-08 09:31:20.366  WARN 140 --- [ost-startStop-1] r.y.q.embed.postgresql.PostgresProcess: Possibly failed to run initdb: 

initdb: cannot be run as root

Please log in (using, e.g., "su") as the (unprivileged) user that will own the server process.

2019-02-08 09:31:40.999 ERROR 140 --- [ost-startStop-1] r.y.q.embed.postgresql.PostgresProcess: Failed to read PID file (File '/var/.../target/database/postmaster.pid' does not exist)

java.io.FileNotFoundException: File '/var/.../target/database/postmaster.pid' does not exist

Apparently, Postgres does not allow to be run with superuser privileges for security reasons.

I've tried to run as a user by creating my own version of the docker-image and adding the following to the DockerFile:

RUN useradd myuser
USER myuser

And this works when I start the docker image from the server's terminal. But by using jenkins pipeline, whoami still prints 'root', which suggests that Jenkins Pipeline uses run -u behind the schemes, which would overrule the DockerFile?

My pipeline job is currently as simple as this:

pipeline {
    agent {
        docker {
            image 'custom-maven:1'
        }
    }
    stages {
        stage('Checkout') {
             ...
        }
        stage('Build') {
            steps {
                sh 'whoami'
                sh 'mvn clean install'
            }
        }
    }
}

So, my question: How do I start this docker image as a different user? Or switch users before running mvn clean install?

UPDATE:

By adding -u myuser as args in jenkins pipeline, I do log in as the correct user, but then the job can't access the jenkins-log file (and hopefully that's the only problem). The user myuser is added to the group root, but this makes no differece:

agent {
    docker {
        image 'custom-maven:1'
        args '-u myuser'
    }
}

And the error:

sh: 1: cannot create /var/.../jenkins-log.txt: Permission denied
sh: 1: cannot create /var/.../jenkins-result.txt.tmp: Permission denied
mv: cannot stat ‘/var/.../jenkins-result.txt.tmp’: No such file or directory
touch: cannot touch ‘/var/.../jenkins-log.txt’: Permission denied
7
  • Why don't your try user root inside docker rather than creating different user? Commented Feb 8, 2019 at 11:07
  • It runs by default as root. But as mentioned above, Postgres does not allow to be run with superuser privileges for security reasons. The embedded postgres installs itself at the beginning of the tests, but it cannot install if running under root. I need a user with no root privileges Commented Feb 8, 2019 at 12:19
  • at the same time is there a poatgres user created automatically? Commented Feb 8, 2019 at 12:26
  • I'm not sure actually, but I suppose there is... postgresql-embedded handles the installation of the postgres service through java (at startup of the server) (github.com/yandex-qatools/postgresql-embedded), and inside my own code in java, a connection happens and everything is set up Commented Feb 8, 2019 at 13:55
  • But why are you running pipeline as root user? Shouldn't it ideally run as jenkins user and then you can run docker image as jenkins user rather than creating some other user so that both pipeline and container have same owner: jenkins? Commented Feb 8, 2019 at 15:22

3 Answers 3

2

I have solved the issue in our case. What I did was sudo before the mvn command. Keep in mind that every sh step has his own shell, so you need to do sudo in each sh step:

sh 'sudo -u <youruser> mvn <clean or whatever> -f <path/to/pomfile.xml>'

The user must be created in the Dockerfile. I've created it without password, but I don't think it matters since you are root...

You must use sudo instead of switching user or something since otherwise you need to provide a password.

This is far from a clean way... I would suggest to not mess with user-switching unless you really need to (like to run a embedded postgres)

Sign up to request clarification or add additional context in comments.

Comments

1

@Thomas Stubbe

I got almost the same error as you mentioned above. I also have an image which has postgresql on it. On the Dockerfile I have created an user named like tdv, and use id command on Container check tdv permission was 1000:1000. I can Start the Container though Jenkins pipeline but it failed to execute sh command, even I add sudo -u tdv for each command. Did you did any other configuration?

My Jenkins Pileline script like following:

pipeline{
    agent none
  stages{
    stage('did operation inside container'){
     agent {
        docker{
        image 'tdv/tdv-test:8.2'
        label 'docker_machine'
        customWorkspace "/opt/test"
        registryUrl 'https://xxxx.xxxx.com'
        registryCredentialsId '8269c5cd-321e-4fab-919e-9ddc12b557f3'
        args '-u tdv --name tdv-test -w /opt/test -v /opt/test:/opt/test:rw,z -v /opt/test@tmp:/opt/test@tmp:rw,z -p 9400:9400 -p 9401:9401 -p 9402:9402 -p 9403:9403 -p 9407:9407 -p 9303:9303 --cpus=2.000 -m=4g xxx.xxx.com/tdv/tdv-test:8.2 tdv.server'
      }
    }
       steps{

               sh 'sudo tdv whoami'
               sh 'sudo tdv pwd'
               sh 'sudo tdv echo aaa'

       }

  }
    }
}

After the Job run, I can check the Container start up actually. but it still get error like following

$ docker top f1140072d77c5bed3ce43a5ad2ab3c4be24e8c32cf095e83c3fd01a883e67c4e -eo pid,comm
ERROR: The container started but didn't run the expected command. Please double check your ENTRYPOINT does execute the command passed as docker run argument, as required by official docker images (see https://github.com/docker-library/official-images#consistency for entrypoint consistency requirements).
Alternatively you can force image entrypoint to be disabled by adding option `--entrypoint=''`.
[Pipeline] {
[Pipeline] sh
sh: /opt/test@tmp/durable-081990da/jenkins-log.txt: Permission denied
sh: /opt/test@tmp/durable-081990da/jenkins-result.txt.tmp: Permission denied
touch: cannot touch ‘/opt/test@tmp/durable-081990da/jenkins-log.txt’: Permission denied
mv: cannot stat ‘/opt/test@tmp/durable-081990da/jenkins-result.txt.tmp’: No such file or directory
touch: cannot touch ‘/opt/test@tmp/durable-081990da/jenkins-log.txt’: Permission denied
touch: cannot touch ‘/opt/test@tmp/durable-081990da/jenkins-log.txt’: Permission denied

Comments

0

Solution

You currently have sh 'sudo tdv whoami'

I think you should add the -u flag after sudo like that: sh 'sudo -u tdv whoami'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.