A PaaS built on top of Amazon EC2 Container Service (ECS)
Go Ruby Other
Latest commit 323a911 Dec 15, 2016 @ejholmes ejholmes committed on GitHub Merge pull request #1031 from remind101/fail-fast
GitHub auth: Fail fast if username/password aren't provided.
Permalink
Failed to load latest commit information.
bin Minor tweaks to bin/bootstrap Dec 9, 2016
cmd Cleanup: Remove old unused packages Dec 15, 2016
docs Merge pull request #1024 from remind101/session-expiration Dec 10, 2016
empiretest Integration test full SAML service provider initiated login. Oct 26, 2016
events Add Stdout event stream Jun 13, 2016
pkg Cleanup: Remove old unused packages Dec 15, 2016
procfile Add support for setting environment variables in extended procfile. Oct 7, 2016
scheduler Increase stack operation timeout Dec 14, 2016
server GitHub auth: Fail fast if username/password aren't provided. Dec 16, 2016
stats Track CloudFormation template sizes. Jul 27, 2016
tests Integration test full SAML service provider initiated login. Oct 26, 2016
vendor Add go-xmlsec dependency Oct 20, 2016
.bumpversion.cfg Bump version: 0.10.1 → 0.11.0 Aug 23, 2016
.dockerignore Cleanup after move empire/ to the root. Jul 1, 2015
.gitignore Support service provider initiated login. Oct 25, 2016
CHANGELOG.md Merge pull request #1030 from remind101/stack-op-timeout Dec 14, 2016
CONTRIBUTING.md Update CONTRIBUTING.md. Jan 22, 2016
Dockerfile Add SAML support Oct 25, 2016
LICENSE Add BSD license. Fixes GH-193 Mar 24, 2015
Makefile Enable race detector (and fix flaky test) Jun 24, 2016
README.md Update dev instructions to install libxmlsec Oct 27, 2016
VERSION Bump version: 0.10.1 → 0.11.0 Aug 23, 2016
apps.go Allow certs to be attached to specific processes. Oct 15, 2016
apps_test.go Move from empire/empire to empire. Jul 1, 2015
certs.go Allow certs to be attached to specific processes. Oct 15, 2016
circle.yml Switch to Go 1.7 Aug 26, 2016
configs.go Only wrap the release creation in a transaction Jul 12, 2016
configs_test.go Store user and commit message with release description May 10, 2016
constraints.go more comments. Jun 24, 2016
constraints_test.go Implement new Extended Procfile format. Apr 26, 2016
db.go Private scope. Jun 24, 2016
db_test.go Private scope. Jun 24, 2016
deployments.go Adds a DeploymentStream type to make it easier to encode jsonmessage … Jul 14, 2016
doc.go Some small tweaks. Jun 24, 2016
docker-compose.yml Remove legacy ECS scheduler Oct 6, 2016
domains.go Private scope. Jun 24, 2016
domains_test.go Move from empire/empire to empire. Jul 1, 2015
empire.go Allow certs to be attached to specific processes. Oct 15, 2016
empire.png Prettier readme. Jan 14, 2016
empire_test.go Top level package documentation. Jun 24, 2016
events.go Update CHANGELOG Jul 27, 2016
events_test.go Update CHANGELOG Jul 27, 2016
extractor.go Add support for setting environment variables in extended procfile. Oct 7, 2016
extractor_test.go Fixes Procfile extraction in Docker 1.12. Jul 2, 2016
logs.go Annotate log streaming errors. Jun 6, 2016
migrations.go Allow certs to be attached to specific processes. Oct 15, 2016
migrations_test.go Allow certs to be attached to specific processes. Oct 15, 2016
mkdocs.yml Documentation additions. Aug 23, 2016
processes.go Add support for setting environment variables in extended procfile. Oct 7, 2016
processes_test.go more comments. Jun 24, 2016
releases.go Allow certs to be attached to specific processes. Oct 15, 2016
releases_test.go Merge default Range. Jul 24, 2015
runner.go Allow certs to be attached to specific processes. Oct 15, 2016
slugs.go Support a `ports` attribute in the extended Procfile. Oct 7, 2016
tasks.go Remove id, container id from output Aug 26, 2016
users.go More docs. Jun 24, 2016
version.go Bump version: 0.10.1 → 0.11.0 Aug 23, 2016

README.md

Empire

readthedocs badge Circle CI Slack Status

Empire

Empire is a control layer on top of Amazon EC2 Container Service (ECS) that provides a Heroku like workflow. It conforms to a subset of the Heroku Platform API, which means you can use the same tools and processes that you use with Heroku, but with all the power of EC2 and Docker.

Empire is targeted at small to medium sized startups that are running a large number of microservices and need more flexibility than what Heroku provides. You can read the original blog post about why we built empire on the Remind engineering blog.

Quickstart

Install

To use Empire, you'll need to have an ECS cluster running. See the quickstart guide for more information.

Architecture

Empire aims to make it trivially easy to deploy a container based microservices architecture, without all of the complexities of managing systems like Mesos or Kubernetes. ECS takes care of much of that work, but Empire attempts to enhance the interface to ECS for deploying and maintaining applications, allowing you to deploy Docker images as easily as:

$ emp deploy remind101/acme-inc:master

Heroku API compatibility

Empire supports a subset of the Heroku Platform API, which means any tool that uses the Heroku API can probably be used with Empire, if the endpoint is supported.

As an example, you can use the hk CLI with Empire like this:

$ HEROKU_API_URL=<empire_url> hk ...

However, the best user experience will be by using the emp command, which is a fork of hk with Empire specific features.

Routing

Empire's routing layer is backed by internal ELBs. Any application that specifies a web process will get an internal ELB attached to its associated ECS Service. When a new version of the app is deployed, ECS manages spinning up the new versions of the process, waiting for old connections to drain, then killing the old release.

When a new internal ELB is created, an associated CNAME record will be created in Route53 under the internal TLD, which means you can use DNS for service discovery. If we deploy an app named feed then it will be available at http://feed within the ECS cluster.

Apps default to only being exposed internally, unless you add a custom domain to them. Adding a custom domain will create a new external ELB for the ECS service.

Deploying

Any tagged Docker image can be deployed to Empire as an app. Empire doesn't enforce how you tag your Docker images, but we recommend tagging the image with the git sha that it was built from, and deploying that. We have a tool for performing deployments called Tugboat that supports deploying Docker images to Empire.

When you deploy a Docker image to Empire, it will extract a Procfile from the WORKDIR. Like Heroku, you can specify different process types that compose your service (e.g. web and worker), and scale them individually. Each process type in the Procfile maps directly to an ECS Service.

Caveats

Because docker run does not exec commands within a shell, commands specified within the Procfile will also not be exec'd within a shell. This means that you cannot specify environment variables in the Procfile. The following is not valid:

web: acme-inc server -port=$PORT

If you need to specify environment variables as part of the command, we recommend splitting out your Procfile commands into small bash shims instead:

web: ./bin/web
#!/bin/bash

set -e

exec acme-inc server -port=$PORT

Tests

Unit tests live alongside each go file as _test.go.

There is also a tests directory that contains integration and functional tests that tests the system using the heroku-go client and the emp command.

To get started, run:

$ make bootstrap

The bootstrap command assumes you have a running postgres server. It will create a database called empire using the postgres client connection defaults.

To run the tests:

$ make test

NOTE: You may need to install libxmlsec1 for the tests to run. You can do this with:

$ brew install libxmlsec1 libxml2 pkg-config

Development

If you want to contribute to Empire, you may end up wanting to run a local instance against an ECS cluster. Doing this is relatively easy:

  1. Ensure that you have the AWS CLI installed and configured.
  2. Ensure that you accepted the terms and conditions for the official ECS AMI:

    https://aws.amazon.com/marketplace/ordering?productId=4ce33fd9-63ff-4f35-8d3a-939b641f1931&ref_=dtl_psb_continue&region=us-east-1

    Also check that the offical ECS AMI ID for US East matches with the one in cloudformation.json: https://github.com/remind101/empire/blob/master/docs/cloudformation.json#L20

  3. Run docker-machine and export the environment variables so Empire can connect:

    $ docker-machine start default
    $ eval "$(docker-machine env default)"
  4. Run the bootstrap script, which will create a cloudformation stack, ecs cluster and populate a .env file:

    $ ./bin/bootstrap
  5. Run Empire with docker-compose:

    $ docker-compose up db # Only need to do this the first time, so that the db can initialize.
    $ docker-compose up

    NOTE: You might need to run this twice the first time you start it up, to give the postgres container time to initialize.

  6. Install the emp CLI.

Empire will be available at http://$(docker-machine ip default):8080 and you can point the CLI there.

$ export EMPIRE_API_URL=http://$(docker-machine ip default):8080
$ emp deploy remind101/acme-inc

Vendoring

Empire follows Go's convention of vendoring third party dependencies. We use the Go 1.5+ vendor expirement, and manage the ./vendor/ directory via govendor.

When you add a new dependency, be sure to vendor it with govendor:

$ govendor add <package>

Releasing

Perform the following steps when releasing a new version:

  1. Create a new branch release-VERSION.
  2. Bump the version number with make bump (this will add a commit to the branch).
  3. Change HEAD -> VERSION in CHANGELOG.md.
  4. Open a PR to review.
  5. Once merged into master, wait for the Conveyor build to complete.
  6. Finally, tag the commit with the version as v<VERSION>. This will trigger CircleCI to:
    • Tag the image in Docker Hub with the version.
    • Build Linux and OS X versions of the CLI and Daemon.
    • Create a new GitHub Release and upload the artifacts.
  7. Update the new GitHub Release to be human readable.
  8. Open a PR against Homebrew to update the emp CLI: https://github.com/Homebrew/homebrew-core/blob/master/Formula/emp.rb

Community

We have a google group, empire-dev, where you can ask questions and engage with the Empire community.

You can also join our Slack team for discussions and support.