Skip to content

Docker helpers

Overview

Pipelight by nature allows a great flexibility. But implementing generics and already wide spread automation methods that require loads of commands is quite cumbersome.

Concerning docker usage, you could write your own functions but Pipelight got you covered with the docker helpers. You are all set for docker testing and deployment.

Docker helpers provide the needed functions to manipulate docker components based on a single docker architecture object definition.

The quickest showcase!

Define your docker components into a Docker instance.

ts
const docker = new Docker({
  containers: [
    {
      name: `my_container`,
      image: {
        name: "debian:latest"
      },
      ports: [{ in: 80, out: 8080 }]
    }
  ]
});
const docker = new Docker({
  containers: [
    {
      name: `my_container`,
      image: {
        name: "debian:latest"
      },
      ports: [{ in: 80, out: 8080 }]
    }
  ]
});

Use the internal methods to manipulate docker components.

ts
docker.containers.create();
docker.containers.create();

This example only scratches the surface. You can define images, volumes and containers as well as their intercations through networks.

Comes in two flavors 🍦

Author's note

The strict declaration is good to build small test suits. Whereas the loose declaration is better suited to build pipelines that deploys applications(front/api/db...) to multiple environnements(dev/prod...).

To take the most out of this helpers you would want to use the docker Loose declaration which is the most simple and automated (and opinionated). If this declaration does not suit your style, head towards the lower level helpers it is based upon. Use the docker Strict declaration for a more personnalized docker architecture definition.

Understand the internal functionning

You first have to define your docker components (images, containers, volumes and networks) according to the DockerAutoParams or the DockerParams type.

ts
const params: DockerAutoParams | DockerParams = {};
const params: DockerAutoParams | DockerParams = {};
ts
// Loose declaration
interface DockerAutoParams {
  globals: Globals;
  containers: ContainerAutoParams[];
}
// Loose declaration
interface DockerAutoParams {
  globals: Globals;
  containers: ContainerAutoParams[];
}
ts
// Strict declaration
interface DockerParams {
  images?: ImageParams[];
  volumes?: VolumeParams[];
  networks?: NetworkParams[];
  containers?: ContainerParams[];
}
// Strict declaration
interface DockerParams {
  images?: ImageParams[];
  volumes?: VolumeParams[];
  networks?: NetworkParams[];
  containers?: ContainerParams[];
}

Attempting to use methods on Typescript types and interfaces returns an error.

ts
params.containers.create(); // returns an error 
params.containers.create(); // returns an error 

You have to transform the DockerAutoParams or DockerParams interface instance into a Docker object instance.

Then, every deep inner Typescript Interface is transformed in its Javascript Class equivalent. allowing the usage of Classes methods.

ts
// enable methods
const docker: Docker = new Docker(params); 
// create every defined containers
docker.container.create(); 
// create every defined volumes
docker.volumes.create();
// enable methods
const docker: Docker = new Docker(params); 
// create every defined containers
docker.container.create(); 
// create every defined volumes
docker.volumes.create();

Opinionated docker architecture

WARNING

"I'm a strong advocate for "docker for small projects" and not just huge, scaling behemoths and microservices." (docker local-persist plugin author)

There is many ways to achieve same results using docker, however, every choice has been made to bring the greatest simplicity, maintability and debuggability possible to the smallest teams (>=1 member).

The helpers add an abstraction layer on docker to build big, in a few lines while keeping things tweakable, to the point it has become a sort of alternative to docker-compose.

The docker helpers bring some optimisation on the table.

  • enhance pipeline readability;

    We need to understand a command at a glance when debugging so we favor long options over short options (--volume over -v)

  • enhance docker architecture maintainability;

    Docker has the practical bind-mounts which is the ability to link a filesystem path /home/mystuffs into a docker container /path/into/container. However, they can be a mess to troubleshoot because not reported by the volume listing command docker volume ls.

    The docker helpers only supports named volumes and named bind mounts (bind-mounts but cleaner) thanks to the docker local-persist plugin that you need to install locally.

    This way, docker volume ls outputs every volumes and every binds. No need to docker container inspect every one of your containers anymore.

  • enhance deployment related files storage;

    Force tidying your dockerfile for autoretrieve by the helper (mandatory in Loose declaration).

    sh
    .docker
    └── Dockerfile.test
    .docker
    └── Dockerfile.test