How to network to my fabric8 docker compose service from cloud build?

168 views Asked by At

My maven build file runs an Integration Test and I use the io.fabric8:docker-maven-plugin to spin up an environment for the test to run against. There are several things running in the resulting environment but to keep this short there is mainly one REST server that the code I am testing needs to talk to.

It works really well locally. I use mvn verify and the integration test runs, and the environment is started up and taken down either side of it. No problems.

However I also want this build to run in GCP Cloud Build. It almost does. The environment is started successfully including the REST server as well as a postgres instance the REST server talks to, and that connection is working. But when my test code tries to talk to the REST server it fails to connect.

I have the port for the REST server declared as 8080:8080, ie the 8080 port is exposed on the local machine. And this works on my own machine. It doesn't work on Cloud Build though. I saw somewhere that Cloud Build likes to use its own network cloudbuild and that I need to define that network in a docker-compose file something like this:

networks:
  default:
    external:
      name: cloudbuild

However I am not using a docker-compose file. I have the images etc to run defined in my pom.xml file under the entry for io.fabric8:docker-maven-plugin and it isn't clear from the fabric8 docs how to specify this. I'm also unclear on whether, with this in place, I need to change my localhost references to something else, though I tried making them cloudbuild and that did not help.

1

There are 1 answers

0
RogerParkinson On

I found the answer here. I discarded the maven plugin approach and I start docker compose in the cloudbuild.yaml file like this:

  - name: 'docker/compose'
    args:  [ '-f', 'liontamer-web/docker/docker-compose.yml', '-f', 'liontamer-web/docker/docker-compose-ci.yml', 'up', '-d']
    id: docker-compose

(yes, my project is called liontamer, and the docker file is in a module named liontamer-web), Notice there are two docker compose files. The second one contains this:

version: '3.2'
networks:
  default:
    external:
      name: cloudbuild

which means it uses the right network name when running under Cloud Build.

The rest of my cloudbuild.yaml file looks like this:

  - name: 'maven:3.8-openjdk-17'
    args:
      - 'mvn'
      - '-Dmaven.test.skip=false'
      - '-Dmaven.repo.local=/workspace/.m2/repository'
      - '--settings'
      - custom-settings.xml
      - clean
      - install
      - '-B'
      - '-DVERSION_ID=$TAG_NAME'
      - '-DBRANCH_ID=master'
      - '-DPROJECT_ID=$PROJECT_ID'
      - '-DCONTAINER_REPO=${_CONTAINER_REPO}'
      - '-DMAVEN_REPO=${_MAVEN_REPO}'
      - '-DDOCKER_CONFIG=/builder/home/.docker'
      - '-P'
      - release
    id: build
    waitFor: [docker-compose]
  - name: 'docker/compose'
    args:  [ '-f', 'liontamer-web/docker/docker-compose.yml', '-f', 'liontamer-web/docker/docker-compose-ci.yml', 'down']
    id: docker-compose-down

it is important to note the waitFor in the build because I think it will otherwise clean up the docker compose stuff before running that if it doesn't find a waitFor. I'm not sure how important the last step which takes docker-compose down but it seems polite to clean up.

One more thing I had to change was that my integration test code has to refer to the docker services by service name. When running locally I have ports exposed on localhost so I can just use localhost with the right port number. Not the case under Cloud Build. So for the one REST server I need to reach from the IT I changed it's host reference from localhost to the service name in the docker compose file.

That means I can't run it locally, of course, unless I do some editing. But this is good enough.