Using Service containers¶
Service containers make it easy to work with various databases, caching services, message broker, etc. within your pipeline. 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/job 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:3.3
- image: postgres ## db service
environment:
- POSTGRES_DB=test
- image: redis ## cache service
steps:
- checkout
- 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:
- checkout
- 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
.
build: # task name
runner:
containers:
...
- image: postgres
environment:
- POSTGRES_DB=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:secret@localhost/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.
build: # task name
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:secret@localhost/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.
build: # task name
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/