Search code examples
azuredockerazure-devopsazure-container-service

Building multiple images from a monorepo where each service has its own Dockerfile


I'm attempting to learn Azure DevOps Pipelines and AKS. The ultimate goal would to Build and deploy to Azure Kubernetes Service, but I'm breaking this into smaller parts so understand what is going on at each stage.

Thus, my current goal is to Build and push to Azure Container Registry.

I'm working with a pretty basic monorepo which has this simplified structure:

acr-test/
  client/
    Dockerfile
  db/
    Dockerfile
  server/
    Dockerfile

I'd like to generate an image for each part of the application so that a arc-test-client and arc-test-server is generated.

What is currently happening when I "Create Pipeline" in Azure DevOps and let it build the azure-pipelines.yml is it just finds the first Dockerfile and bases all the parameters on it, ignoring the other ones.

Some I'm curious:

  • Is it possible to create multiple images from a single azure-pipelines.yml?
  • Do I need multiple .yml for each Dockerfile?
  • Do I need to write a separate .sh to build and push these separately (example)?
  • Or is this simply not possible with a mono-repo?

Solution

    1. yes, you'd need to modify the azure-pipelines.yml for that.
    2. no. one for all or one for each dockerfile is okay
    3. not necessary, you could use a .sh script, but probably easier to just have docker tasks in the azure-pipelines.yml
    4. it is.

    you would need to do something like this:

        steps:
        - task: Docker@2
          displayName: Build and push an image to container registry
          inputs:
            command: buildAndPush
            repository: $(imageRepository1)
            dockerfile: $(dockerfilePath1)
            containerRegistry: $(dockerRegistryServiceConnection)
            tags: |
              $(tag1)
        - task: Docker@2
          displayName: Build and push an image to container registry
          inputs:
            command: buildAndPush
            repository: $(imageRepository2)
            dockerfile: $(dockerfilePath2)
            containerRegistry: $(dockerRegistryServiceConnection)
            tags: |
              $(tag2)
        - task: Docker@2
          displayName: Build and push an image to container registry
          inputs:
            command: buildAndPush
            repository: $(imageRepository3)
            dockerfile: $(dockerfilePath3)
            containerRegistry: $(dockerRegistryServiceConnection)
            tags: |
              $(tag3)
    

    or can have multiple something.yml in the repo and have individual builds for each component (makes a lot more sense, tbh)

    alternatively, with your file structure you can just reuse the same yaml file as a template and just feed it parameters. that would reduce code duplication and allow for easier management of your builds