meli

package module
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 2, 2019 License: MIT Imports: 25 Imported by: 0

README

meli

CircleCI codecov GoDoc Go Report Card

Meli is supposed to be a faster, and drop in, alternative to docker-compose. Faster in the sense that, Meli will try to pull as many services(docker containers) as it can in parallel.

Meli is a Swahili word meaning ship; so think of Meli as a ship carrying your docker containers safely across the treacherous container seas.

It's currently work in progress, API will remain unstable for sometime.

I only intend to support docker-compose version 3+

Meli is NOT intended to replicate every feature of docker-compose, it is primarily intended to enable you to pull, build and run the services in your docker-compose file as fast as possible.
If you want to exec in to a running container, use docker; if you want to run an adhoc command in a container, use docker; if you want..... you get the drift.

Installing/Upgrading

Download a binary release for your particular OS from the releases page
We have binaries for:

  • linux(64bit)
  • windows(64bit)
  • macOS(64bit)

Usage

meli --help

Usage of meli:
  -up
    	Builds, re/creates, starts, and attaches to containers for a service.
        -d option runs containers in the background
  -f string
    	path to docker-compose.yml file. (default "docker-compose.yml")
  -build
    	Rebuild services
  -v	Show version information.
  -version
    	Show version information.

cat docker-compose.yml

version: '3'
services:
  redis:
    image: 'redis:3.0-alpine'
    environment:
      - RACK_ENV=development
      - type=database
    ports:
      - "6300:6379"
      - "6400:22"

meli -up

redis :: Pulling from library/redis 
redis :: Pulling fs layer 
redis :: Pulling fs layer 
redis :: Downloading [======================>        ]  3.595kB/8.164kB
redis :: Downloading [==============================>]  8.164kB/8.164kB
redis :: Download complete [========================>]  8.164kB/8.164kB
redis :: The server is now ready to accept connections on port 6379

Usage as a library

You really should be using the official docker Go sdk
However, if you feel inclined to use meli;

package main

import (
	"context"
	"log"
	"os"

	"github.com/docker/docker/client"
	"github.com/komuw/meli"
)

func main() {
	dc := &meli.DockerContainer{
		ComposeService: meli.ComposeService{Image: "busybox"},
		LogMedium:      os.Stdout,
		FollowLogs:     true}

	ctx := context.Background()
	cli, err := client.NewEnvClient()
	if err != nil {
		log.Fatal(err, " :unable to intialize docker client")
	}
	defer cli.Close()

	meli.LoadAuth() // load dockerhub info
	err = meli.PullDockerImage(ctx, cli, dc)
	log.Println(err)

}

Benchmarks

Aaah, everyones' favorite vanity metric yet no one seems to know how to conduct one in a consistent and scientific manner.
Take any results you see here with a large spoon of salt; They are unscientific and reek of all that is wrong with most developer benchmarks.

Having made that disclaimer,

Benchmark test:
this docker-compose file

Benchmark script:
for docker-compose:
docker ps -aq | xargs docker rm -f; docker system prune -af; /usr/bin/time -apv docker-compose up -d
for meli:
docker ps -aq | xargs docker rm -f; docker system prune -af; /usr/bin/time -apv meli -up -d

Benchmark results(average):

tool Elapsed wall clock time(seconds)
docker-compose 10.411 seconds
meli 3.945 seconds

Thus, meli appears to be 2.6 times faster than docker-compose(by wall clock time).
You can checkout the current benchmark results from circleCI
However, I'm not making a tool to take docker-compose to the races.

Development

Build

git clone git@github.com:komuw/meli.git
go build -o meli cli/cli.go
./meli -up -f /path/to/docker-compose-file.yml

debug

go build -o meli cli/cli.go
dlv exec ./meli -- -up -f testdata/docker-compose.yml
(dlv) help
(dlv) break cli/cli.go:246
(dlv) continue

TODO

  • add better documentation(godoc)
  • stabilise API(maybe)

Documentation

Overview

Package meli provides programming interface to interact with the docker daemon. meli also has a command line application(cli) that is a faster and drop in alternative to docker-compose. The installation instructions for the cli application can be found: https://github.com/komuw/meli#installingupgrading

Example usage:

package main

import (
"errors"
"github.com/sanity-io/litter"
"github.com/gogo/protobuf/vanity/command"
	"context"
	"log"
	"os"

	"github.com/docker/docker/client"
	"github.com/komuw/meli"
)

