Giter Club home page Giter Club logo

binci's Introduction

Travis Codecov NSP Status

Binci

Binci is a utility that allows you to easily containerize your development workflow using Docker. Simply put, it's like having a cleanroom for all of your development processes which contain services (like databases) without needing to setup and maintain these environments manually.


FAQ: Why Binci over Docker-Compose?

Installation

YARN/NPM

The best way to install Binci and keep it updated is through NPM, included with Node.js, or Yarn.

yarn global add binci or npm install binci -g


Obvious Note: You need to have Docker installed as well.

Important Note: In order to run the tasks, Binci creates a temp file (binci.sh). The tool will do its best to determine the best location (usually /tmp), but this can be explicitly set by specifying the environment variable BINCI_TMP.

Quick Start

After you have Binci installed you can initialize a project by moving to the project directory and running the following:

binci init

The above will prompt you to enter a base image; this should be a valid Docker image.

Once the configuration is generated you can run tasks. The default template includes several, for example:

binci env

The above will load your project via Binci & Docker, then echo the environment variables available.

Usage

Binci is controlled by a binci.yml file in the root of your project. A basic example is shown below:

from: node:6
services:
  - mongo:
      from: mongo:3.0
      env:
        - DB_ROOT_PASSWORD=foo
      expose:
        - 27017:27017
env:
  - TMP=${TMP}
  - HOST=${HOST:-localhost}
expose:
  - 8080:8080
volumes:
  - ${HOME}/.ssh:/root/.ssh
user: nobody
hosts:
  - google.com:127.0.0.1
before: npm install
after: echo "done"
tasks:
  env: env | sort
  start: node index.js
  lint: npm run lint
  test: npm test
  run: node index.js

The above can then be executed via the binci <task> command from within the same directory as your project and binci.yml. For example, binci run would perform the following:

  • Pull and start mongo with DB_ROOT_PASSWORD environment variable and port 27017 exposed
  • Sets the following on the container:
    • Set the primary container environment variable TMP to the same as the host machine
    • Expose port 8080 to the host system
    • Mount the host machine's .ssh directory in the container
    • Set a host entry for google.com to 127.0.0.1
  • Run npm install inside the container before running the task
  • Run node index.js task inside the container
  • Echo done after the task has completed

Custom Execution

Binci also allows for executing tasks not predefined in the configuration file using the -e flag. For example:

binci -e "/bin/sh"

The above would start the container using the configuration, call the before task, then start the sh shell. The container will then remain in the shell until an exit command is sent by the user.

Container Image (from <string> or dockerfile <string>)

The dockerfile configuration property can be specified to point to this project's Dockerfile, which will be auto-built for task execution. This image will be rebuilt any time the Dockerfile is edited. Defaults to ./Dockerfile.

The from configuration property causes Binci to use the specified image to run tasks, rather than building a new image from a local Dockerfile.

For testing different images easily, the either the -b <build-dockerfile> or -f <from-alternate-image> arguments can be passed on execution.

Tags (tags <Array<string>>)

If a dockerfile is being used rather than the from property, tags can be specified to define one or more tags to apply to any newly built container in addition to the default Binci tag. They can be specified in any format accepted by the docker build command's -t flag, such as repo/imageName:version.

dockerfile: ./Dockerfile
tags:
  - myorg/myrepo:latest
  - myorg/myrepo:5.1.0

The above binci.yml will, in the event that Binci needs to build a new container, tag the build with Binci's own tag in addition to the two listed tags. When Binci is done running, the command docker push myorg/myrepo:latest would work as expected.

Rebuilding

When a dockerfile is used, Binci will automatically rebuild it if the dockerfile changes. However, it may be necessary to trigger a rebuild when other files change that may impact the build. To list these files, specify rebuildOnChange:

dockerfile: ./Dockerfile
rebuildOnChange:
  - ./Gemfile
  - ./Gemfile.lock
  - ./Rakefile

When any of those files are changed, the next Binci run will rebuild the image from the dockerfile before executing the task.

Services

Services add links into the primary container, exposing the services for utilization. For the most part, services utilize the same format for definition as the primary container.

