Provision of Docker Containers with Sparrowdo

melezhik profile image Alexey Melezhik ・6 min read


Sparrowdo is a configuration management tool written on Perl6, in this post I'm going to show you how one can configure ( provision ) Docker instances by Sparrowdo scenarios.

Install Sparrowdo

Install Perl6

There are many ways to install Perl6, here are couple of links you can start with:

Once you've finished installing Perl6, the rest is simple, you need to install Sparrowdo as Perl6 module:

$ zef install Sparrowdo

Running Docker Container

Sparrowdo provisions live Docker containers so you need to run one. I'm going to use bitnami/minideb-extras, however you are free to choose your own one:

$ docker run -t -d bitnami/minideb-extras bash

If we check our Docker containers, the output will be something like that:

$ docker ps
CONTAINER ID        IMAGE                    COMMAND                 CREATED             STATUS              PORTS               NAMES
99bc3937ea37        bitnami/minideb-extras   "/entrypoint.sh bash"   2 seconds ago       Up 1 second                             determined_montalcini

As we've seen we succeeded in running our Docker instance.

Creating Sparrowdo Scenario

Sparrowdo exposes a neat DSL for servers configuration, so we are going to cover some Sparrowdo DSL to show how to use it.

The rest of this article will be related to how one can configure running Docker instances by the means of various Sparrowdo scenarios.

We are going to cover some typical use cases.


By default Sparrowdo looks for the scenario source code at the file named sparrowfile located in the current working directory. So we are going place scenario code here.

Consider the first simple use case of creating users and directories.

Creating users, files and directories

Probably most often thing you do setting up your server, so:

user "melezhik";

