linkorb.shipyard
ansible-role-shipyard
About Shipyard
Shipyard is a tool that helps manage Docker swarm clusters and stacks using Ansible playbooks.
It's inspired by tools like Helm and helmfile and offers similar features, but works with Docker Swarm instead of Kubernetes.
Concepts:
- Shipyard Chart: This is a package that defines a Docker Compose stack and all associated files (like config and environment files). It's like a Helm Chart or a Homebrew formula. A Shipyard Chart contains everything needed to deploy and run an application as a Docker Swarm stack, and can handle everything from simple apps to complex web application stacks with several dependencies (like databases and caches).
- Shipyard Stack: This is a specific instance of a Shipyard Chart, customized using a
values.yaml
file. - shipyard.yaml: This file specifies which Charts to set up, what values to use, and on which Docker hosts.
The concepts are similar to Helm and helmfile, but Shipyard does not require a Kubernetes cluster; it uses Docker Swarm for deployments.
Prerequisites
This Ansible role requires that your target hosts are set up with:
- Docker Swarm (confirm with
docker swarm deploy
) - Docker Compose (confirm with
docker-compose
) - Docker pull authentication for the images being used (confirm with
docker pull my-image
)
Role variables
You can customize the role using some optional variables:
shipyard_filename
: Path to your shipyard.yaml file. Default:{{inventory_path}}/shipyard.yaml
. This can be a Jinja2 template.shipyard_charts_path
: Path to your charts directory. Default:{{inventory_path}}/shipyard/charts
shipyard_stacks_path
: Path to your stacks (values.yaml / values.sops.yaml) directory. Default:{{inventory_path}}/shipyard/stacks
shipyard_stacks_docker_secrets
: A list of Docker Secrets. Default:[]
shipyard_tag
: Optionally deploy only stacks with this tag. Default: empty
Usage
Obtain the role from Ansible galaxy
Set up your requirements.yml
file to include the role:
roles:
- name: linkorb.shipyard
Then run ansible-galaxy install -r requirements.yml
to install the role.
Creating a shipyard.yaml file:
The shipyard.yaml
file defines which stacks to deploy to which hosts.
# shipyard.yaml
stacks:
- name: my-traefik
chart: traefik
host: swarm-host-a
values: my-traefik/values.yaml
tag: lb
- name: my-whoami
chart: whoami
host: swarm-host-a
values: my-whoami/values.yaml
tag: apps
- name: my-mariadb
chart: mariadb
host: swarm-host-a
values: my-mariadb/values.yaml
tag: db
- name: my-whoami-b
chart: whoami
host: swarm-host-b
values: my-whoami-b/values.yaml
tag: apps
Adding the shipyard role to your ansible playbook
In your Ansible playbook (usually site.yml
), add:
- name: Docker shipyard host configuration
hosts: my-swarm-hosts # or a group of hosts - should be Docker Swarm managers with Docker image pull authentication
tags:
- shipyard # or any tag you want to run this playbook
roles:
- role: linkorb.shipyard # the role from Ansible galaxy
vars:
shipyard_tag: apps
This will deploy to the specified hosts using the shipyard.yaml
file located in the playbook's root directory.
Creating a Shipyard Chart
The structure for a Shipyard Chart looks like this:
my-shipyard-chart/
Chart.yaml # metadata for the chart
LICENSE # license for this chart
README.md # readme for this chart
values.yaml # default values for this chart
templates/ # Jinja2 templates for this chart
docker-compose.yml # Docker Compose template file for this chart
example.conf # example config file template for this chart
env.example # another example config file for this chart
a-directory/ # directory to copy to the target host
The Shipyard role will copy the files in the templates/
directory to the target host and render them using the Chart and Stack values.
values.yaml / values.sops.yaml and chart default values
Each stack needs a values file that includes specific values for that instance of the chart. This is loaded from {{shipyard_stacks_path}}/{{stack_name}}/values.yaml
. If a values.sops.yaml
file is found, it will also be loaded and decrypted automatically.
Each chart also has default values. If any specific stack-level value is not defined, the chart's default value is used.
The loading order is:
- Default values from the chart
- The values.yaml from the stack
- The values.sops.yaml from the stack
Special Values
primed_volumes
: List of Docker volume information objects to create for the stack. This is only meaningful if the Chart supports it.
Each volume info object contains:
name
: The name of the volumetarget
: Where to mount the volume in the containerpath
: The path on the remote host to copy into the volume.
For example, to create a volume with MariaDB initialization scripts:
# my-stack/values.yaml
primed_volumes:
- name: mariadb_init_data
target: /docker-entrypoint-initdb.d # where the MariaDB looks for init data
path: docker-entrypoint-initdb.d # this dir is in the Chart templates/
Target host directory structure
On the target hosts (Docker Swarm managers), the role creates the following structure:
/opt/shipyard/stacks/
my-shipyard-stack/
docker-compose.yml # rendered Docker Compose file
example.conf # rendered example config file
# ... etc
Deploying the stacks to Docker Swarm
After template files are created, the role will run docker stack deploy
on the target host to deploy the stack.
Example Shipyard Chart
See the example/shipyard/charts/whoami directory for an example of a Shipyard Chart.
Contributing
We welcome contributions to improve this repository. Whether it's fixing bugs, adding features, or enhancing documentation, your help is appreciated. To contribute, fork the repository and clone your fork.
Please read LinkORB's Contribution Guidelines for standards on commits, branches, and pull requests, and our code of conduct before submitting any changes.
If you cannot make the changes yourself, feel free to report an issue so that we or others can help.
Brought to you by the LinkORB Engineering team
Check out our other projects at linkorb.com/engineering.
By the way, we're hiring!
ansible-galaxy install linkorb.shipyard