8. Clone repository
docker build
- Install RubyGems
- Install NPM Packages
- Compile static assets
- Seal Docker image
docker push
- Upload to Docker Registry
Building a Rails Container
9. Inertia
You get used to it
Your build time only goes up
Number of workers only goes up
“Our build is complex”
“We already use Docker, the Cloud. This is as fast as it gets!”
“It is automated, we don’t care it takes 30 minutes”
“The XYZ team should fix it”
10. it was a reality check
20 minutes per build
Flakiness
Resource Starvation
Really expensive
* where do you put secrets??????
11. Why is it slow?
push
webhook
worker bootstrap
docker build cache not
reused between builds
cold asset precompilation
2nd build
22. Locutus trade offs
FAST
Local caches
Secure
Stable
But needs love
We need to maintain:
Infrastructure
Orchestration
Web UI
Scripts Copy & Pasta
Dockerfiles / Buildpacks :(
Troubleshooting :(
24. Provider agnostic
Disposable
Secure
Sandboxed Docker Daemon (dind)
Pre-made recipes
Buildpack
Dockerfiles
Locutus Assembly
Pipa: Requirements
Build whatever you want
Cache whatever you want
Repeatable
Run locally if needed
As fast as Locutus
25. Is there an app fo dat?
Orchestration / UI
Docker first
On-premise
Worker fully sandboxed
Concurrency Primitives
“Only 3 builds for app X at same time”
Parallelism
“Send job to 30 workers”
26. Buildkite
On-premise
Orchestration *only*
Github Hooks
UI / Reporting
API
Agent is a single binary (Go)
Also distributed as docker container
Concurrency Primitives
Parallelism
Per Build artifacts
Per Build shared key-value store
Switch workers!!
No batteries included … on purpose
27. Buildkite Pipeline Sample - buildkite/sample-pipelines
Waits for previous step
to complete
Requires Interaction
UI/API/slack
Branch filtering
37. Provider agnostic
Disposable
Secure
Sandboxed Docker Daemon (dind)
Pre-made recipes
Buildpack
Dockerfiles
Locutus Assembly
Pipa: Requirements
Build whatever you want
Cache whatever you want
Repeatable
Run locally if needed
As fast as Locutus
42. Using it
Everything is namespaced!
pipa cache pull /tmp/artifacts
pipa build --if base -- docker build -t $PIPA_IMAGE_FULL_NAME .
pipa image exists --local --tag base
pipa image exists --remote --tag base
Downloads s3://artifacts/app_group/app_env/app_name/cache.tar to /tmp/artifacts
Only runs command if registry/app_group/app_env/app_name:base exists
Checks if registry/app_group/app_env/app_name:base exists (locally/remotely)
43. Pipeline Inference
How should pipa build your app?
Customize it in your repo; or
Select a template; or
Let pipa figure it out!
47. Pipeline Selection
Custom script in repo
Custom pipeline in repo
Default pipeline in repo
User requested specific pipeline
Check for common file locations
repo/Dockerfile? -> docker
repo/borg? -> borg
Default to Heroku Buildpack
PIPA_PIPELINE_CMD
PIPA_PIPELINE_FILE
PIPA_PIPELINE_TEMPLATE
repo/.buildkite/pipeline.yml
50. Provider agnostic
Disposable
Secure
Sandboxed Docker Daemon (dind)
Pre-made recipes
Buildpack
Dockerfiles
Locutus Assembly
Pipa: Requirements
Build whatever you want
Cache whatever you want
Repeatable
Run locally if needed
As fast as Locutus?
Git
well understood
BB no search
CI
Lots of players
Support a lot of use cases ( too generic )
Similar to Capistrano
Do you trust 3rd party systems with your credentials?
Variance due to hardware, network, load, time of day
Rails asset fingerprint
Infrastructure: it can be better
Build/Dockerfile: it can be better
Cache affinity
Up/down when we want
Maintenance when we want
Already way more cost effective than 3rd party
The standard
No issues at all wrt space, but server will have to download all that
Convention
docker run + commit trick
Throwaway precompile
Precompile /artifacts is an external volume
Compile /artifacts is copied into the image
Disposable = Troubleshoot on the side
Repeatable = many envs, PCI compliance
Artifacts = tests with phantomjs screenshots
Command and control botnet
QMail, runit, and others
Normalize
Rewrite env vars
Rewire signals
Cobra couldn’t use env vars as defaults
Isolated all things required to “build” and “test” containers
Image = docker way is to pull & check exit code
Treediff = has to be done via checksums, size is bad