{"id":13415992,"url":"https://github.com/newrelic/centurion","last_synced_at":"2025-05-14T05:10:26.217Z","repository":{"id":17696008,"uuid":"20502024","full_name":"newrelic/centurion","owner":"newrelic","description":"A mass deployment tool for Docker fleets","archived":false,"fork":false,"pushed_at":"2024-08-26T19:53:14.000Z","size":516,"stargazers_count":1760,"open_issues_count":9,"forks_count":112,"subscribers_count":71,"default_branch":"master","last_synced_at":"2025-05-07T23:55:27.533Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/newrelic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-06-04T21:44:12.000Z","updated_at":"2025-05-03T05:07:19.000Z","dependencies_parsed_at":"2024-06-19T00:12:11.737Z","dependency_job_id":"0c24c7aa-41f0-4e67-b0fd-61efd8fe433e","html_url":"https://github.com/newrelic/centurion","commit_stats":{"total_commits":323,"total_committers":49,"mean_commits":6.591836734693878,"dds":0.6563467492260062,"last_synced_commit":"64da27aff64c52795872c340a0056ce69a56775c"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/newrelic%2Fcenturion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/newrelic%2Fcenturion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/newrelic%2Fcenturion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/newrelic%2Fcenturion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/newrelic","download_url":"https://codeload.github.com/newrelic/centurion/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254076848,"owners_count":22010611,"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-30T21:00:53.523Z","updated_at":"2025-05-14T05:10:26.190Z","avatar_url":"https://github.com/newrelic.png","language":"Ruby","readme":"Centurion\n=========\n\nA deployment tool for Docker. Takes containers from a Docker registry and runs\nthem on a fleet of hosts with the correct environment variables, host volume\nmappings, and port mappings. Supports rolling deployments out of the box, and\nmakes it easy to ship applications to Docker servers.\n\nWe're using it in our production infrastructure.\n\nCenturion works in a two part deployment process where the build process ships\na container to the registry, and Centurion ships containers from the registry\nto the Docker fleet. Registry support is handled by the Docker command line\ntools directly so you can use anything they currently support via the normal\nregistry mechanism.\n\nIf you haven't been using a registry, you should read up on how to do that\nbefore trying to deploy anything with Centurion.\n\nCommercial Docker Registry Providers:\n- Docker, Inc. [provides repositories](https://index.docker.io/), and hosts the\n  main public Docker repository.\n- [Quay.io](https://quay.io) from the CoreOS team\n\nOpen-source:\n- The [Docker Distribution](https://github.com/docker/distribution) project,\n  built and maintained by Docker. You host this yourself.\n\nStatus\n------\n\nThis project still being maintained, but no new feature work is planned. The initial commit on GitHub contains\none roll-up commit of all our internal code. But all internal development will\nnow be on public GitHub. See the CONTRIBUTORS file for the contributors to the\noriginal internal project.\n\nInstallation\n------------\n\nCenturion is a Ruby gem. It assumes that you have a working, modern-ish Ruby\n(1.9.3 or higher). On Ubuntu 12.04 you can install this with the `ruby-1.9.1`\nsystem package, for example. On OSX this is best accomplished via `rbenv` and\n`ruby-build` which can be installed with [Homebrew](http://brew.sh/) or from\n[GitHub](https://github.com/sstephenson/rbenv).\n\nOnce you have a running, modern Ruby, you simply:\n\n```\n$ gem install centurion\n```\n\nWith rbenv you will now need to do an `rbenv rehash` and the commands should\nbe available. With a non-rbenv install, assuming the gem dir is in your path,\nthe commands should just work now.\n\nConfiguration\n-------------\n\nCenturion expects to find configuration tasks in the current working directory\ntree.\n\nWe recommend putting all your configuration for multiple applications into a\nsingle repo rather than spreading it around by project. This allows a central\nchoke point on configuration changes between applications and tends to work\nwell with the hand-off in many organizations between the build and deploy\nsteps. If you only have one application, or don't need this you can\ndecentralize the config into each repo.\n\nIt will look for configuration files in either `./config/centurion` or `.`.\n\nThe pattern at New Relic is to have a configs repo with a `Gemfile` that\nsources the Centurion gem. If you want Centurion to set up the structure for\nyou and to create a sample config, you can simply run `centurionize` once you\nhave the Ruby Gem installed.\n\nCenturion ships with a simple scaffolding tool that will setup a new config repo for\nyou, as well as scaffold individual project configs. Here's how you run it:\n\n```bash\n$ centurionize -p \u003cyour_project\u003e\n```\n\n`centurionize` relies on Bundler being installed already. Running the command\nwill have the following effects:\n\n * Ensure that a `config/centurion` directory exists\n * Scaffold an example config for your project (you can specify the registry)\n * Ensure that a Gemfile is present\n * Ensure that Centurion is in the Gemfile (if absent it just appends it)\n\nAny time you add a new project you can scaffold it in the same manner even\nin the same repo.\n\n### Writing configs\n\nIf you used `centurionize` you will have a base config scaffolded for you.\nBut you'll still need to specify all of your configuration.\n\nConfigs are in the form of a Rake task that uses a built-in DSL to make them\neasy to write. Here's a sample config for a project called \"radio-radio\" that\nwould go into `config/centurion/radio-radio.rake`:\n\n```ruby\nnamespace :environment do\n  task :common do\n    set :image, 'example.com/newrelic/radio-radio'\n    host 'docker-server-1.example.com'\n    host 'docker-server-2.example.com'\n  end\n\n  desc 'Staging environment'\n  task :staging =\u003e :common do\n    set_current_environment(:staging)\n    env_vars YOUR_ENV: 'staging'\n    env_vars MY_DB: 'radio-db.example.com'\n    host_port 10234, container_port: 9292\n    host_port 10235, container_port: 9293\n    host_volume '/mnt/volume1', container_volume: '/mnt/volume2'\n  end\n\n  desc 'Production environment'\n  task :production =\u003e :common do\n    set_current_environment(:production)\n    env_vars YOUR_ENV: 'production'\n    env_vars MY_DB: 'radio-db-prod.example.com'\n    host_port 22234, container_port: 9292\n    host_port 23235, container_port: 9293\n    command ['/bin/bash', '-c', '/path/to/server -e production']\n  end\nend\n```\n\nThis sets up a staging and production environment and defines a `common` task\nthat will be run in either case. Note the dependency call in the task\ndefinition for the `production` and `staging` tasks.  Additionally, it defines\nsome host ports to map, sets which servers to deploy to, and sets a custom\ncommand. Some configuration will be provided to the containers at startup time,\nin the form of environment variables.\n\nMost of the DSL items (`host_port`, `host_volume`, `env_vars`, `host`) can be\nspecified more than once and will append to the configuration. However, there\ncan only be one `command`; the last one will take priority.\n\nYou can also assign lambdas to environment variables. The lambda function will\nbe invoked by Centurion during deploy time with `server_hostname` as its only\nargument. The `server_hostname` yielded will be the same string as was\nspecified in the `host` argument for the server currently being deployed to.\n\nThis is useful to assign a sticky identity for each of the containers\nin the deploy. For example, a hash mapping hostname to another string which is\ndifferent on each host. \n```ruby\n  desc 'Host-specific env vars'\n  task :production =\u003e :common do\n    env_vars MEMBER_ID: lambda do |hostname| \n        {\n          'web-server-1.company.net' =\u003e 'machine1'\n          'web-server-2.company.net' =\u003e 'machine2'\n        }[hostname]\n      end\n  end\n```\n\nYou can cause your container to be started with a specific DNS server\nIP address (the equivalent of `docker run --dns 172.17.42.1 ...`) like this:\n```ruby\n  task :production =\u003e :common do\n    set :dns, [ '172.17.42.1' ]\n    # ...\n  end\n```\n\n### Container Names\n\nThis is the name that shows up in the `docker ps` output. It's the name\nof the container, not the hostname inside the container. By default\nthe container will be named using the name of the project as the base\nof the name.\n\nIf you want to name your container something other than the project name,\nuse the `name` setting. The actual name for the created container will\nhave a random hex string appended, to avoid name conflicts when you repeatedly\ndeploy a project:\n\n```ruby\n  task :common do\n    set :name, 'backend'\n    # ...\n  end\n```\nWith this, the container will be named something like `backend-4f692997`.\n\n### Container Labels\n\nYou may add arbitrary labels to your containers by calling `labels` with a hash.\nThe call is cumulative, so you may express patterns like:\n\n```ruby\nnamespace :environment do\n  task :common do\n    set :image, 'example.com/newrelic/radio-radio'\n    host 'docker-server-1.example.com'\n    labels team: 'radio-ops'\n  end\n\n  desc 'Staging environment'\n  task :staging =\u003e :common do\n    labels environment: 'radio-staging'\n    env_vars YOUR_ENV: 'staging'\n  end\nend\n```\n\nThis would result in the container having two labels, as shown in a \n`docker inspect` example:\n\n```\n  \"Labels\": {\n    \"team\": \"radio-ops\",\n    \"environment\": \"radio-staging\"\n  }\n```\n\nHash keys and values will be stringified, so you may pass any object with a \n`#to_s` method.\n\n### Container Hostnames\n\nIf you don't specify a hostname to use inside your container, the container\nwill be given a hostname matching the container ID. This probably is good for\na lot of situations, but it might not be good for yours. If you need to have\na specific hostname, you can ask Centurion to do that:\n\n```ruby\nset :container_hostname, 'yourhostname'\n```\n\nThat will make *all* of your containers named 'yourhostname'. If you want to do\nsomething more dynamic, you can pass a `Proc` or a lambda like this:\n\n```ruby\nset :container_hostname, -\u003e(hostname) { \"#{hostname}.example.com\" }\n```\n\nThe lambda will be passed the current server's hostname. So, this example will\ncause \".example.com\" to be appended to the hostname of each Docker host during\ndeployment.\n\n*If you want to restore the old behavior from Centurion 1.6.0* and earlier, you\ncan do the following:\n\n```ruby\nset :container_hostname, -\u003e(hostname) { hostname }\n```\n\nThat will cause the container hostname to match the server's hostname.\n\n### Network modes\n\nYou may specify the network mode you would like a container to use via:\n\n```ruby\nset :network_mode, 'networkmode'\n```\n\nDocker (and therefore Centurion) supports one of `bridge` (the default), `host`,\nand `container:\u003ccontainer-id\u003e` for this argument.\n\nIn `host` and `container...` network modes, you may specify a \n`host_port, container_port` mapping, however the port numbers will only be used\nfor container health checks. The mapping itself, while still passed via the API,\nwill be ignored by Docker.\n\n### PID modes\n\nYou may specify the PID mode you would like a container to use via:\n\n```ruby\nset :pid_mode, 'pidmode'\n```\n\nDocker (and therefore Centurion) supports one of nothing (the default), `host`,\nand `container:\u003ccontainer-id\u003e` for this argument.\n\n### CGroup Resource Constraints\n\nLimits on memory and CPU can be specified with the `memory` and `cpu_shares`\nsettings. Both of these expect a 64-bit integer describing the number of\nbytes, and the number of CPU shares, respectively.\n\nFor example, to limit the memory to 1G, and the cpu time slice to half the\nnormal length, include the following:\n\n```ruby\nmemory 1.gigabyte\ncpu_shares 512\n```\n\nFor more information on Docker's CGroup limits see [the Docker\ndocs](https://docs.docker.com/reference/run/#runtime-constraints-on-cpu-and-memory).\n\n### Adding Extended Capabilities\n\nAdditional kernel capabilities may be granted to containers, permitting them\ndevice access they do not normally have. You may specify these as follows:\n\n```ruby\nadd_capability 'SOME_CAPABILITY'\nadd_capability 'ANOTHER_CAPABILITY'\ndrop_capability 'SOMEOTHER_CAPABILITY'\n```\n\nYou may also ask for all but a few capabilities as follows:\n\n```ruby\nadd_capability 'ALL'\ndrop_capability 'SOME_CAPABILITY'\n```\n\nFor more information on which kernel capabilities may be specified, see the\n[Docker docs](https://docs.docker.com/reference/run/#runtime-privilege-linux-capabilities-and-lxc-configuration).\n\n### Setting the security options\n\nSome Docker platforms support container security overlays called `seccomp`. \nDuring container creation, you may specify security options to control the \nseccomp permissions. \n\nTo set a seccomp path:\n```ruby\nadd_security_opt 'seccomp=/path/to/seccomp/profile.json'\n```\n\nOr, to unblock all syscalls in a container:\n\n```ruby\nadd_security_opt 'seccomp=unconfined'\n```\n\nFor more information on this argument, see the [Docker docs](https://docs.docker.com/engine/security/seccomp/).\n\n### Interpolation\n\nCurrently there a couple of special strings for interpolation that can be added\nto any `env_var` value in the DSL. `%DOCKER_HOSTNAME%` will be replaced with\nthe current server's hostname in the environment variable at deployment time.\nAlso `%DOCKER_HOST_IP%` will be replaced with the *public* IP address of the\nDocker server using a `getaddrinfo` call on the client.\n\n### Use TLS certificate\n\nCenturion can use your existing Docker TLS certificates when using Docker with\nTLS support. In doing so you have 2 choices.\n\n#### Your certificate files are in `~/.docker/`\n\nYou just need to enable the tls mode as the following:\n\n```ruby\n  task :production =\u003e :common do\n    set :tlsverify, true\n    # ...\n  end\n```\n\nCenturion will only set the `--tlsverify` to true and Docker will read your\ncertificate from the `~/.docker/` path.\n\n#### Your certificate files are not in `~/.docker/`\n\nGiven your files are in `/usr/local/certs/`\nYou have to set the following keys:\n\n```ruby\n  task :production =\u003e :common do\n    set :tlsverify, true\n    set :tlscacert, '/usr/local/certs/ca.pem'\n    set :tlscert, '/usr/local/certs/ssl.crt'\n    set :tlskey, '/usr/local/certs/ssl.key'\n    # ...\n  end\n```\n\nModify the paths as appropriate for your cert, ca, and key files.\n\n### Use SSH to connect *beta*\n\nIf your Docker server does not expose its HTTP service over TCP, you can\ninstead talk to it via SSH.\n\nThis functions by creating a local Unix socket that forwards to the remote\nDocker Unix socket, so it requires that the user you connect as has access to\nthe Docker socket without any `sudo`. Currently it also assumes that you\nauthenticate via public key, so be sure that you have `ssh-add`ed your key to\nyour SSH agent if it has a passcode.\n\nYou can configure it with a few options:\n\n```ruby\n  task :common do\n    set :ssh, true # enable ssh connections\n    set :ssh_user, \"myuser\" # if you want to specify the user to connect as, otherwise your current user\n    set :ssh_log_level, Logger::DEBUG # passed on to net/ssh, can be noisy; defaults to Logger::WARN\n    set :ssh_socket_heartbeat, 5 # passed on to net/ssh (Net::SSH::Connection::Session#loop); defaults to 30\n  end\n```\n\n#### Troubleshooting SSH connections\n\nIn some cases you may notice your SSH commands are completing successfully,\nbut the connection isn't aware they are done. This will manifest as a tunneled\ncommand taking much longer than anticipated - minutes depending on your\nserver's configuration. You may need to set `:ssh_socket_heartbeat` to a\nsmaller number. This will check more frequently if the command has completed\nwhich can alleviate this issue, though it will consume more CPU as it wakes up\nits threads more frequently.\n\nDeploying\n---------\n\nCenturion supports a number of tasks out of the box that make working with\ndistributed containers easy.  Here are some examples:\n\n### Do a rolling deployment to a fleet of Docker servers\n\nA rolling deployment will stop and start each container one at a time to make\nsure that the application stays available from the viewpoint of the load\nbalancer. As the deploy runs, a health check will hit each container to ensure\nthat the application booted correctly. By default, this will be a GET request to\nthe root path of the application. The healthcheck endpoint is configurable by adding\n`set(:status_endpoint, '/somewhere/else')` in your config. The status endpoint\nmust respond with a valid response in the 200 status range.\n\n```bash\n$ bundle exec centurion -p radio-radio -e staging -a rolling_deploy\n```\n\n**Custom Health Check**:\nYou can use a custom health check by specifying a callable object (anything that\nresponds to :call), e.g. a Proc, lambda, or method. This method will be invoked with\nthe host url, the port that needs to be checked, and the specified endpoint(via\n`set(:status_endpoint, '/somewhere/else')`). If the port is ready, health check\nshould return a truthy value, falsey otherwise. Here's an example of a custom\nhealth check that verifies that an elasticsearch node is up and has joined the\ncluster.\n\n```ruby\ndef cluster_green?(target_server, port, endpoint)\n  response = begin\n    Excon.get(\"http://#{target_server.hostname}:#{port}#{endpoint}\")\n  rescue Excon::Errors::SocketError\n    warn \"Elasticsearch node not yet up\"\n    nil\n  end\n\n  return false unless response\n  !JSON.parse(response)['timed_out']\nend\n\ntask :production =\u003e :common do\n  set_current_environment(:production)\n  set :status_endpoint, \"/_cluster/health?wait_for_status=green\u0026wait_for_nodes=2\"\n  health_check method(:cluster_green?)\n  host_port 9200, container_port: 9200\n  host 'es-01.example.com'\n  host 'es-02.example.com'\nend\n```\n\n**Rolling Deployment Settings**:\nYou can change the following settings in your config to tune how the rolling\ndeployment behaves. Each of these is controlled with `set(:var_name, 'value')`.\nThese can be different for each environment or put into a common block if they\nare the same everywhere. Settings are per-project.\n\n * `rolling_deploy_check_interval` =\u003e Controls how long Centurion will wait after\n    seeing a container as up before moving on to the next one. This should be\n    slightly longer than your load balancer check interval. Value in seconds.\n    Defaults to 5 seconds.\n * `rolling_deploy_wait_time` =\u003e The amount of time to wait between unsuccessful\n    health checks before retrying. Value in seconds. Defaults to 5 seconds.\n * `rolling_deploy_retries` =\u003e The number of times to retry a health check on\n   the container once it is running. This count multiplied by the\n   `rolling_deployment_wait_time` is the total time Centurion will wait for\n   an individual container to come up before giving up as a failure. Defaults\n   to 24 attempts.\n * `rolling_deploy_skip_ports` =\u003e Either a single port, or an array of ports\n   that should be skipped for status checks. By default status checking assumes\n   an HTTP server is on the other end and if you are deploying a container where some\n   ports are not HTTP services, this allows you to only health check the ports\n   that are. The default is an empty array. If you have non-HTTP services that you\n   want to check, see Custom Health Checks in the previous section.\n\n### Deploy a project to a fleet of Docker servers\n\nThis will hard stop, then start containers on all the specified hosts. This\nis not recommended for apps where one endpoint needs to be available at all\ntimes. It is fast.\n\n```bash\n$ bundle exec centurion -p radio-radio -e staging -a deploy\n```\n\n### Deploy a bash console on a host\n\nThis will give you a command line shell with all of your existing environment\npassed to the container. The `CMD` from the `Dockerfile` will be replaced\nwith `/bin/bash`. It will use the first host from the host list.\n\n```bash\n$ bundle exec centurion -p radio-radio -e staging -a deploy_console\n```\n\n### Repair unhealthy docker containers\n\nThis will preform a health check on each host using rolling deployment\nhealth check settings and redeploy to the host if a health check fails.\n\n```bash\n$ bundle exec centurion -p radio-radio -e staging -a repair\n```\n\n### List all the tags running on your servers for a particular project\n\nReturns a nicely-formatted list of all the current tags and which machines they\nare running on. Gives a unique list of tags across all hosts as well.  This is\nuseful for validating the state of the deployment in the case where something\ngoes wrong mid-deploy.\n\n```bash\n$ bundle exec centurion -p radio-radio -e staging -a list:running_container_tags\n```\n\n### List all the containers currently running for this project\n\nReturns a (as yet not very nicely formatted) list of all the containers for\nthis project on each of the servers from the config.\n\n```bash\n$ bundle exec centurion -p radio-radio -e staging -a list:running_containers\n```\n\n### List registry images\n\nReturns a list of all the images for this project in the registry.\n\n```bash\n$ bundle exec centurion -p radio-radio -e staging -a list\n```\n\n### Registry\n\nCenturion needs to have access to some registry in order to pull images to\nremote Docker servers. This needs to be either a hosted registry (public or\nprivate), or [Dogestry](https://github.com/dogestry/dogestry).\n\n#### Access to the registry\n\nIf you are not using either Dogestry, or the public registry, you may need to\nprovide authentication credentials.  Centurion needs to access the Docker\nregistry hosting your images directly to retrive image ids and tags. This is\nsupported in both the config file and also as command line arguments.\n\nThe command line arguments are:\n * `--registry-user` =\u003e The username to pass to the registry\n * `--registry-password` =\u003e The password\n\nThese correspond to the following settings:\n\n * `registry_user`\n * `registry_password`\n\n#### Alternative Docker Registry\n\nCenturion normally uses the built-in registry support in the Docker daemon to\nhandle pushing and pulling images. But Centurion also has the ability to use\nexternal tooling to support hosting your registry on Amazon S3. That tooling is\nfrom a project called [Dogestry](https://github.com/dogestry/dogestry).\nWe have recently improved that tooling substantially in coordination with the\nCenturion support.\n\nDogestry uses the Docker daemon's import/export functionality in combination\nwith Amazon S3 to provide reliable hosting of images.  Setting Centurion up to\nuse Dogestry is pretty trivial:\n\n 1. Create an S3 bucket and download the credentials to let you access the\n    bucket. Generally these are IAM user keys.\n 1. Install Dogestry binaries on the client from which Dogestry is run.\n    Binaries are provided in the [GitHub release](https://github.com/dogestry/dogestry).\n 1. Add the settings necessary to get Centurion to pull from Dogestry. A config\n    example is provided below:\n\n```ruby\nnamespace :environment do\n  task :common do\n    registry :dogestry                       # Required\n    set :aws_access_key_id, 'abc123'         # Required\n    set :aws_secret_key, 'xyz'               # Required\n    set :s3_bucket, 'docker-images-bucket'   # Required\n    set :s3_region, 'us-east-1'              # Optional\n  end\nend\n```\n\n**TLS with Dogestry**: Because this involves a little passing around of both\nsettings and environment variables, there are a couple of things to verify to\nmake sure everything is passed properly between Centurion and Dogestry. If your\nkeys have the default names and are in located in the path represented by\n`DOCKER_CERT_PATH` in your environment, this should just work. Otherwise you'll\nneed to be sure to `set :tlsverify, true` and *also* set the TLS cert names as\ndecribed above. \n\nDevelopment\n-----------\n\nCenturion supports a few features to make development easier when\nbuilding your deployment tooling or debugging your containers.\n\n#### Overriding Environment Variables\n\nSometimes when you're doing development you want to try out some configuration\nsettings in environment variables that aren't in the config yet. Or perhaps you\nwant to override existing settings to test with. You can provide the\n`--override-env` command line flag with some overrides or new variables to set.\nHere's how to use it:\n\n```bash\n$ centurion -e development -a deploy -p radio-radio --override-env=SERVICE_PORT=8080,NAME=radio\n```\n\nCenturion is aimed at repeatable deployments so we don't recommend that you use\nthis functionality for production deployments. It will work, but it means that\nthe config is not the whole source of truth for your container configuration.\nCaveat emptor.\n\n#### Exporting Environment Variables Locally\n\nSometimes you need to test how your code works inside the container and you\nneed to have all of your configuration exported. Centurion includes an action\nthat will let you do that. It exports all of your environment settings for the\nenvironment you specify. It then partially sanitizes them to preserve things\nlike `rbenv` settings. Then it executes `/bin/bash` locally.\n\nThe action is named `dev:export_only` and you call it like this:\n\n```bash\n$ bundle exec centurion -e development -p testing_project -a dev:export_only\n$ bundle exec rake spec\n```\n\nIt's important to note that the second line is actually being invoked with new\nenvironment exported.\n\nFuture Additions\n----------------\n\nWe're currently looking at the following feature additions:\n\n * [etcd](https://github.com/coreos/etcd) integration for configs and discovery\n * Add the ability to show all the available tasks on the command line\n\nContributions\n-------------\n\nContributions are more than welcome. Bug reports with specific reproduction\nsteps are great. If you have a code contribution you'd like to make, open a\npull request with suggested code.\n\nNote that PR's and issues are reviewed every ~2 weeks. If your PR or issue is\ncritical in nature, please reflect that in the description so that it receives\nfaster attention.\n\nPull requests should:\n\n * Clearly state their intent in the title\n * Have a description that explains the need for the changes\n * Include tests!\n * Not break the public API\n * Add yourself to the CONTRIBUTORS file. I might forget.\n\nIf you are simply looking to contribute to the project, taking on one of the\nitems in the \"Future Additions\" section above would be a great place to start.\nPing us to let us know you're working on it by opening a GitHub Issue on the\nproject.\n\nBy contributing to this project you agree that you are granting New Relic a\nnon-exclusive, non-revokable, no-cost license to use the code, algorithms,\npatents, and ideas in that code in our products if we so choose. You also agree\nthe code is provided as-is and you provide no warranties as to its fitness or\ncorrectness for any purpose\n\nCopyright (c) 2014-2017 New Relic, Inc. All rights reserved.\n","funding_links":[],"categories":["Container Operations","Ruby","Deployment and Infrastructure","DevOps Tools"],"sub_categories":["Deployment and Infrastructure"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnewrelic%2Fcenturion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnewrelic%2Fcenturion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnewrelic%2Fcenturion/lists"}