- Adam Wiggins' The Twelve-Factor App
- Modern software design for software-as-a-service
- Heroku enables and enforces these patterns
- One codebase - many deploys
- 2 million releases in Feb alone
- 600 "kernel" releases in Feb alone
- 2x more Rails than Sinatra
- 3x more Webrick than Thin
- 5x more Thin than Unicorn
- 10x more Unicorn than Puma
- 6 web dynos, 1 data worker, 4 databases
- 1 production DB
- 2 read-only follower DBs
- 1 test DB
- Encrypted
- Stored in Dynamo
$ heroku addons:add heroku-postgresql:dev --version=9.2
Attached as HEROKU_POSTGRESQL_COPPER_URL
$ heroku pg:psql COPPER
=> \i schema.sql
CREATE TABLE
=> create extension pg_stat_statements;
CREATE EXTENSION
https://github.com/nzoschke/apache-http-git https://github.com/kr/heroku-buildpack-inline
$ cat bin/compile
#!/bin/bash
set -x
BUILD_DIR=$(pwd)
mkdir -p $BUILD_DIR/src
curl -s http://apache.mirrors.pair.com/httpd/httpd-2.2.24.tar.gz | tar xz -C $BUILD_DIR/src
curl -s http://git-core.googlecode.com/files/git-1.8.1.4.tar.gz | tar xz -C $BUILD_DIR/src
cd $BUILD_DIR/src/git-1.8.1.4
./configure --prefix=/app/vendor/git --without-tcltk
make -i -k
DESTDIR=$BUILD_DIR make -i install
cd $BUILD_DIR/src/httpd-2.2.24
./configure --prefix=/app/vendor/httpd
make
DESTDIR=$BUILD_DIR make install
rm -rf $BUILD_DIR/src
$ cat bin/httpd
#!/bin/bash
PORT=${PORT:-5000}
ROOT=$(cd $(dirname $0)/..; pwd)
export GIT_DIR=/tmp/foo.git
git init --bare $GIT_DIR
git config http.receivepack true
cat >/tmp/httpd.$$.conf <<EOF
CustomLog "/tmp/access_log" combinedio
ErrorLog "/tmp/error_log"
LogLevel debug
SetEnv GIT_PROJECT_ROOT /tmp
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias / $ROOT/vendor/git/libexec/git-core/git-http-backend/
Listen $PORT
EOF
touch /tmp/access_log
touch /tmp/error_log
tail -F /tmp/access_log &
tail -F /tmp/error_log &
exec /app/vendor/httpd/bin/httpd -D FOREGROUND -f /tmp/httpd.$$.conf &
https://github.com/ddollar/anvil
$ heroku build .
Checking for app files to sync... done, 2 files needed
Uploading: 100.0% (ETA: 0s)
Launching build process... done
Fetching buildpack... done
Compiling app...
Success, slug is https://api.anvilworks.org/slugs/cd447c86-528a-4a4b-90e0-3cea29b645e8.tgz
https://devcenter.heroku.com/articles/labs-pipelines
$ curl -vX POST https://cisaurus.herokuapp.com/v1/apps/heroku-secrets/release \
-H "Content-Type: text/json" \
-u ":$HEROKU_API_KEY" \
-d '{"app":"heroku-secrets", "description":"foo", "slug_url":"https://api.anvilworks.org/slugs/cd447c86-528a-4a4b-90e0-3cea29b645e8.tgz"}'
< HTTP/1.1 202 Accepted
$ heroku run bash
~ $ du -sh
5.2M .
~ $ hostname
eb34173c-733e-4d38-9b30-7f9d356fc554
~ $ echo $PORT
22728
~ $ /sbin/ifconfig | sed -n 's/.*inet addr:\([0-9.]\+\)\s.*/\1/p' | head -1
10.29.141.197
~ $ curl ifconfig.me/host
ec2-54-234-58-59.compute-1.amazonaws.com
~ $ bundle exec irb
$ heroku run bash
Running `bash` attached to terminal... up, run.8679
Sometimes I wonder if I'm in my right mind. Then it passes off and I'm
as intelligent as ever.
-- Samuel Beckett, "Endgame"
~ $
$ cat $HOME/.profile.d/fortune.sh
#!/bin/bash
ruby <<'EOF'
contents = Dir["/app/vendor/usr/share/games/fortunes/*"].map { |f| File.open(f).read }
fortunes = contents.map { |f| f.split("\n%\n") }
puts fortunes.flatten.shuffle[0]
EOF
- 56.5 million unique runs in February alone
- 75000+ instances and counting in Heroku's production cloud life
https://devcenter.heroku.com/articles/labs-https-drains
- HTTP Drains
- L2met Server / Service -> Librato, etc.