0
votes

I have a spring boot project with 4 microservices (Eureka service registry, Config server, a Zuul gateway and a userservice) in one repository with a parent project where I have a docker-compose.yml which reads the Dockerfiles in the microservices project and uses the "application-docker.yml" and "bootstrap-docker.yml"

What I'd like to do is to trigger a jenkins pipeline after a commit in git so that it will compile and deploy the microservices in Docker. Eventually I'd like to have a production configuration that deploys the images in Kubernetes maybe AWS.

Now, in order to work, the microservices need to start in order:

  1. configserver
  2. eureka service registry
  3. gateway , etc..

What is the best practise?

If I have separate repositories per microservice, I think I can figure it out. It should be easy to deploy a single microservice assuming that configserver and eureka service registry are already up and running, in reality they should never change.

If I have a single repository, and I keep developing new microservices, do I need to have separate jenkins file per microservices or can I have a jenkinsfile in the parent project and use docker-compose? How does it work? Any articles online that can help (couldn't find any). Does it make sense?

Or do I need to look at Jenkins X ?

Thanks!

1

1 Answers

0
votes

I would recommend using separate repositories for each microservice. You use microservices to prevent monoliths and have small well-defined services; it only seems appropriate to also separate them by space i.e. store them in separate repositories (making it for example easier to reuse one).

You would then have to provide a Jenkinsfile in each repo. These would be mostly identical.

If you want fast release cycles you could automatically deploy a single service upon release. Alternatively you could use an additional release train module that handles the full deployment. In both cases I would use a docker-compose file that handles the interconnection between the services. You can enforce the right order by using 'depends_on, links, volumes_from, and network_mode: "service:..."'. For a full reference see the docker documentation.

If you want to keep your single repository your Jenkinsfile(s) would have to be quite hacky, I suppose... After each commit you would either

  • build all modules --> monolithic behaviour

  • somehow determine which modules have changed (e.g. looking at the git log) --> same behaviour as with multiple modules but very hackily

The Docker-Compose File

If you want to release all modules at a specific point of time you could use a Release Train module where the docker-compose.yml resides next to a Jenkinsfile. Then when you want to ship your application you can start this Jenkins-job.

If you want to ship each service as soon as it is released, independently from the others, you would need to access the docker-compose.yml from each module. You could do this manually (since the files won't change too often) or create a docker module that you use as a git-submodule in all your services.

We use a generic docker-compose.yml for this, where every version is replaced by a variable:

example-service:
  image: example.service:${EXAMPLE_SERVICE_VERSION}

Then to start that specific service in jenkins we use the command

export EXAMPLE_SERVICE_VERSION=1.1.1
docker-compose -p example-project -f docker-compose.yml up -d example-service