Container Naming

During execution, service containers are named in 2 ways:

  1. Ephemeral (non-persisted): bc_<NAME>_<INSTANCE-ID>
  2. Persisted: <NAME>

The above naming convention allows for persisted services to be shared with other Binci instances, or manually run docker containers, via the --link argument.

At startup Binci will ensure any persisted or already running containers are not started again.

After completion, Binci will run a detached process which will execute docker stop and docker rm on any non-persisted, ephemeral services.

Persisting Services

Services which need to persist between runs can be set by providing persist: true in their configurations.

Persisted services will not stop after the primary container finishes its task and can be used by the same project, other projects, or independently.

Disabling Services

By default, all services in the configuration will be linked on any run. To disable services for specific tasks, you can define them like this:

tasks:
  lint:
    disable:
      - mongo
    cmd: npm run lint
  start: npm start

Alternatively, you can disable all services for a task with '*':

tasks:
  lint:
    disable: "*"
    cmd: npm run lint
  start: npm start

For one-off cases, individual services can also be disabled via the command line:

binci lint -d mongo

or all services:

binci lint -d '*'
binci lint --disable-all

Container Management

Binci will automatically stop services after any run (success or fail). However, if this fails or some other fringe-case causes this process to stop responding the system can leave orphaned containers running.

In order to mitigate this issue Binci will run a check for any bc_ prefixed containers on each run. If orphaned services are identified a warning message will appear at the beginning of the process to indicate the orphaned service(s) and commands to remedy/exit these containers.

The following commands can be run to cleanup any running containers:

Stop and Remove Binci Containers:

binci --cleanup

Stop and Remove ALL Containers:

binci --cleanup-all

Environment Variables (env <array>)

Setting env array items will expose environment variables in the primary instance or services. These entries can be raw strings or use ${VAR} notation, where VAR is an environment variable on the host machine to use. Entries should use the format <ENV_VAR>=<VALUE>.

You can provide default values for environment variables by using the standard bash syntax. For example, VAR=${FOO:-foobar} will first look for the FOO environment variable, and if it is not defined VAR will be set to the string foobar (i.e. VAR=foobar).

Expose (expose <array>)

Setting expose array items will expose ports to the host machine from the primary or service containers. Entries should use the format <CONTAINER_PORT>:<HOST_PORT>

Volumes (volumes <array>)

Setting volumes will mount volumes on the host machine to designated paths on the primary or service containers. Entries should use the format <HOST_PATH>:<CONTAINER_PATH>

The current working directory will automatically mount to the same path on the container instance by default. To change its mount point and the working directory, specify the workDir parameter at the top level.

Users (user <string>)

Setting user will instruct the container to run under the username or UID specified.

Hosts (hosts <array>)

Setting hosts will update the hosts configuration for the container. Entries should use the format <HOST_NAME>:<ADDRESS>

Privileged (privileged <boolean>)

By default binci uses Docker's --privileged flag to run, you can disable by setting this in the config or passing --privileged=false in the binci command.

Service Stop Time (stopTimeSecs <integer>)

The standard procedure for stopping a Docker container is the stop command which sends SIGTERM and allows a grace period (default: 10) for the container to exit on its own.

Some containers may not exit via SIGTERM (or may hang). In this case, the service container can utilize the stopTimeSecs property:

services:
  - mongo:
      from: mongo:3.0
      stopTimeSecs: 3

The stopTimeSecs above would forcibly stop the container after 3 seconds using Docker's stop command's -t option.

Global Setting:

In addition to setting the stopTimeSecs per service, this property can be set in the root of the binci.yml configuration and will be applied to any services that don't have an explicit stopTimeSecs property.

Service Command (command <string|Array>)

In the event that a service's default command needs to be overridden, the command property can do that. Specify the command with a string or array of strings.

Development

Tests

Binci can be run via yarn/npm scripts, but is also setup to run development tasks using Binci.

Ensure you have the latest version installed then run:

binci install test or yarn install && yarn test.

End-to-End Tests

