Babyburger
Babyburger

Reputation: 1828

Jenkins Docker container can't upload artifact to Nexus Docker container

I have the following setup for my DevOps environment, orchestrated with Docker Compose:

(simplified) docker-compose.yml:

version: '3.7'
services:
  nexus:
    build: ./nexus/.
    expose:
      - 8081
    networks:
      - devops-network
  jenkins:
    build: ./jenkins/.
    expose:
      - 8080
    depends_on:
      - nexus
    networks:
      - devops-network
  nginx:
    image: nginx:1.19.5
    ports:
      - 80:80
    depends_on:
      - nexus
      - jenkins
    networks:
      - devops-network
networks:
  devops-network:

(simplified) nginx.conf:

http {
    upstream docker-jenkins {
        server jenkins:8080;
    }
    upstream docker-nexus {
        server nexus:8081;
    }

    server {
        server_name  jenkins.homenetwork.dns;

        location / {
            proxy_pass http://docker-jenkins;
        }
    }

    server {
        server_name  nexus.homenetwork.dns;

        location / {
            proxy_pass http://docker-nexus;
        }
    }
}

Jenkins can communicate with Nexus through a Docker network. If I enter the Jenkins container, then ping nexus and curl http://nexus:8081 give me positive responses (I get feedback from Nexus).

But when I run a Jenkins pipeline with a nested Docker agent for Maven:

pipeline {
    agent {
        docker {  // successfully pulls image
            image 'maven:3.6.3-openjdk-11'
            args '-v /root/.m2:/root/.m2'
        }
    }
    stages {
        stage('Maven build') {
            steps {
                mavenBuildStep()
            }
        }
        stage('Upload'){
            steps {
                withMaven(mavenSettingsConfig: 'cdb64ca9-d8e1-4d19-b486-e86c0ee75f50')
                    {
                        echo 'uploading Maven artifacts'
                        sh 'mvn deploy -DskipTests'   // fails because it can't find nexus
                    }

            }
        }
    }
}

and maven settings.xml with the above id:

<servers>
    <server>
        <id>nexus-snapshots</id>
        <username>jenkins</username>
        <password>${JENKINS_NEXUS_PASSWORD}</password>
    </server>
</servers>

and this in my pom.xml:

<distributionManagement>
    <snapshotRepository>
        <id>nexus-snapshots</id>
        <url>http://nexus:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

then it says:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy (default-deploy) on project parent: Failed to retrieve remote metadata ... from/to nexus-snapshots (http://nexus:8081/repository/maven-snapshots/): Transfer failed for http://nexus:8081/repository/maven-snapshots/.../1.0.0-SNAPSHOT/maven-metadata.xml: Unknown host nexus: No address associated with hostname

When I change the repository url in the pom.xml to the network IP of the Nexus container:

<distributionManagement>
    <snapshotRepository>
        <id>nexus-snapshots</id>
        <url>http://172.26.0.2:8081/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>

it then times out:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy (default-deploy) on project parent: ... Connect to 172.26.0.2:8081 [/172.26.0.2] failed: Connection timed out

What is going on? I mapped the host Docker daemon to the Jenkins container with setfacl -m user:jenkins:rw /var/run/docker.sock, so it should be able to reach the Nexus container? When I pull the Docker image in the pipeline, the image gets added to my host system and doesn't need to be downloaded again the next time so this seems to be in working order. Is it because the 'Docker inside Docker' doesn't have access to devop-network?

Ideally I would be able to set http://nexus.homenetwork.dns/repository/maven-snapshots/ as url in my pom instead, but this doesn't seem possible. Does anyone have experience with this kind of setup?

Update

To validate my suspicions, I used agent any instead of a Docker agent in the Jenkins pipeline and I installed maven in the Jenkins container. With that setup, running the Jenkins pipeline correctly uploads the snapshots with url http://nexus:8081/repository/maven-snapshots/.

This is not a bad solution, but I'm left wondering how to make it work with the Docker agent out of pure curiosity.

Upvotes: 1

Views: 1101

Answers (1)

Oli
Oli

Reputation: 23

Hey I had the very same problem and I was looking for a solution for quite some time now. I also didn't get it at first. However, I figured it out at the end to be a quite basic docker thing. The docker agent basically runs a new docker container. If you want it to access another already existing one with just 'nexus' you have to add it to the same bridge network. In your case you need to add

pipeline { agent { docker {
...
args  '--net="devops-network"'
}
}

This at least solved it for me.

Upvotes: 2

Related Questions