{"id":13452387,"url":"https://github.com/faradayio/cage","last_synced_at":"2025-04-12T22:34:28.439Z","repository":{"id":10804218,"uuid":"67065137","full_name":"faradayio/cage","owner":"faradayio","description":"Develop and deploy complex Docker applications","archived":false,"fork":false,"pushed_at":"2023-02-04T01:03:35.000Z","size":12526,"stargazers_count":309,"open_issues_count":43,"forks_count":26,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-04T02:06:21.474Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://cage.faraday.io","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/faradayio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-31T18:59:13.000Z","updated_at":"2025-02-11T14:49:22.000Z","dependencies_parsed_at":"2023-01-13T16:24:45.682Z","dependency_job_id":null,"html_url":"https://github.com/faradayio/cage","commit_stats":null,"previous_names":["faradayio/conductor"],"tags_count":53,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faradayio%2Fcage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faradayio%2Fcage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faradayio%2Fcage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faradayio%2Fcage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/faradayio","download_url":"https://codeload.github.com/faradayio/cage/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248640782,"owners_count":21138093,"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":[],"created_at":"2024-07-31T07:01:22.679Z","updated_at":"2025-04-12T22:34:28.414Z","avatar_url":"https://github.com/faradayio.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Cage: Develop and deploy complex Docker applications\n\n[![Latest version](https://img.shields.io/crates/v/cage.svg)](https://crates.io/crates/cage) [![License](https://img.shields.io/crates/l/cage.svg)](https://opensource.org/licenses/MIT) [![Build Status](https://travis-ci.org/faradayio/cage.svg?branch=master)](https://travis-ci.org/faradayio/cage) [![Build status](https://ci.appveyor.com/api/projects/status/3hn8cwckcdhpcasm/branch/master?svg=true)](https://ci.appveyor.com/project/emk/cage/branch/master) [![Documentation](https://img.shields.io/badge/documentation-docs.rs-yellow.svg)](https://docs.rs/cage/) [![Gitter](https://badges.gitter.im/faradayio/cage.svg)](https://gitter.im/faradayio/cage?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n\n\u003ca href=\"http://cage.faraday.io/\"\u003e\n  \u003cimg src=\"http://cage.faraday.io/assets/cage-logo.svg\" alt=\"Logo\"\n       width=\"200\" height=\"113\"\u003e\n\u003c/a\u003e\n\nDoes your project have too many Docker services? Too many git repos? Cage\nmakes it easy to develop complex, multi-service applications locally.  It\nworks with standard `docker-compose.yml` files and `docker-compose`, but\nit helps bring order to the complexity:\n\n- Cage provides a standardized project structure, much like Rails did for\n  web development.\n- Cage allows you to work with multiple source repositories, and to mix\n  pre-built Docker images with local source code.\n- Cage removes the repetitive clutter from your `docker-compose.yml` files.\n- Cage provides secret management, either using a single text file\n  or [Hashicorp's Vault][vault].\n\nFor more information about Cage, see\nthe [introductory website](http://cage.faraday.io/).\n\n[vault]: https://www.vaultproject.io/\n\n## Installation\n\nFirst, you need to [install Docker][] and make sure that you\nhave [at least version 1.8.1][compose] of `docker-compose`:\n\n```sh\n$ docker-compose --version\ndocker-compose version 1.8.1, build 878cff1\n```\n\nWe provide [pre-built `cage` binaries for Linux and MacOS][releases] on the\nrelease page.  The Linux binaries\nare [statically linked][rust-musl-builder] and should work on any modern\nLinux distribution.  To install, you can just unzip the binaries and copy\nthem to `/usr/local/bin`:\n\n```sh\nunzip cage-*.zip\nsudo cp cage /usr/local/bin/\nrm cage-*.zip cage\n```\n\nIf you would like to install from source, we recommend using `rustup` and\n`cargo install`:\n\n```sh\ncurl https://sh.rustup.rs -sSf | sh\ncargo install cage\n```\n\nIf you have [trouble][] using cage's vault integration, try installing with\n`cargo` instead.\n\nNote that it's [possible to build `cage` for Windows](./WINDOWS.md), but\nit's still not yet officially supported.\n\n[install Docker]: https://docs.docker.com/engine/installation/\n[compose]: https://github.com/docker/compose/releases\n[releases]: https://github.com/faradayio/cage/releases\n[rust-musl-builder]: https://github.com/emk/rust-musl-builder\n[trouble]: https://github.com/faradayio/cage/issues/11\n\n## Trying it out\n\nCreate a new application using `cage`:\n\n```sh\ncage new myapp\ncd myapp\n```\n\nPull the pre-built Docker images associated with this application and start\nup the database pod:\n\n```sh\ncage pull\ncage up db\n```\n\nRun the `rake` image to initialize your database:\n\n```sh\ncage run rake db:create\ncage run rake db:migrate\n```\n\nAnd bring up the rest of the app:\n\n```sh\ncage up\n```\n\nLet's take a look at the pods and services defined by this application:\n\n```sh\n$ cage status\ndb enabled type:placeholder\n└─ db\nfrontend enabled type:service\n└─ web ports:3000\nrake enabled type:task\n└─ rake\n```\n\nThis shows us that the `web` service is listening on port 3000, so you\nshould be able to access the application\nat [http://localhost:3000](http://localhost:3000).  But let's make a\nchange!  First, list the available source code for the services in this\napp:\n\n```sh\n$ cage source ls\nrails_hello               https://github.com/faradayio/rails_hello.git\n```\n\nTry mounting the source code for `rails_hello` into all the containers that\nuse it:\n\n```sh\n$ cage source mount rails_hello\n$ cage up\n$ cage source ls\nrails_hello               https://github.com/faradayio/rails_hello.git\n  Cloned at src/rails_hello (mounted)\n```\n\nYou may also notice that since `myapp_rake_1` is based on the same\nunderlying Git repository as `myapp_web_1`, that it also has a mount of\n`src/rails_hello` in the appropriate location.  If you change the source on\nyour host system, it will automatically show up in both containers.\n\nNow, create an HTML file at `src/rails_hello/public/index.html`:\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\u003ctitle\u003eSample page\u003c/title\u003e\u003c/head\u003e\n  \u003cbody\u003e\u003ch1\u003eSample page\u003c/h1\u003e\u003c/body\u003e\n\u003c/html\u003e\n```\n\nAnd reload the website in your browser.  You should see the new page!\n\nWe can also run container-specific unit tests, which are specified by the\ncontainer, so that you can invoke any unit test framework of your choice:\n\n```sh\ncage test web\n```\n\nAnd we can access individual containers using a configurable shell:\n\n```sh\n$ cage shell web\nroot@21bbbb41ad4a:/usr/src/app#\n```\n\nThe top-level convenience commands like `test` and `shell` make it much\neasier to perform standard development tasks without knowing how individual\ncontainers work.\n\nFor more information, check out `cage`'s help:\n\n```sh\ncage --help\n```\n\n## What's a pod?\n\nA \"pod\" is a tightly-linked group of containers that are always deployed\ntogether.  Kubernetes [defines pods][pods] as:\n\n\u003e A pod (as in a pod of whales or pea pod) is a group of one or more\n\u003e containers (such as Docker containers), the shared storage for those\n\u003e containers, and options about how to run the containers. Pods are always\n\u003e co-located and co-scheduled, and run in a shared context. A pod models an\n\u003e application-specific “logical host” - it contains one or more application\n\u003e containers which are relatively tightly coupled — in a pre-container\n\u003e world, they would have executed on the same physical or virtual machine.\n\nIf you're using Amazon's ECS, a pod corresponds to an ECS \"task\" or\n\"service\".  If you're using Docker Swarm, a pod corresponds to a single\n`docker-compose.xml` file full of services that you always launch as a\nsingle unit.\n\nPods typically talk to other pods using ordinary DNS lookups or service\ndiscovery.  If a pod accepts outside network connections, it will often do\nso via a load balancer.\n\n[pods]: http://kubernetes.io/docs/user-guide/pods/\n\n## Project format\n\nSee `examples/hello` for a complete example.\n\n```txt\nhello\n└── pods\n    ├── common.env\n    ├── frontend.yml\n    └── targets\n        ├── development\n        │   └── common.env\n        ├── production\n        │   ├── common.env\n        │   └── frontend.yml\n        └── test\n            └── common.env\n```\n\n### File types\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eFilename\u003c/th\u003e\n    \u003cth\u003eDescription\u003c/th\u003e\n    \u003cth\u003eFound in\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003ecommon.env\u003c/code\u003e\n    \u003ctd\u003eSets environment variables at different levels. \u003ccode\u003ecommon\u003c/code\u003e is a reserved word.\u003c/td\u003e\n    \u003ctd\u003eTop-level \u003ccode\u003epods/\u003c/code\u003e dir and also in target dirs (\u003ccode\u003eproduction\u003c/code\u003e, etc.)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003e$SERVICE.yml\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003eValid \u003ca href=\"https://docs.docker.com/compose/compose-file/\"\u003e\u003ccode\u003edocker-compose.yml\u003c/code\u003e version 2\u003c/a\u003e defining images, etc.\u003c/td\u003e\n  \u003ctd\u003eTop-level \u003ccode\u003epods/\u003c/code\u003e dir and also in target dirs (\u003ccode\u003eproduction\u003c/code\u003e, etc.)\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n  \u003ctd\u003e\u003ccode\u003e$SERVICE.metadata.yml\u003c/code\u003e\u003c/td\u003e\n  \u003ctd\u003ePod-level metadata that isn't valid in \u003ca href=\"https://docs.docker.com/compose/compose-file/\"\u003e\u003ccode\u003edocker-compose.yml\u003c/code\u003e version 2\u003c/a\u003e.\u003c/td\u003e\n  \u003ctd\u003eTop-level \u003ccode\u003epods/\u003c/code\u003e dir and also in target dirs (\u003ccode\u003eproduction\u003c/code\u003e, etc.)\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Other commands\n\n### cage run-script\n\nThe `run-script` command operates similarly to `npm run \u003cscript\u003e` or\n`rake \u003ctask\u003e`. Simply define a set of named scripts in the pod's metadata:\n\n```yml\n# tasks.yml\nservices:\n  runner:\n    build: .\n```\n\n```yml\n# tasks.metadata.yml\n\nservices:\n  runner:\n    scripts:\n      populate:\n        - [\"npm\",\"run\",\"populate\"]\n```\n\nBy running `cage run-script populate`, cage will find all services\nthat have a `populate` script and run it. You can also specify a\npod or service with `cage run-script tasks populate`.\n\n## Reporting issues\n\nIf you encounter an issue, it might help to set the following shell\nvariables and re-run the command:\n\n```sh\nexport RUST_BACKTRACE=1 RUST_LOG=cage=debug,compose_yml=debug\n```\n\n## Development notes\n\nPull requests are welcome!  If you're unsure about your idea, then please\nfeel free to file an issue and ask us for feedback.  We like suggestions!\n\n### Setting up tools\n\nWhen working on this code, we recommend installing the following support\ntools:\n\n```sh\nrustup component add rustfmt\nrustup component add clippy\ncargo install cargo-watch\n```\n\nRun the following in a terminal as you edit:\n\n```sh\ncargo watch -x test\n```\n\nBefore committing your code, run:\n\n```sh\ncargo clippy\ncargo fmt\n```\n\nThis will automatically check for warnings, and reformat your code according to the project's\nconventions.  We use Travis CI to verify that `cargo fmt` has been run and\nthat the project builds with no warnings.  If it fails, no worries—just go\nahead and fix your pull request, or ask us for help.\n\n### On MacOS\n\nThe openssl crate needs a compatible version of the `openssl` libraries. You may be able to install them as follows:\n\n```sh\nbrew install openssl\n```\n\n### Official releases\n\nTo make an official release, you need to be a maintainer, and you need to\nhave `cargo publish` permissions.  If this is the case, first edit\n`Cargo.toml` to bump the version number, then regenerate `Cargo.lock`\nusing:\n\n```sh\ncargo build\n```\n\nCommit the release, using a commit message of the format:\n\n```txt\nv\u003cVERSION\u003e: \u003cSUMMARY\u003e\n\n\u003cRELEASE NOTES\u003e\n```\n\nThen run:\n\n```sh\ncargo publish\ngit tag v$VERSION\ngit push; git push --tags\n```\n\nThis will rebuild the official binaries using Travis CI, and upload a new version of\nthe crate to [crates.io](https://crates.io/crates/cage).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaradayio%2Fcage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffaradayio%2Fcage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaradayio%2Fcage/lists"}