Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-57382

Documentation advises use of legacy container link feature

XMLWordPrintable

      Docs recommend deprecated / legacy docker features

      The docker-workflow-plugin documentation for scripted pipeline multiple/sidecar container use advises users to use the container link ("--link") feature in Docker and links to https://docs.docker.com/network/links/.

      But the Docker documentation warns that this is a legacy feature that's not recommended. It recommends user defined networks. Where that's not possible the default "bridge" network, while considered legacy, is preferred to using container links.

      The docs should not use the --link argument.

      Simplify use of correct Docker inter-container connections in Jenkins

      Code enhancements are not necessary to use the default bridge, but a container.getIpAddress() accessor in org/jenkinsci/plugins/docker/workflow/Docker.groovy's Container inner class would be very helpful. Without it the user's code must use docker inspect to get the container IP to connect to, as Docker doesn't do container-name resolving for the default bridge network:

      docker.image("postgres:11").withRun("-p 5555:5432") { -> pgcontainer
      
        def postgres_ip = sh(
          script: "docker inspect -f {{.NetworkSettings.IPAddress}} ${pgcontainer.id}",
          returnStdout: true)
        
        docker.image("myapp:latest").inside {
          sh("runMyApp --postgres-host ${postgres_ip} --postgres-port 5555")
        }
      
      }
      

      Natively support user defined networks

      Even better we could natively support user-defined Docker networks with relatively small changes:

      • a docker.withNetwork(...) DSL call that creates a user defined network and passes a Network object with getName() accessor to the inner closure, then cleans it up on closure exit. Like withRun etc. Name is generated if not provided.
      • All context-nested docker.withRun and docker.inside calls will use this network by default by automatically passing the --network argument to docker run
      • A Container.getName(...) accessor in org/jenkinsci/plugins/docker/workflow/Docker.groovy's Container inner class, for easy referencing containers by name whether generated or otherwise. (unless the resolver works with container-id, need to check}}

      When using user-defined networks Docker creates a custom /etc/resolv.conf that points to its proxy nameserver, allowing other containers to be resolved by name. So you could then write the following code - which does not currently work and is not implemented:

      docker.withNetwork {
        docker.image("postgres:11").withRun { -> pgcontainer
        
          docker.image("myapp:latest").inside {
            sh("runMyApp --postgres-host ${pgcontainer.name} --postgres-port 5432")
          }
        }
      }
      

      ... and the Docker resolver will resolve pgcontainer.name to the right IP on the bridge network.

      It'd be further improved by supporting these features:

      • A different network can be selected even within a withNetwork closure by passing a new network keyword argument to docker.withRun or docker.inside. This may be a string network name or a Network wrapper object.
      • docker.createNetwork(...), docker.rmNetwork(...) and docker.getNetwork wrappers for more complex use cases return and destroy Network objects. getNetwork can take a create bool arg to get create-if-not-exists semantics, and can be used to load existing user defined networks.
      • (maybe as sugar): A publish argument to withRun and inside so you don't have to fiddle with the docker argument list to expose port ranges.

            Unassigned Unassigned
            ringerc Craig Ringer
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: