Skip to content

bsideup/configo

Repository files navigation

Configo Build Status Goreport Join the chat at https://gitter.im/bsideup/configo Approved issues

Configo helps running 12factor (http://12factor.net/config) applications by loading environment variables from different sources.

Configuration

See wiki for detailed explanation of configuration options, supported sources and more examples: https://github.com/bsideup/configo/wiki

Usage

Imagine having an application that is configurable with environment variables. Let us assume that this is a self-contained (http://12factor.net/processes) NodeJS application, and that we have a Docker image for it:

FROM node

ADD . /app
WORKDIR /app

CMD ["node", "server.js"]

Surely you want to deploy this application to dev/qa/production. Some configuration is obviously required. We will use these environment variables for this configuration:

docker run \
  -e "DB_MONGO_URI=mongodb://user:pass@mongo.prod.domain.com/db" \
  -e "DB_REDIS_URI=redis://some.redis.prod.domain.com/0" \
  -e "GOOGLE_ANALYTICS_KEY=UA-XXXXX-Y" \
  -e TWITTER_KEY=abcdefg \
  -e SEND_EMAILS=true \
  myAppImage

We also have a server to run some background jobs:

docker run \
  -e "DB_MONGO_URI=mongodb://user:pass@mongo.prod.domain.com/db" \
  -e "DB_REDIS_URI=redis://some.redis.prod.domain.com/0" \
  -e TWITTER_KEY=abcdefg \
  -e SEND_EMAILS=true \
  -e RUN_JOBS=true \
  myAppImage

Since we have 5 servers in production, we have to configure these environment variables for each server. Would it not be nice to have a single source of configuration and load it for each app? And maybe some shared configuration as well? This is where Configo comes in.

Meet Configo!

First, change your Dockerfile ever so slightly:

FROM node

+RUN curl -L https://github.com/bsideup/configo/releases/download/v0.4.1/configo.linux-amd64 >/usr/local/bin/configo && \
+    chmod +x /usr/local/bin/configo

ADD . /app
WORKDIR /app

-CMD ["node", "server.js"]
+CMD ["configo", "node", "server.js"]

For this example, we will use an URL as a source for Configo. Other possible sources can be used - check the configuration section below for more information.

Upload your configuration files to your internal HTTP server:

$ curl -sSL https://my.server.com/common.yaml
db:
  mongo:
    uri: mongodb://user:pass@mongo.prod.domain.com/db
  redis:
    uri: redis://some.redis.prod.domain.com/0
twitter:
  key: abcdefg
send_emails: true
$ curl -sSL https://my.server.com/server.yaml
google.analytics.key: UA-XXXXX-Y
$ curl -sSL https://my.server.com/jobs.yaml
run_jobs: true

We are now ready to start our applications:

docker run \
  -e CONFIGO_SOURCE_0='{"type": "http", "format": "yaml", "url": "https://my.server.com/common.yaml"}' \
  -e CONFIGO_SOURCE_100='{"type": "http", "format": "yaml", "url": "https://my.server.com/server.yaml"}' \
  myAppImage

docker run \
  -e CONFIGO_SOURCE_0='{"type": "http", "format": "yaml", "url": "https://my.server.com/common.yaml"}' \
  -e CONFIGO_SOURCE_100='{"type": "http", "format": "yaml", "url": "https://my.server.com/jobs.yaml"}' \
  myAppImage

Since we added Configo, it will now load configuration from the sources we specified. In addition, it will merge these settings and configure the environment variables for your application.

Thanks