directory "/var/data/dir-one", %(
    owner => "melezhik"

And then give this scenario run by Sparrowdo:

$ sparrowdo --no_sudo --docker=determined_montalcini --format=production --bootstrap

The first run will produce a lot of output, don't be confused - because it's fresh server and Sparrowdo first install implies (*) Sparrow client bootstrap on this server ( notice --bootstrap option ). It results on many supplemental operations to be carried out.

The second run will be much faster and will produce much terser output (**):

running sparrow tasks on ... 
target OS is - ubuntu
push [task] create user melezhik OK
push [task] create directory /var/data/dir-one OK
SPL file /opt/sparrow/sparrow.list is empty
get index updates from SparrowHub ... OK
set up task box file - /home/melezhik/.sparrowdo//opt/sparrow/task-box.json - OK
public@user is uptodate (0.2.1)
public@directory is uptodate (0.1.5)
running task box from /opt/sparrow/sparrow-cache/task-box.json ... 
2017-10-10 10:22:30 : [task] create user melezhik [path] modules/change/
2017-10-10 10:22:30 : [task] create directory /var/data/dir-one [path] modules/create/

(*) Sparrow client is used as Sparrowdo agent to execute scenario which gets complied into underlying Sparrow tasks

(**) BTW, Sparrowdo comes with options to set the reports up, please follow the documentation.

Installing system packages

It is also often need when you do server setup and configuration, so:

package-install (

And the output will be:

running sparrow tasks on ... 
target OS is - ubuntu
push [task] install packages: nano mc ncdu nginx OK
SPL file /opt/sparrow/sparrow.list is empty
get index updates from SparrowHub ... OK
set up task box file - /home/melezhik/.sparrowdo//opt/sparrow/task-box.json - OK
installing public@package-generic version 0.003007 ...
Download https://sparrowhub.org/plugins/package-generic-v0.003007.tar.gz --- 200
running task box from /opt/sparrow/sparrow-cache/task-box.json ... 
2017-10-10 10:35:54 : [task] install packages: nano mc ncdu nginx [path] modules/apt-get/ [params] action:install package:nano
2017-10-10 10:36:01 : [task] install packages: nano mc ncdu nginx [path] modules/apt-get/ [params] action:install package:mc
2017-10-10 10:36:53 : [task] install packages: nano mc ncdu nginx [path] modules/apt-get/ [params] action:install package:ncdu
2017-10-10 10:36:59 : [task] install packages: nano mc ncdu nginx [path] modules/apt-get/ [params] action:install package:nginx

Running services

Services are vital part of infrastructure and configuration. Sparrowdo provides a desired set of functions to deal with this task. Let's install Nginx web server and the add it to run levels and then start it. The scenario will be:

package-install 'nginx';
service-enable 'nginx';
service-start 'nginx';

And the Sparrowdo report looks like this:

running sparrow tasks on ... 
target OS is - ubuntu
push [task] install packages: nginx OK
push [task] enable service nginx OK
push [task] start service nginx OK
SPL file /opt/sparrow/sparrow.list is empty
get index updates from SparrowHub ... OK
set up task box file - /home/melezhik/.sparrowdo//opt/sparrow/task-box.json - OK
public@package-generic is uptodate (0.3.7)
installing public@service version 0.001015 ...
Download https://sparrowhub.org/plugins/service-v0.001015.tar.gz --- 200
running task box from /opt/sparrow/sparrow-cache/task-box.json ... 
2017-10-10 10:42:33 : [task] install packages: nginx [path] modules/apt-get/ [params] action:install package:nginx
2017-10-10 10:42:33 : [task] enable service nginx [path] modules/enable/ [params] os:debian service:nginx
2017-10-10 10:42:33 : [task] start service nginx [path] modules/start/ [params] os:debian service:nginx

BTW Sparrowdo provides some nifty functions to check services health, so let's use somes to check Nginx server availability:

proc-exists 'nginx';

In this case we change --format to default value to see more details:

$ sparrowdo --no_sudo --docker=determined_montalcini --format=default
running sparrow tasks on ... 
target OS is - ubuntu
push [task] check nginx process OK
push [task] run bash: curl -fsSLk -D - --retry 3 -o /dev/null ... OK
SPL file /opt/sparrow/sparrow.list is empty
get index updates from SparrowHub ... OK
set up task box file - /home/melezhik/.sparrowdo//opt/sparrow/task-box.json - OK
installing public@proc-validate version 0.001003 ...
Download https://sparrowhub.org/plugins/proc-validate-v0.001003.tar.gz --- 200
installing public@bash version 0.001006 ...
Download https://sparrowhub.org/plugins/bash-v0.001006.tar.gz --- 200
running task box from /opt/sparrow/sparrow-cache/task-box.json ... 
2017-10-10 11:26:28 : [task] check nginx process [path] /
check by pid file
pid found at /var/run/nginx.pid:11114
11114 nginx: master process /usr/       43:54
ok  scenario succeeded
ok  text match /.*/
ok  '11114 nginx: master process /usr/       43:54' match /.*/
@ runs bash command
2017-10-10 11:26:28 : [task] run bash: curl -fsSLk -D - --retry 3 -o /dev/null ... [path] modules/bash-command/ [params] envvars:
++ test -z
++ bash -c ' curl -fsSLk -D - --retry 3 -o /dev/null'
HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Tue, 10 Oct 2017 11:26:28 GMT
Content-Type: text/html
Content-Length: 867
Last-Modified: Tue, 10 Oct 2017 10:37:28 GMT
Connection: keep-alive
ETag: "59dca2e8-363"
Accept-Ranges: bytes

ok  scenario succeeded

And finally, if those high level abstractions are not enough you can always execute an arbitrary Bash code, see next section.

Executing Bash Code

Bash function makes it possible to insert snippets of Bash code and execute them, there are many ways to call it and various parameters you may add, the simple form is just a bash $command, like this:

bash('echo hello world');


Sparrowdo is a modern, all batteries included toolkit to configure servers remotely. As we've seen, it plays nice with Docker.

There is a lot of ground to cover, like ssh/scp commands invocation, fetching Git repositories, population of configuration files by templates and more, I'd encourage you to delve the details at Sparrowdo GitHub documentation pages or at Sparrowdo dedicated blog site - http://sparrowdo.wordepress.com

As usual - ideas, comments and questions are welcome.


The author of Sparrowdo.

Posted on Oct 10 '17 by:

melezhik profile

Alexey Melezhik


Sparrow6 - Raku Automation Framework


markdown guide

What I'm missing from the article: If you write "Sparrowdo provisions live Docker containers" do you mean that you are actually provisioning docker containers like they are normal systems?

Otherwise I'm missing the parts that talk about how the workflow looks like to actually built images (for ephemeral containers), since that is usually what we want to do if we use docker, isn't it?


Sure, Sparrowdo configures running Docker containers, it does not fit for building images.