piku/DESIGN.md

89 wiersze
3.8 KiB
Markdown
Czysty Zwykły widok Historia

2016-03-28 17:10:07 +00:00
# Design Notes
The idea behind `piku` is that it provides the simplest possible way to deploy web apps or services. Simplicity comes at the expense of features, of course, and this document tries to capture the trade-offs.
2016-03-28 22:28:38 +00:00
## Why uWSGI
2016-03-28 17:10:07 +00:00
Using [uWSGI][uwsgi] in [emperor mode][emperor] gives us the following features for free:
2016-03-28 22:28:38 +00:00
* Painless Python WSGI and `virtualenv` integration
2016-03-28 17:10:07 +00:00
* Process monitoring, restarting, basic resource limiting, etc.
2016-04-02 19:16:44 +00:00
* Basic security scaffolding, beginning with the ability to define `uid`/`gid` on a per-app basis (if necessary)
2016-03-28 17:10:07 +00:00
2016-03-28 22:28:38 +00:00
## Application packaging
An app is simply a `git` repository with some additional files on the top level, the most important of which is the `Procfile`.
### `Procfile` format
2016-03-29 21:06:53 +00:00
`piku` recognizes three kinds of process declarations in the `Procfile`:
* `wsgi` workers, in the format `dotted.module:entry_point` (Python-only)
* `web` workers, which can be anything that honors the `PORT` environment variable
* `worker` prcesses, which are standalone workers
So a Python application could have a `Procfile` like such:
```bash
wsgi: module.submodule:app
worker: python long_running_script.py
```
...whereas a generic app would be:
```bash
web: embedded_server --port $PORT
worker: background_worker
````
Any worker will be automatically respawned upon failure ([uWSGI][uwsgi] will automatically shun/throttle crashy workers).
2016-03-28 22:28:38 +00:00
2016-04-02 19:16:44 +00:00
## `ENV` settings
Since `piku` is targeted at [12 Factor apps][12f], it allows you to set environment variables in a number of ways, the simplest of which is by adding an `ENV` file to your repository:
```bash
SETTING1=foo
# piku supports comments and variable expansion
SETTING2=${SETTING1}/bar
# if this isn't defined, piku will assign a random TCP port
PORT=9080
```
Environment variables can be changed after deployment using `config:set`.
2016-03-28 22:28:38 +00:00
## Runtime detection
`piku` follows a very simple set of rules to determine what kind of runtime is required:
1. If there's a `requirements.txt` file at the top level, then the app is assumed to require Python.
2. _TODO: Go_
3. _TODO: Node_
4. _TODO: Java_
2. For all the rest, a `Procfile` is required to determine the application entry points.
2016-03-28 17:10:07 +00:00
## Application isolation
Application isolation can be tackled at several levels, the most relevant of which being:
* OS/process isolation
* Runtime/library isolation
For 1.0, all applications run under the same `uid`, under separate branches of the same filesystem, and without any resource limiting.
2016-03-28 22:28:38 +00:00
Ways to improve upon that (short of full containerisation) typically entail the use of a `chroot` jail environment (which is available under most POSIX systems in one form or another) or Linux kernel namespaces - both of which are supported by [uWSGI][uwsgi] (which can also handle resource limiting to a degree).
2016-03-28 17:10:07 +00:00
As to runtime isolation, `piku` only provides `virtualenv` support until 1.0, and all Python apps will use the default interpreter (Go, Node and Java support will share these limitations in each major version).
Supporting multiple Python versions can be done by deploying `piku` again under a different Python or using `pyenv` when building app environments, which makes it a little harder to manage using the same [uWSGI][uwsgi] setup (but not impossible).
2016-03-28 22:45:35 +00:00
## Internals
2016-04-03 16:33:38 +00:00
`piku` uses two `git` repositories for each app: a bare repository for client push, and a clone for deployment (which is efficient in terms of storage since `git` tries to use hardlinks on local clones whenever possible).
2016-03-28 22:45:35 +00:00
This separation makes it easier to cope with long/large deployments and restore apps to a pristine condition, since the app will only go live after the deployment clone is reset (via `git checkout -f`).
2016-03-28 17:10:07 +00:00
[uwsgi]: https://github.com/unbit/uwsgi
[emperor]: http://uwsgi-docs.readthedocs.org/en/latest/Emperor.html
2016-04-02 19:16:44 +00:00
[12f]: http://12factor.net