Provision of Docker Containers with Sparrowdo
Tags: docker, perl6, linux, devops
Published: 2017-10-10 11:58:30

---
title: Provision of Docker Containers with Sparrowdo
published: true
description: How to Provision Docker Instances with Powerful Sparrowdo DSL 
tags: docker, Perl6, Linux, devops
---


# Introduction

[Sparrowdo](https://github.com/melezhik/sparrowdo) is a configuration management tool written on [Perl6](https://perl6.org/), 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:

* [http://rakudo.org/how-to-get-rakudo/](http://rakudo.org/how-to-get-rakudo/)
* [https://github.com/nxadm/rakudo-pkg/releases](https://github.com/nxadm/rakudo-pkg/releases)


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](https://hub.docker.com/r/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](https://github.com/melezhik/sparrowdo/blob/master/core-dsl.md) 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.

## Sparrowfile

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 127.0.0.1 ... 
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](https://github.com/melezhik/sparrowdo) 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](https://github.com/melezhik/sparrowdo#--format)._


# Installing system packages

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


```
package-install (
  'nano',
  'mc',
  'ncdu',
  'nginx'
);

```


And the output will be:

```
running sparrow tasks on 127.0.0.1 ... 
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](https://github.com/melezhik/sparrowdo/blob/master/core-dsl.md#services) 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 127.0.0.1 ... 
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](https://github.com/melezhik/sparrowdo/blob/master/core-dsl.md#asserts) to check services health, so let's use somes to check Nginx server availability:


```
proc-exists 'nginx';
http-ok;
```


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 127.0.0.1 ... 
target OS is - ubuntu
push [task] check nginx process OK
push [task] run bash: curl -fsSLk -D - --retry 3 127.0.0.1 -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 /.*/
STATUS	SUCCEED
@ runs bash command
2017-10-10 11:26:28 : [task] run bash: curl -fsSLk -D - --retry 3 127.0.0.1 -o /dev/null ... [path] modules/bash-command/ [params] envvars:
++ test -z
++ bash -c ' curl -fsSLk -D - --retry 3 127.0.0.1 -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
STATUS	SUCCEED
```

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](https://github.com/melezhik/sparrowdo/blob/master/core-dsl.md#bash-commands) 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');

```


# Conclusion

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](https://github.com/melezhik/sparrowdo/blob/master/core-dsl.md#ssh) commands invocation, [fetching](https://github.com/melezhik/sparrowdo/blob/master/core-dsl.md#git) Git repositories, population of configuration files by [templates](https://github.com/melezhik/sparrowdo/blob/master/core-dsl.md#templates) and more, I'd encourage you to delve the details at Sparrowdo GitHub [documentation pages](https://github.com/melezhik/sparrowdo) or at Sparrowdo dedicated blog site - [http://sparrowdo.wordepress.com](http://sparrowdo.wordepress.com)

As usual - ideas, comments and questions are welcome.

Regards.

The author of Sparrowdo.