Reusing executors with different additional docker images

Hello everyone, I’m trying to reuse an executor but in a specific job I need to use an additional docker image that I don’t need in other jobs that use the same executor, so how can I specify for that specific job to use this additional docker image?
I’m trying to avoid code duplication so I don’t want 2 executors with the same environment variables and the second executor with the additional image as is shown in the following .circleci/config.yml file:

executors:
  ruby_with_db_executor:
    docker:
      - image: circleci/ruby:2.6.6-node-browsers
        environment:
          <some-params-here>
      - image: postgres:11.6-alpine

  ruby_with_db_and_redis_executor:
    docker:
      - image: circleci/ruby:2.6.6-node-browsers
        environment:
          <same-params-as-previous-executor-here>
      - image: postgres:11.6-alpine
      - image: redis

I’m trying to get rid of the second executor because if I change any parameters in one executor, I would need to do so in the second as well.

I have read the documentation proposed Overriding keys when invoking an executor but it seems the docker images from the executor are not present in the build when I do the following:

jobs:
  my_job:
    docker:
      - image: circleci/ruby:2.6.6-node-browsers
      - image: redis
    executor: ruby_with_db_executor
    steps:
      - checkout
      <other-steps>

I get an error that postgres image is not present (that should have come from the executor).

1 Like

Yeah, the documentation seems to describe this as the expected behaviour unfortunately:

For example, if your job declares a docker stanza, it will be used, in its entirety, instead of the one in your executor

This kind of significantly reduces the utility of executors in my opinion, so I hope we get more options in the future. You can try hacking around this a tad by using YAML anchors (something I did before reusable config elements were introduced), but it’s messy and only possibly improves your situation:

images:
  ruby: &_ruby
    image: circleci/ruby:2.6.6-node-browsers
    environment:
          <some-params-here>
  postgres: &_postgres
    image: postgres:11.6-alpine
  redis: &_redis
    image: redis

executors:
  ruby_with_db_executor:
    docker:
      - *_ruby
      - *_postgres

  ruby_with_db_and_redis_executor:
    docker:
      - *_ruby
      - *_postgres
      - *_redis

Since you can’t combine the list of base images with new entries this way, you’re still stuck adding additional images in both places if you decide to do that in the future, but at least if you change the definitions of any individual image it will be updated in both locations.

1 Like