{"id":13416556,"url":"https://github.com/binci/binci","last_synced_at":"2025-05-16T05:04:14.692Z","repository":{"id":21534827,"uuid":"43073069","full_name":"binci/binci","owner":"binci","description":":whale: Containerize your development workflow.","archived":false,"fork":false,"pushed_at":"2022-12-06T20:24:40.000Z","size":1849,"stargazers_count":672,"open_issues_count":15,"forks_count":26,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-05-16T05:04:07.457Z","etag":null,"topics":["cli","containers","continuous-integration","docker","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/binci.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-24T14:48:21.000Z","updated_at":"2025-05-10T19:37:22.000Z","dependencies_parsed_at":"2023-01-13T21:32:48.539Z","dependency_job_id":null,"html_url":"https://github.com/binci/binci","commit_stats":null,"previous_names":["technologyadvice/devlab"],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binci%2Fbinci","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binci%2Fbinci/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binci%2Fbinci/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binci%2Fbinci/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/binci","download_url":"https://codeload.github.com/binci/binci/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254471061,"owners_count":22076585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","containers","continuous-integration","docker","nodejs"],"created_at":"2024-07-30T21:01:00.795Z","updated_at":"2025-05-16T05:04:14.671Z","avatar_url":"https://github.com/binci.png","language":"JavaScript","readme":"[![Travis](https://travis-ci.org/binci/binci.svg?branch=master)](https://travis-ci.org/binci/binci)\r\n[![Codecov](https://codecov.io/gh/binci/binci/branch/master/graph/badge.svg)](https://codecov.io/gh/Binci/binci)\r\n[![NSP Status](https://nodesecurity.io/orgs/binci/projects/cbac1faf-7c38-41f1-b648-1b4c8dfd8f02/badge)](https://nodesecurity.io/orgs/binci/projects/cbac1faf-7c38-41f1-b648-1b4c8dfd8f02)\r\n\r\n\u003cimg src=\"./binci.png\" align=\"right\"\u003e\r\n\r\n# Binci\r\n\r\nBinci is a utility that allows you to easily containerize your development\r\nworkflow using Docker. Simply put, it's like having a cleanroom for all of your\r\ndevelopment processes which contain services (like databases) without needing\r\nto setup and maintain these environments manually.\r\n\r\n---\r\n\r\n\u003cimg width=\"100%\" src=\"http://i.imgur.com/4NOBeYU.gif\"\u003e\r\n\r\n**FAQ: [Why Binci over Docker-Compose?](#why-binci-over-docker-compose)**\r\n\r\n## Installation\r\n\r\n### YARN/NPM\r\n\r\nThe best way to install Binci and keep it updated is through NPM, included with [Node.js](https://nodejs.org), or Yarn.\r\n\r\n`yarn global add binci` or `npm install binci -g`\r\n\r\n---\r\n\r\n_Obvious Note: You need to have [Docker](https://www.docker.com/) installed as well._\r\n\r\n**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`.\r\n\r\n## Quick Start\r\n\r\nAfter you have Binci installed you can initialize a project by moving to the project directory and running the following:\r\n\r\n```\r\nbinci init\r\n```\r\n\r\nThe above will prompt you to enter a base image; this should be a valid Docker image.\r\n\r\nOnce the configuration is generated you can run tasks. The default template includes several, for example:\r\n\r\n```\r\nbinci env\r\n```\r\n\r\nThe above will load your project via Binci \u0026 Docker, then echo the environment variables available.\r\n\r\n## Usage\r\n\r\nBinci is controlled by a `binci.yml` file in the root of your project. A basic example is shown below:\r\n\r\n```yaml\r\nfrom: node:6\r\nservices:\r\n  - mongo:\r\n      from: mongo:3.0\r\n      env:\r\n        - DB_ROOT_PASSWORD=foo\r\n      expose:\r\n        - 27017:27017\r\nenv:\r\n  - TMP=${TMP}\r\n  - HOST=${HOST:-localhost}\r\nexpose:\r\n  - 8080:8080\r\nvolumes:\r\n  - ${HOME}/.ssh:/root/.ssh\r\nuser: nobody\r\nhosts:\r\n  - google.com:127.0.0.1\r\nbefore: npm install\r\nafter: echo \"done\"\r\ntasks:\r\n  env: env | sort\r\n  start: node index.js\r\n  lint: npm run lint\r\n  test: npm test\r\n  run: node index.js\r\n```\r\n\r\nThe above can then be executed via the `binci \u003ctask\u003e` command from within the same directory as your project and `binci.yml`. For example, `binci run` would perform the following:\r\n\r\n- Pull and start `mongo` with `DB_ROOT_PASSWORD` environment variable and port `27017` exposed\r\n- Sets the following on the container:\r\n  - Set the primary container environment variable `TMP` to the same as the host machine\r\n  - Expose port `8080` to the host system\r\n  - Mount the host machine's `.ssh` directory in the container\r\n  - Set a host entry for `google.com` to `127.0.0.1`\r\n- Run `npm install` inside the container before running the task\r\n- Run `node index.js` task inside the container\r\n- Echo `done` after the task has completed\r\n\r\n### Custom Execution\r\n\r\nBinci also allows for executing tasks not predefined in the configuration file using the `-e` flag. For example:\r\n\r\n```\r\nbinci -e \"/bin/sh\"\r\n```\r\n\r\nThe 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.\r\n\r\n## Container Image (`from \u003cstring\u003e` or `dockerfile \u003cstring\u003e`)\r\n\r\nThe `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`.\r\n\r\nThe `from` configuration property causes Binci to use the specified image to run tasks, rather than building a new image from a local Dockerfile.\r\n\r\nFor testing different images easily, the either the `-b \u003cbuild-dockerfile\u003e` or `-f \u003cfrom-alternate-image\u003e` arguments can be passed on execution.\r\n\r\n## Tags (`tags \u003cArray\u003cstring\u003e\u003e`)\r\n\r\nIf 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`.\r\n\r\n```yaml\r\ndockerfile: ./Dockerfile\r\ntags:\r\n  - myorg/myrepo:latest\r\n  - myorg/myrepo:5.1.0\r\n```\r\n\r\nThe above binci.yml will, in the event that Binci needs to build a new container, tag the build with Binci's own tag in\r\naddition to the two listed tags. When Binci is done running, the command `docker push myorg/myrepo:latest` would work\r\nas expected.\r\n\r\n## Rebuilding\r\n\r\nWhen 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`:\r\n\r\n```yaml\r\ndockerfile: ./Dockerfile\r\nrebuildOnChange:\r\n  - ./Gemfile\r\n  - ./Gemfile.lock\r\n  - ./Rakefile\r\n```\r\n\r\nWhen any of those files are changed, the next Binci run will rebuild the image from the dockerfile before executing the task.\r\n\r\n## Services\r\n\r\nServices 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.\r\n\r\n### Container Naming\r\n\r\nDuring execution, service containers are named in 2 ways:\r\n\r\n1. Ephemeral (non-persisted): `bc_\u003cNAME\u003e_\u003cINSTANCE-ID\u003e`\r\n2. Persisted: `\u003cNAME\u003e`\r\n\r\nThe above naming convention allows for persisted services to be shared with other Binci instances, or manually run docker containers, via the `--link` argument.\r\n\r\nAt startup Binci will ensure any persisted or already running containers are not started again.\r\n\r\nAfter completion, Binci will run a detached process which will execute `docker stop` and `docker rm` on any non-persisted, ephemeral services.\r\n\r\n### Persisting Services\r\n\r\nServices which need to persist between runs can be set by providing `persist: true` in their configurations.\r\n\r\nPersisted services will not stop after the primary container finishes its task and can be used by the same project, other projects, or independently.\r\n\r\n### Disabling Services\r\n\r\nBy default, all services in the configuration will be linked on any run. To disable services for specific tasks, you can define them like this:\r\n\r\n```yaml\r\ntasks:\r\n  lint:\r\n    disable:\r\n      - mongo\r\n    cmd: npm run lint\r\n  start: npm start\r\n```\r\n\r\nAlternatively, you can disable all services for a task with `'*'`:\r\n\r\n```yaml\r\ntasks:\r\n  lint:\r\n    disable: \"*\"\r\n    cmd: npm run lint\r\n  start: npm start\r\n```\r\n\r\nFor one-off cases, individual services can also be disabled via the command line:\r\n\r\n```\r\nbinci lint -d mongo\r\n```\r\n\r\nor all services:\r\n\r\n```\r\nbinci lint -d '*'\r\nbinci lint --disable-all\r\n```\r\n\r\n## Container Management\r\n\r\nBinci 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.\r\n\r\nIn 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.\r\n\r\nThe following commands can be run to cleanup any running containers:\r\n\r\n**Stop and Remove Binci Containers:**\r\n\r\n```\r\nbinci --cleanup\r\n```\r\n\r\n**Stop and Remove ALL Containers:**\r\n\r\n```\r\nbinci --cleanup-all\r\n```\r\n\r\n## Environment Variables (`env \u003carray\u003e`)\r\n\r\nSetting `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 `\u003cENV_VAR\u003e=\u003cVALUE\u003e`.\r\n\r\nYou 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`).\r\n\r\n## Expose (`expose \u003carray\u003e`)\r\n\r\nSetting `expose` array items will expose ports to the host machine from the primary or service containers. Entries should use the format `\u003cCONTAINER_PORT\u003e:\u003cHOST_PORT\u003e`\r\n\r\n## Volumes (`volumes \u003carray\u003e`)\r\n\r\nSetting `volumes` will mount volumes on the host machine to designated paths on the primary or service containers. Entries should use the format `\u003cHOST_PATH\u003e:\u003cCONTAINER_PATH\u003e`\r\n\r\nThe 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.\r\n\r\n## Users (`user \u003cstring\u003e`)\r\n\r\nSetting `user` will instruct the container to run under the username or UID specified.\r\n\r\n## Hosts (`hosts \u003carray\u003e`)\r\n\r\nSetting `hosts` will update the hosts configuration for the container. Entries should use the format `\u003cHOST_NAME\u003e:\u003cADDRESS\u003e`\r\n\r\n## Privileged (`privileged \u003cboolean\u003e`)\r\n\r\nBy 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.\r\n\r\n## Service Stop Time (`stopTimeSecs \u003cinteger\u003e`)\r\n\r\nThe 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.\r\n\r\nSome containers may not exit via `SIGTERM` (or may hang). In this case, the service container can utilize the `stopTimeSecs` property:\r\n\r\n```yaml\r\nservices:\r\n  - mongo:\r\n      from: mongo:3.0\r\n      stopTimeSecs: 3\r\n```\r\n\r\nThe `stopTimeSecs` above would forcibly stop the container after 3 seconds using [Docker's `stop` command's `-t` option](https://docs.docker.com/engine/reference/commandline/stop/).\r\n\r\n**Global Setting:**\r\n\r\nIn 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.\r\n\r\n## Service Command (`command \u003cstring|Array\u003e`)\r\n\r\nIn 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.\r\n\r\n## Development\r\n\r\n### Tests\r\n\r\nBinci can be run via `yarn`/`npm` scripts, but is also setup to run development tasks using Binci.\r\n\r\nEnsure you have the latest version installed then run:\r\n\r\n`binci install test` or `yarn install \u0026\u0026 yarn test`.\r\n\r\n### End-to-End Tests\r\n\r\nTo 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.\r\n\r\n### Testing Builds\r\n\r\nTo test binary builds:\r\n\r\n**1. Build Binary:**\r\n\r\n```\r\nyarn run build:linux\r\n```\r\n\r\n**2. Run (Ubuntu) Docker in Docker:**\r\n\r\n```\r\ndocker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock -v $PWD:/app -w /app ubuntu sh -c \"apt-get update \u0026\u0026 apt-get install docker.io -y \u0026\u0026 bash\"\r\n```\r\n\r\n**3. Create Binci Alias:**\r\n\r\n```\r\nalias binci=$PWD/bin/linux/binci\r\n```\r\n\r\nOnce the above steps are completed the `binci` executable will be available.\r\n\r\n## Why Binci Over Docker Compose?\r\n\r\nFirst off, we like [Docker Compose](https://docs.docker.com/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.\r\n\r\nCompose 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.\r\n\r\nSome more comparisons:\r\n\r\n- 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.\r\n- 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.\r\n- 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.\r\n- 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.\r\n- Tasks don't need to be defined at runtime via arguments or flags, you just tell Binci which predefined task to run.\r\n\r\n## License\r\n\r\nBinci is licensed under the MIT license. Please see [`LICENSE.txt`](/LICENSE.txt) for full details.\r\n\r\n## Credits\r\n\r\nBinci was originally created at [TechnologyAdvice](http://www.technologyadvice.com) in Nashville, TN.\r\n","funding_links":[],"categories":["Development with Docker","Systems/Software Development","JavaScript","nodejs","cli"],"sub_categories":["Development Environment","CI/CD"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinci%2Fbinci","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinci%2Fbinci","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinci%2Fbinci/lists"}