Sergei Volynkin
Sergei Volynkin

Reputation: 401

Unable to connect to docker container in Jenkins pipeline when using "Docker outside of Docker" setup

I'm running a Jenkins job based on such agent:

pipeline {
  agent {
    docker {
      image 'cypress/base:10'
        args '-v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v /usr/local/bin/docker-compose:/usr/local/bin/docker-compose -u root'
    }
  }
…

note: docker and docker-compose are mounted into my agent container to be able to run docker containers inside the pipeline stages ("Docker outside of Docker" setup)

down the pipeline, I start docker-compose setup that consists of 2 containers - server and webapp

…
sh 'docker-compose up --build --detach'
…

After that, I want to send a GET request to localhost:8080, this is where the web-app should be served from. But I get

Error: connect ECONNREFUSED localhost:8080

The same docker-compose setup works on my dev. machine. Port forwarding is set up correctly (8080:8080 port forwarding is enabled in docker-compose configuration file)

I think it's somewhat related to the "Docker outside of Docker" setup that I do in Jenkins 🤔Maybe port 8080 actually appears to be listening on the host of the agent of my pipeline, not sure…

I will be happy to get fresh ideas on the problem, completely run out of my mind with this.

And just to give more context: I want to run web-app + API server via docker-compose and then run Cypress (outside of docker-compose setup) to do E2E testing via UI

Upvotes: 1

Views: 1855

Answers (1)

Leil Jan C
Leil Jan C

Reputation: 85

In Jenkins docker out of docker setup, technically, Jenkins is also another container that "shares" the same space with other containers. Meaning, it can communicate to the containers it "created".

In my case, what I did was create a custom bridge network on my docker-compose.yml file

version: "3.8"

services:
  app:
    build:
      context: .
    ports:
      - 8081:8080
    depends_on:
      - redisdb
    networks:
      - frontend
      - backend

  redisdb:
    image: redis
    ports:
      - 127.0.0.1:6380:6379
    networks:
      - backend

networks:
  frontend: {}
  backend: {}

Then once this is created, docker-compose creates these networks with the following format:

  • {FOLDER_NAME}_frontend (example: pipeline_frontend)
  • {FOLDER_NAME}_backend

These networks are usually bridge networks.

My Jenkins container originally resides in the default network "bridge". Since my jenkins is in a bridge network and these containers are in a bridge type network, I can connect my jenkins via runtime later in the pipeline.

docker network connect pipeline_frontend jenkins

Now from jenkins, I can communicate directly to the container via its service name. In my case for example, from my Jenkins, I can curl to http://app:8080

Note: This answer is only applicable if Jenkins container exclusively resides in the host as with the containers it creates. I have not tested this on a setup wherein Jenkins has external nodes.

Upvotes: 1

Related Questions