Search code examples
postgresqldockerjenkinsjenkins-pipelineroot

Jenkins pipeline with docker: run docker as specific user (embedded postgresql


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

Solution

  • 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)