To run end-to-end tests run yarn run e2e. This works by fully emulating a run inside the /test/project directory and executing /test/system/run.js with the /test/system/tests.json definitions file.

Testing Builds

To test binary builds:

1. Build Binary:

yarn run build:linux

2. Run (Ubuntu) Docker in Docker:

docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock -v $PWD:/app -w /app ubuntu sh -c "apt-get update && apt-get install docker.io -y && bash"

3. Create Binci Alias:

alias binci=$PWD/bin/linux/binci

Once the above steps are completed the binci executable will be available.

Why Binci Over Docker Compose?

First off, we like Docker Compose, and definitely think it's a powerful tool. However, Binci was built because Compose is more about long-running, containerized environment and what we set out to build was a way to run ephemeral, limited-lifespan tasks without having to manage cleanup between each run.

Compose takes the approach of spinning up containers that run, almost like a virtual machine, while you need them. Binci looks at things from a point of view of abstracting docker run command chains to create a single-run instance only for that task, then shutting down and doing cleanup so each run is clean and running off a consistent base.

Some more comparisons:

  • With Binci you don't need a Dockerfile for local development, thus you can use it whether or not your project will be deployed in Docker or to bare metal.
  • Binci only builds Docker images if you want it to. Specifying an image in the config will run all tasks off of that image without ever building a local one first.
  • When you install local dependencies in your project folder, run a build, execute your coverage tool, or write any local files, that just happens on your hard disk, not locked away in some container. They'll be available to every other task you run.
  • With Binci you don't need to run tasks in a containerized shell, you simply define the tasks and run them. You can kick tasks off with any local script, build tool, or IDE run configuration without building a container first.
  • Tasks don't need to be defined at runtime via arguments or flags, you just tell Binci which predefined task to run.

License

Binci is licensed under the MIT license. Please see LICENSE.txt for full details.

Credits

Binci was originally created at TechnologyAdvice in Nashville, TN.

binci's People

Contributors

brandonros avatar jordandenison avatar ksafranski avatar levithomason avatar polpetta avatar psvet avatar svetkomir avatar tomfrost avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

binci's Issues

Node 4+ Support

Remove Babel and use only ES6/2015 as supported by Node v4+

Disable services (opt-out) by task

Allow task definitions to explicitly define unneeded services:

services:
  - mongodb:
    from: mongo:3.0
tasks:
  lint:
    disable:
      - mongodb
    cmd: npm run lint

Warn of orphaned services

