docker deployment
current deployment
- Build an DEB
- Deploy DEB to test env.
- Run unit and integration tests
- Deploy to each node in production (via chef)
Current deployment
- Development ENV could be not same Production ENV and Test
- Even if your code is perfect, deployment might fall
- More work done on start-up (via chef-boot)
- Not FAST!
- Slower,error-prone , runtime dependency (chef,apt,pypi)
- Chef or Debian repo. could be down
Deployment w/ Docker
- Build docker container for application
- Dependencies in Dockerfile
- Without config/env
- Build/Run/Test container with TEST env. (CI tool)
- Push docker container image to registry
- Pull docker container on each node
- "Paramertized containers" using environment variables
- Run docker container
Common environment
config
An app’s config is everything that is likely to vary between deploys (staging, production, developer environments, etc).
- Resource handles to the database, Memcached, and other backing services
- Credentials to external services such as Amazon S3 or Twitter
- Per-deploy values such as the canonical hostname for the deploy
Config
"The twelve-factor app stores config in environment variables (often shortened to env vars or env). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard."
"Paramertized containers" using environment variables
FiG : Fast, isolated development environments using Docker
Dockerfile
FROM orchardup/python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
fig.yml
web:
build: .
command: python app.py
ports:
- "5000:5000"
volumes:
- .:/code
links:
- redis
redis:
image: orchardup/redis
FIG : FAST, ISOLATED DEVELOPMENT ENVIRONMENTS USING DOCKER
app.py
from flask import Flask
from redis import Redis
import os
app = Flask(__name__)
redis = Redis(
host=os.environ.get('REDIS_1_PORT_6379_TCP_ADDR'),
port=int(os.environ.get('REDIS_1_PORT_6379_TCP_PORT'))
)
@app.route('/')
def hello():
redis.incr('hits')
return 'Hello World! I have been seen %s times.' % redis.get('hits')
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
FIG : FAST, ISOLATED DEVELOPMENT ENVIRONMENTS USING DOCKER
fig.yml (for production?)
web:
build: .
command: python app.py
ports:
- "5000:5000"
environment:
REDIS_1_PORT_6379_TCP_ADDR : 192.168.100.45
REDIS_1_PORT_6379_TCP_PORT : 6379
Connector agnostic containers
Cross-Host linking using Ambassador Containers
Linking containers is only in same host (now)
(consumer) --> (redis-ambassador) ---network---> (redis-ambassador) --> (redis)
Docker Deployment Tools
- Helios (spotify) : https://github.com/spotify/helios
- drone.io (CI) : https://github.com/drone/drone
- shippable (CI) : https://www.shippable.com/
- Centurion(newrelic) : https://github.com/newrelic/centurion
- fleet(coreos) : https://github.com/coreos/fleet
Docker Performance
Startup Time
Building images
docker performance
Installing image
docker benchmark
docker performance
- CPU Performance
- = Native Performance
- Memory Performance
- = a few % shaved off for (optional) accounting
- Network and Disk I/O Performance
- = small overhead ; can be reduced to zero
docker Misconception
" Your systems need to already be in fine working order before you even consider using Docker in production."
- secured least-privilege access (key based logins, firewalls, fail2ban, etc)
- restorable secure off-site database backups
- automated system setup (using Ansible, Puppet, etc)
- automated deploys
- automated provisioning
- monitoring of all critical services
- and more (documentation, etc)