Different docker images per branches

docker
circle.yml

#1

I would like to use different docker images per branches.
I have 3 images: repo/myimage:develop, repo/myimage:staging and repo/myimage:master.

I want to use repo/myimage:staging when $CIRCLE_BRANCH is staging, repo/myimage:master when $CIRCLE_BRANCH is master and repo/myimage:develop for all the other branches:

I started from this config:

jobs:
  build:
    docker:
       - image: "repo/myimage:${CIRCLE_BRANCH}"

Since I’m using the same branch names in the circleci repo, it works for staging and master.

How do I tell now the config to use repo/myimage:develop when CIRCLE_BRANCH is not staging or master?

Ideally something like:

jobs:
  build:
    docker:
       - image: "repo/myimage:${if CIRCLE_BRANCH == 'staging' then 'staging' else if CIRCLE_BRANCH == 'master' then 'master' else 'development'}"

Thanks.


#2

A workaround would be to duplicate the build job definition, changing only the name (to build_develop or similar) and the image tag (to develop) and then use the branch filters in your workflow definition to run that other job when the branch is not staging or master.

It’s a bit hacky, but would work for you I reckon. You could use yml references to have the job defined once and include it into both the build and build_develop jobs.


#3

I wouldn’t say that’s “a bit hacky”. That was actually going to be my suggestion.


#4

Thanks for the suggestion!

I came up with this solution, which setups an api container and a postgres container to run e2e tests with selenium using different tags for the containers according to the branch.

What do you think?


version: 2

# Default working directory
default_work_dir: &default_work_dir
  working_directory: ~/app

# Default docker images
docker:
  - &primary_image
    image: mycompany/primary-image
  - &selenium_image
    image: selenium/standalone-chrome:3.1.0
  - &development_postgres_image
    image: mycompany/postgres:development
  - &development_api_image
    image: mycompany/api:development
  - &staging_postgres_image
    image: mycompany/postgres:staging
  - &staging_api_image
    image: mycompany/api:staging
  - &master_postgres_image
    image: mycompany/postgres:master
  - &master_api_image
    image: mycompany/api:master

# Default steps 
checkout_test_build: &checkout_test_build
  - checkout
  # Install dependencies 
  # Run linter and unit tests
  # Build app in /app/dist
  # Save the dist file in cache to restore it when deploying
  - save_cache:
      key: build-{{ .Branch }}-{{ .Revision }}
      paths:
        - ~/app/dist
  # Run e2e tests
  # Store artifacts

jobs:
  # Build jobs
  build_development:
    <<: *default_work_dir
    docker: 
      - *primary_image
      - *selenium_image
      - *development_postgres_image
      - *development_api_image
    steps: *checkout_test_build
  build_staging:
    <<: *default_work_dir
    docker: 
      - *primary_image
      - *selenium_image
      - *staging_postgres_image
      - *staging_api_image
    steps: *checkout_test_build
  build_master:
    <<: *default_work_dir
    docker: 
      - *primary_image
      - *selenium_image
      - *master_postgres_image
      - *master_api_image
    steps: *checkout_test_build

  # Deploy jobs
  deploy_staging:
    <<: *default_work_dir
    docker:
      - *primary_image
    steps: 
      - checkout
      - restore_cache:
          key: build-{{ .Branch }}-{{ .Revision }}
      - deploy:
          name: Deploy staging
          command: ./deploy.sh staging
  deploy_master:
    <<: *default_work_dir
    docker:
      - *primary_image
    steps: 
      - checkout
      - restore_cache:
          key: build-{{ .Branch }}-{{ .Revision }}
      - deploy:
          name: Deploy master
          command: ./deploy.sh master

workflows:
  version: 2

  build-test-deploy:
    jobs:

      # When merging any branch except `staging`, and `master`
      # we run the checkout/test/build job against development API
      - build_development:
          filters:
            branches:
              ignore: /(staging|master)/

      # Build, test and deploy when merging staging
      - build_staging:
          filters:
            branches:
              only: staging
      - deploy_staging:
          requires: 
            - build_staging
          filters:
            branches:
              only: staging

      # Build, test and deploy when merging master
      - build_master:
          filters:
            branches:
              only: master
      - deploy_master:
          requires: 
            - build_master
          filters:
            branches:
              only: master

#5

@gpbl Yeah, that looks nice! Good use of the YML references as well. :thumbsup:


#6

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.