With refactor (#33), service shutdown is now detached and, in turn, does not report a service stop or rm call failure.

Add utility that runs on startup and compares current instanceId to running containers reported in docker ps, then looks for (and reports) orphans based on name and missing parent container.

Add Multi-Task Run

Add the ability to run multiple tasks in one command.

Proposed approach:

tasks:
    install: npm install
    lint: npm run lint
    test: npm test
    all: $install $lint $test

The above all would start the container and any linked services + setup, then run install, lint, and test

Fail to start service

Tried to do the following

services:
  - mysql:
      from: mysql:latest
      ports:
          - '3306:3306'
      volumes:
          - ./mysql:/var/lib/mysql
      environment:
          - MYSQL_ROOT_PASSWORD=aqwe123
      restart: always
  # - nginx:
  #     from: nginx:latest
  #     ports:
  #         - '80:80'
  #     volumes:
  #         - ./nginx:/etc/nginx/conf.d
  #         - ./logs/nginx:/var/log/nginx
  #         - ./wordpress:/var/www/html
  #     links:
  #         - wordpress
  #     restart: always
  - wordpress:
      from: wordpress:4.8.0-php5.6-fpm
      ports:
          - '9000:9000'
      volumes:
          - ./wordpress:/var/www/html
      environment:
          - WORDPRESS_DB_NAME=wpdb
          - WORDPRESS_TABLE_PREFIX=wp_
          - WORDPRESS_DB_HOST=mysql
          - WORDPRESS_DB_PASSWORD=aqwe123
      links:
          - mysql
      restart: always
expose:
   - 8000:8000
   - 3306:3306
   - 9000:9000
from: nginx:latest
ports:
    - '8000:8000'
volumes:
    - ./nginx:/etc/nginx/conf.d
    - ./logs/nginx:/var/log/nginx
    - ./wordpress:/var/www/html
hosts:
  - 192.168.99.100:127.0.0.1
before:
  - echo "before..."
after:
  - echo "after..."
tasks:
  env: env | sort
  # shell: /bin/bash
  # run: "nginx -g daemon off;"

kept getting

Failed to start service wordpress for some reason

While using a docker-compose.yml worked

Improve UX Symmetry between Zombie Container Warning and Cleanup

When starting a task, binci warns the user if there are any zombie containers that were not torn down correctly; it then suggests running --cleanup to remove them. The information given to the user, however, is different between the warning and cleanup: the warning displays the container name, but cleanup shows the container id. It would be awesome if we could make two small tweaks to make this more consistent:

  1. Use the same identifier between the warning and cleanup task.
  2. Make formatting consistent between the warning and cleanup task (one is comma-separated, the other is newline-separated).

Here's an example of what the users sees now:

screen shot 2017-06-12 at 12 52 21 pm

Build up of containers eventually chokes system resources

After running several lab tasks throughout the day, the containers started by DevLab build up over time. These eventually turn my fans into rocket ships and start choking my system:

I find I have to restart docker periodically to reclaim system performance and settle my fans. It would be grand if we could find a way to reliably kill off these containers after using them.

If we know they are running, can we spawn a child process to kill them instead of logging that they are still running?

Container Log Output

Stream both service(s) and primary container output to log files in .devlab_logs/%service_name%. Use log retention limits with config setting (by service) for log_max_size (default 1Mb).

Add `exec` to service config

Add ability to specify an exec to run when the (to be) linked service is started:

services:
  - mongo:3.0:
      name: mongodb
      env:
        - DB_ROOT_PASSWORD=foo
      expose:
        - 27017:27017
      persist: false
      exec: |
        some command

Default tasks

Seems laminar is intended to be pretty transparent, which is great. What about defaulting the tasks to npm, gulp, and make tasks? Not sure how priority would be determined but it seems like an easy win.

Federating connected services

If projects are connected by path (see issue #28) they could have common services they (could) share.

From internal discussion:

my thought here is simply better container naming system, then let the naming guide federation, i.e. check for a container by name xyz and link if it exists, else create - it's simple but it's conservative and less to manage, then layer that with better output so if you have multiple services that aren't named the same (and not federating) it's very obvious 1. that it's happening and 2. how to fix it. I was thinking about it and I don't want to be to assumptive, and here's my case: we use postgres:8 to emulate redshift, but what if we also want to have postgres running as well (postgres:latest), assumptive federating there could/would break shit whereas simply naming services as you naturally would (redshift v. postgres) tells a better story of how to connect things

Sharing services

from: foo/node-dev:5
services:
  - vault:
      from: foo/node-vault-dev:latest
      env:
        - VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200
      expose:
        - 8200:8200
  - db:
      from: registry.hub.docker.com/library/postgres:latest
      env:
        - POSTGRES_PASSWORD=example
      expose:
        - 5432:5432

It isn't clear in the documentation how to share the exposed 5432 port from the postgres service to the vault service. Is this currently possible? If so, how?

The source path doesn't exist and is not known to Docker.

PS C:\GitHub\test-windows\node-sso-formatter> binci dev
√ Starting services vault, db
√ Running Task
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
docker: Error response from daemon: Mount denied:
The source path "C:/Users/snikolov/AppData/Local/Temp:C"
doesn't exist and is not known to Docker.
See 'docker run --help'.
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
× Command failed
PS C:\GitHub\test-windows\node-sso-formatter>

I added a console.log(args) right before https://github.com/binci/binci/blob/master/src/proc.js#L17 and we're looking at

[ 'run',
  '--rm',
  '-v',
  '/C/GitHub/test-windows/node-sso-formatter:/C/GitHub/test-windows/node-sso-formatter:cached',
  '-v',
  '/Users/snikolov/AppData/Local/Temp:/Users/snikolov/AppData/Local/Temp',
  '-w',
  '/C/GitHub/test-windows/node-sso-formatter',
  '--privileged',
  '-it',
 ...
  '-p',
  '8080:8080',
  '-p',
  '9090:9090',
  '--link',
  'bc_vault_1QjhthmQq:vault',
  '--link',
  'bc_db_1QjhthmQq:db',
  '--name',
  'bc_primary_1QjhthmQq',
  'registry.banno-internal.com/node-dev:8',
  'sh',
  '/Users/snikolov/AppData/Local/Temp/binci.sh' ]

Custom Order in Starting or avoiding paralelling

Hi,

I've a question due to the new version v3 that you can gently help me.
We're trying to start a custom container that have some dependencies with other services (databases) in same devlab.yml . In the past, we were using "link" tag and the order of the containers executions was sequentially, so there was no dependencies problem.

Is there something that changed in the new version that I have into account in order to manage this issue?

A little sample could be:

from: mhart/alpine-node:latest
services:
  - elasticsearch:
      from: elasticsearch:2.3.0
      persist: false
      expose:
  - mycontainer:
      from: myservice:latest
      persist: false
      link:
        - elasticsearch
      expose:
        - 9000:9000
expose:
  - 7000:7000
  - 5858:5858
env:
  - LOCAL_HOME=${HOME}
forward: true
before: echo "Waiting for services startup" && sleep 10
tasks:
  env: env
  install: npm install
  start: npm start

Many thanks in advance,
Manuel

If persistence is on, DevLab doesn't reconnect to an existing mongodb container.

If I try to use DevLab with a persistent Mongodb it doesn't work. It seems to not stop the running Container when I quit the current task.

Error response from daemon: Cannot start container 7fd10af6ac5bf34a53d7a7cf525dc0673457b76cf082d1461ca4f8f5a5354b03: failed to create endpoint devlab_mongodb_username_1447779638533 on network bridge: Bind for 0.0.0.0:27017 failed: port is already allocated

Unite service (link) and primary container load

Currently services are started via the services lib with a limited set of passable commands and config options. Instead of this pattern, unite with the primary container startup and create a loader which loads both services and the primary container identically, the only difference being the links created in the primary container.

This not only simplifies the startup process and should allow for parallelizing load but also means services will have the same configuration and task abilities.

Command to view all tasks

npm run lists all scripts available in package.json. I often want to list all tasks available to lab. Is there a way to do this? If not, I'd propose something like lab tasks to view all tasks.

Change name from Devlab to Binci

Summary

In order to establish a more unique brand and prevent any conflicts with further development in the future, the decision has been made to rename/rebrand Devlab to Binci. In order to maintain commit, issue, and release histories this will occur via a migration of this repository to the new Binci organization.

Current Devlab Implementations

In order to make this transition low-impact the current Devlab npm namespace will be retained for the foreseeable future, giving anyone using this application time to migrate.

Requirements:

  • Create new organization
  • Retain namespace on npm and secure domain name (bin.ci)
  • Update documentation
  • Update codebase and tests using new conventions and naming
  • Update binary deploy location (http://binci.technologyadvice.com)
  • Update Travis integration and deployments
  • Update Codecov reporting

Move Away from update-notifier

update-notifier has a transient security risk as it eventually uses an old version of got

Sadly, to update to the newest version, you'd have to move to esm.
See: https://github.com/yeoman/update-notifier/releases/tag/v6.0.0

I'm personally fine using it without any update-notifier at all.

But if one is desired, you could follow in the footsteps of nodemon and switch to simple-update-notifier which has far less dependencies. (See: remy/nodemon#2033)

I'm happy to help with a PR for either change but would like a maintainers approval and direction first.

Better BINCI_TMP resolution on Windows?

PS C:\github\test-windows\node-sso-formatter> binci
√ Starting services vault, db
√ Running Task
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
sh: can't open '/tmp/binci.sh': No such file or directory
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
× Command failed
PS C:\github\test-windows\node-sso-formatter>

Not quite what I'd expect. What other information can I give to help debug this? cc @svetkomir

Consider More Graceful Config Validation

For example:

  • Binci currently won't run if env is empty. What if I don't have any env vars to set?
  • Binci currently won't run if expose is empty. What if I don't need to expose anything?

TypeError: Incorrect value for stdio stream: inherit

Hi,

I followed the README, and cloned the demo app.

However, when I run 'lab install', I run into the following error - everytime.

> Starting service devlab_mongodb_puretech_1446502746915


!> Failed to start devlab_mongodb_puretech_1446502746915
!> TypeError: Incorrect value for stdio stream: inherit
!> Error running npm run test;, exited with code 1

> Stoping service: devlab_mongodb_puretech_1446502746915

Can you please help with this issue. I am running this on Koding.com

Refactor

After review of desired features and refactoring required to achieve them a rewrite of the core libs has been decided as the best approach. This rewrite will maintain all existing features while also addressing:

  • Improved output, stream to log files per service
  • Unification/standardization of both services and primary container
  • Improved service naming conventions
  • Improved testing and increased coverage
  • Asynchronous service loading
  • Functional code

The above represents the initial goals but this list may change during refactor. The end result of this refactor will be release of v3.

Recommendation for replicating the host UID/GID in containers

What is the recommended way to ensure that host's UID and GID gets used in container without hardcoding the values in Dockerfile ?

I am attempting to use lein to scaffold a project with binci -e but generated files are owned by root by default and are not editable on host os where I run my editor.

Unlike docker CLI, binci doesn't accept --user and I also don't see a way to pass build args.

Given this is a development utility, would you consider having a simple way to ensure that host's UID/GID gets used in container ?

Dump Logs from Failing Service Start

Currently when a service startup fails or a link cannot be completed the process simply exits with no explanation of the error. Need to dump any error messages so problem can be triaged and corrected.

Mapping volumes from primary containers to service containers

I'm trying to understand how to use binci but wanted to find out bout the volumes for the primary docker container and the service containers

to explain my dilemma...

I am trying to put together a wordpress development server where I need the following

1 Need a php server for wordpress
2 Need a mysql server
3 Want a nodejs server for theme development

For items 1 and 3 I want to be able to share " a particular volume" in the docker-compose way I'd simply reference the container and all volumes would be used. However I'm trying to see if I can share just a "specific" volume

In come binci If i created the 3 services would binci be able to distributor the specific volume to the 2 containers? How does the volumes for the primary server relate to the service container volumes?

Service naming/config change

The example shows

services:
  - mongodb:mongo

as a way to provide a name for the chosen service. Two issues there:

  • The syntax used is the standard syntax for choosing a tag, so it's unintuitive
  • We're not providing a way to choose tag

So I suggest we allow this...

services:
  - mongodb

or this

services:
  - mongodb:3.0

As well as this:

services:
  - mongodb:3.0:
      name: mymongo  # Defaults to projectname_mongodb_3.0 if not specified
      repo: quay.io/yadda  # Defaults to standard docker hub
      auth: blahblah  # defaults to public access
      env:
        DB_ROOT_PASSWORD: testing123 # many services require their own envs to set things like this up, defaults to no additional envs
      exec: |
        # a script to run after the box stands up. Allows us to bootstrap schemas into a DB or something.
        # This is a HUGE feature that not even Wercker supports, but we could, and it would work in dev and test.
      persist: false # Default true. Specifies whether or not the box is torn down and re-created with each run.

Running multiple tasks for multiple containers

Is the "tasks" related to the service container? or is it related to "binci" related services? I ask this because I have a service with where i need to run specific commands for php and node simultaneously. does the task initiate those commands for me?

after services started hook

I use Binci to launch a Docker image that exposes a CMD that is a daemon. I have found the need to run shell commands against the container once it has come alive. Since the docker container name is some form of bc_serviceName_randomLetters, I'm stuck pretty much using grep/sed/awk to figure out which container I want to attach + run commands to.

Would this be an easy configuration option to add?

afterServicesStarted:
  containerName:
    - touch magicFile

Add ability to override default `stop` grace period

As some (service) containers seem to hang, or ignore the SIGTERM sent to PID 1 by docker stop completely, add ability to specify grace period for services:

  - container:
      from: some/image:tag
      stopTimeSecs: <n>

n would be an integer representing number of seconds before forcing shutdown with SIGKILL. If not specified would default to Docker's default of 10.

Ability to change user from root to nobody

USER nobody
EXPOSE 8080 9090
ENTRYPOINT [ "node", "--max-http-header-size", "65536", "/app/dist/index.js" ]

Something like this is the Dockerfile equivalent. Is this possible with binci?

DevLab in Windows "Invalid bind mount spec"

Running Windows 10 Pro, Docker 1.12.5, and DevLab 3.1.1.

I get an error when attempting to start containers with DevLab in Windows (from cmd, git bash, or powershell). I have shared the C: drive.

Here's the output error (personal info substituted with asterisks):

> lab install

√ Starting services rabbitmq, postgres
√ Running command: env
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
docker: Error response from daemon: Invalid bind mount spec "/C/Users/****/server:C:\\Users\\****\\server": invalid mode: \Users\****\server.
See 'docker run --help'.
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
× Command failed

Here's my config file:

from: busybox
services:
  - rabbitmq:
      from: gonkulatorlabs/rabbitmq
      expose:
        - 5672:5672
  - postgres:
        from: kiasaki/alpine-postgres
        env:
          - POSTGRES_USER=postgres
          - POSTGRES_PASSWORD=password
          - POSTGRES_DB=dev
        expose:
          - 5432:5432
expose:
  - 9000:9000
quiet: false
forward: true
tasks:
  env: env
  clean: npm run clean
  install: env
  test: npm run test
  lint: npm run lint
  build: npm run build
  start: npm start
  ci: |
    npm run lint 
    npm run test 
    npm run build

I can't tell for sure, but it seems like there is a problem with msys path conversion with docker, but I can't (or don't know how to) control what's passed to docker while using DevLab. I know there are some workarounds recommended with docker (a seemingly related issue) but I'm not sure how I'd implement these suggestions when DevLab is executing the Docker commands. I'm new to DevLab and Docker, so I apologize if I'm way off the mark here.

Docker Version Check, Automatic --rm Handling

Docker versions less than 1.13.0 did not support -d and --rm together for service containers. We have been (and I just restored with #63) an environment variable to manually set this.

Better plan: on start do a version check of Docker. This serves 2 purposes:

  1. Is docker even installed? Should throw, it's kinda a big deal
  2. Is it greater than or equal to 1.13? If not we can pull the --rm and move it to service shutdown.

Remove temp devlab.sh immediately upon execution

The feature added in 3.3.3 which creates a temp devlab.sh to run the commands from the task currently waits until ALL execution is finished to remove the file. This means that if the task errors the file doesn't get removed.

Need to have the devlab.sh file removed immediately after it is executed to prevent issues with overwrites/permissions or accidentally committing the file to version control.

Link services via path to (external) devlab project

Ability to specify a service via path + task, i.e.:

services:
    - restapi:
        path: /projects/restapi
        task: run

Additionally, path should support environment variables to allow dynamic paths based on user's local config, for example: path: $RESTAPI_PATH

Cleanup service naming convention

Currently uses %USER%_%SVC%_%TIMESTAMP% convention, this should be controllable through the config and by default much more concise.

Docker Desktop 3.3.0 broke binci

Reproduction:

binci.yml

from: registry.hub.docker.com/library/node:lts
services:
  - db:
      from: registry.hub.docker.com/library/postgres:latest
      env:
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=example
        - POSTGRES_DB=db
      expose:
        - 5432:5432
tasks:
  hello: echo hello
$ binci hello
✔ Starting service db
✔ Running Task
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
docker: Error response from daemon: Cannot link to a non running container: /bc_db_HDQxOObjp AS /bc_primary_HDQxOObjp/db.
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
✖ Command failed

Log some output when pulling new service images

Either by capturing Docker's output, or adding other focused spinner messages. The first time running a task with all new services, it's hard to tell if it's actually working because all that's visible for however long it takes to pull the images and spin up (which can be long) is Starting services ....

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.