func main() {
	dc := &meli.DockerContainer{
		ComposeService: meli.ComposeService{Image: "busybox"},
		LogMedium:      os.Stdout,
		FollowLogs:     true}

	ctx := context.Background()
	cli, err := client.NewEnvClient()
	if err != nil {
		log.Fatal(err, " :unable to intialize docker client")
	}
	defer cli.Close()

	meli.LoadAuth() // read dockerhub info
	err = meli.PullDockerImage(ctx, cli, dc)
	log.Println(err)
}

Index

Constants

This section is empty.

Variables

View Source
var AuthInfo sync.Map

AuthInfo stores a users' docker registry/hub info

Functions

func BuildDockerImage

func BuildDockerImage(ctx context.Context, cli APIclient, dc *DockerContainer) (string, error)

BuildDockerImage builds a docker image via docker daemon

func ConnectNetwork

func ConnectNetwork(ctx context.Context, cli APIclient, dc *DockerContainer) error

ConnectNetwork connects a container to an existent docker network.

func ContainerLogs

func ContainerLogs(ctx context.Context, cli APIclient, dc *DockerContainer) error

ContainerLogs returns the logs generated by a container in an io.ReadCloser.

func ContainerStart

func ContainerStart(ctx context.Context, cli APIclient, dc *DockerContainer) error

ContainerStart starts a docker container via docker daemon server

func CreateContainer

func CreateContainer(ctx context.Context, cli APIclient, dc *DockerContainer) (bool, string, error)

CreateContainer creates a docker container

func CreateDockerVolume

func CreateDockerVolume(ctx context.Context, cli APIclient, name, driver string, dst io.Writer) (string, error)

CreateDockerVolume creates a docker volume

func GetNetwork

func GetNetwork(ctx context.Context, networkName string, cli APIclient) (string, error)

GetNetwork gets or creates newtwork(if it doesn't exist yet.)

func LoadAuth

func LoadAuth()

LoadAuth loads a users' docker registry/hub info into AuthInfo

func PullDockerImage

func PullDockerImage(ctx context.Context, cli APIclient, dc *DockerContainer) error

PullDockerImage pulls a docker from a registry via docker daemon

Types

type APIclient

type APIclient interface {
	// we implement this interface so that we can be able to mock it in tests
	// https://medium.com/@zach_4342/dependency-injection-in-golang-e587c69478a8
	ImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error)
	ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
	ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error)
	ContainerStart(ctx context.Context, containerID string, options types.ContainerStartOptions) error
	ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error)
	NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error)
	NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error)
	NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error
	VolumeCreate(ctx context.Context, options volume.VolumeCreateBody) (types.Volume, error)
	ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error)
	ContainerRemove(ctx context.Context, containerID string, options types.ContainerRemoveOptions) error
}

APIclient is meli's client to interact with the docker daemon server

type Buildstruct

type Buildstruct struct {
	// remember to use caps so that they can be exported
	Context    string `yaml:"context,omitempty"`
	Dockerfile string `yaml:"dockerfile,omitempty"`
}

Buildstruct represents a docker-compose' build section

type ComposeService

type ComposeService struct {
	Image       string      `yaml:"image,omitempty"`
	Ports       []string    `yaml:"ports,omitempty"`
	Labels      []string    `yaml:"labels,omitempty"`
	Environment []string    `yaml:"environment,omitempty"`
	Command     string      `yaml:"command,flow,omitempty"`
	Restart     string      `yaml:"restart,omitempty"`
	Build       Buildstruct `yaml:"build,omitempty"`
	Volumes     []string    `yaml:"volumes,omitempty"`
	Links       []string    `yaml:"links,omitempty"`
	EnvFile     []string    `yaml:"env_file,omitempty"`
}

ComposeService represents a docker-compose' service section

type DockerComposeConfig

type DockerComposeConfig struct {
	Version  string                    `yaml:"version,omitempty"`
	Services map[string]ComposeService `yaml:"services"`
	Volumes  map[string]string         `yaml:"volumes,omitempty"`
}

DockerComposeConfig represents a docker-compose file

type DockerContainer

type DockerContainer struct {
	ServiceName       string
	ComposeService    ComposeService
	NetworkID         string
	NetworkName       string
	FollowLogs        bool
	DockerComposeFile string
	ContainerID       string // this assumes that there can only be one container per docker-compose service
	LogMedium         io.Writer
	CurentDir         string
	Rebuild           bool
	EnvFile           []string
}

DockerContainer represents a docker container

func (*DockerContainer) UpdateContainerID

func (dc *DockerContainer) UpdateContainerID(containerID string)

UpdateContainerID updates a containers ID

Directories

Path Synopsis
Package main provides the command line interface for the meli application.
Package main provides the command line interface for the meli application.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL