deis/deis — pull request #2575 by bacongobbler (2014-11-24 20:48:48+00:00)
Title: Proposal: use a Process Manager for Procfile Deployment Workflows

In Deis, there are three different ways to deploy your application:

1. Heroku Buildpack
2. Dockerfile
3. Docker image

For each workflow, we schedule them out by process type. The two default process types are "web" and "cmd". "web" is the process type used for workflows that follow the Heroku model. "cmd" is a special process type for docker images.

In the scheduler, we run the application's image via the command `start `. The `cmd` process type is special, however, which the scheduler sends the command "" which means "please let the docker image determine its own default process type". This is handled by the image's CMD or ENTRYPOINT commands.

Each workflow has its own separate way of handling this `start ` command. For buildpack deployments, the image is based on [slugrunner][slugrunner] which introspects the Procfile and runs the process. For dockerfile deployments, this was handled by [supplying your own start script](http://docs.deis.io/en/latest/using_deis/using-dockerfiles/#define-process-types) which brings up the discussion on how this process is wonky. Docker image workflows have no such concept of process types and therefore do not have a way to utilize this workflow.

With this proposal, I'd like to unify the interface between all three workflows through a process manager.

## What is a Process Manager?

A process manager is a tool used to handle Heroku's workflow from start to finish. However, it also supplies a command which introspects a Procfile and runs specific process types. Some current process managers out there today include [foreman](http://ddollar.github.io/foreman/), [goreman](https://github.com/mattn/goreman/) and [herokuish](https://github.com/gliderlabs/herokuish).

## Why a Process Manager?

Simply put, One Binary to Rule them All. Relying on a process manager means that we can standardize across all three platforms to better improve the workflow for scaling out by process type.

## How will this work?

For buildpack worflows, this dependency will be injected at build-time into the final docker image. When `start ` is called, we can call `process_manager start `.

For Dockerfile workflows, this dependency will be injected at build-time should a Procfile be present in the application directory. For example:

```
><> ls | grep file
Procfile
Dockerfile
```

If a Procfile is present, Deis will then inject two entries into the Dockerfile and copy over a binary into the application directory:

```
cp process_manager $APP_DIR/
echo "COPY process_manager /bin/" >> $APP_DIR/Dockerfile
echo "ENTRYPOINT process_manager" >> $APP_DIR/Dockerfile
```

For Docker image workflows, this means that you must include this process manager inside the docker image in order to handle this workflow. For example, if we were to recommend `goreman`:

```
><> cat Dockerfile
FROM python:2.7
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
COPY . /app # includes Procfile
RUN curl -sSL https://github.com/mattn/goreman/releases/download/v0.0.6/goreman_linux_amd64.tar.gz | tar -xz && \
chmod +x goreman
ENTRYPOINT goreman
```

This way, `start worker` will start the worker process.

# What about `deis run`?

In order for this to work, the process manager must also be able to run arbitrary commands in the absence of `start `. For example, `goreman env` is a valid command which runs `env` and displays its output, exit code etc. This is to handle `deis run` operations which the scheduler sends the raw command as the spawned process.

closes #2545

[slugrunner]: https://github.com/deis/deis/tree/master/builder/slugrunner