Skip to content

Using Service containers

Service containers make it easy to work with various databases, caching services, message broker, etc. within a workflow. For example, you might need to run integration tests that need a database or cache service.

These are essentially docker containers which are created and connected when a task within a workflow starts and destroyed when it completes. Your steps in a task can communicate to these using host network (localhost:<port> or 127.0.0.1:<port>).

An example -

  • For Linux VM build environment, you can use containers property to define the service containers.
  • For Docker build envionment, you can append in containers property after first element.
tasks:
  execute-tests:
    runner:
      containers:
      - image: razorci/ruby
      - image: postgres ## db service
        environment:
        - POSTGRES_DB=test
      - image: redis ## cache service
    steps:
    - commands:
      # Wait for the containers to be healthly using dockerize CLI
      # dockerize: https://github.com/jwilder/dockerize
      - dockerize -wait tcp://localhost:5432 -wait tcp://localhost:6379
    - run: bundle exec rspec
    ...
tasks:
  execute-tests:
    runner:
      os_image: ubuntu
      containers:
      - image: redis # cache service
      - image: postgres # db service
        environment:
        - POSTGRES_DB=test
    steps:
    - commands:
      # Wait for the containers to be healthly using dockerize CLI
      # dockerize: https://github.com/jwilder/dockerize
      - dockerize -wait tcp://localhost:5432 -wait tcp://localhost:6379

    - run: bundle exec rspec
    ...

Note

You can configure different service containers for each task in a workflow using runner property within the tasks.<task_id> or global. For more details, refer to "Pipeline YAML".

It uses the host network mode for the service containers. For example, if a container which binds to port 8080, the container's service will be available on port 8080 on runner VM. All ports are exposed from the container to the host VM by default.

Examples

This sections shows examples of creating service containers for various database, caching and message-broker, etc. use-cases.

Postgresql

The following example uses postgres image from Dockerhub and the service would be available at localhost:5432.

  steps:
    runner:
      containers:
      ...
      - image: postgres
        environment:
        - POSTGRES_DATABASE=db_test
        - POSTGRES_USER=test
        - POSTGRES_PASSWORD=secret
        options:
        - --health-cmd pg_isready
        - --health-interval 10s
        - --health-timeout 5s
        - --health-retries 5
    steps:
    ...

    # wait for the container to be ready
    - run: dockerize -wait tcp://localhost:5432

    # connection URI: postgres://test:[email protected]/db_test

MySQL

The following example uses mysql image from Dockerhub and the service would be available at localhost:3306. For more options, please refer to official page.

  steps:
    runner:
      containers:
      ...
      - image: mysql
        environment:
        - MYSQL_ROOT_PASSWORD=secret
        - MYSQL_DATABASE=db_test
        - MYSQL_ROOT_HOST=%
    steps:
    ...

    # wait for the container to be ready
    - run: dockerize -wait tcp://localhost:3306

    # connection URI: mysql://root:[email protected]/db_test

Redis

The following example uses redis image from Dockerhub and the service would be available at localhost:6379. For more options, please refer to official page.

  steps:
    runner:
      containers:
      ...
      - image: redis
        options:
        - --health-cmd "redis-cli ping"
        - --health-interval 10s
        - --health-timeout 5s
        - --health-retries 5
    steps:
    ...

    # wait for the container to be ready
    - run: dockerize -wait tcp://localhost:6379

    # connection URI: redis://localhost/