Solid Python Application Deployments for Everybody¶
Date: | 2013-03-16 |
---|---|
Speaker: | Hynek Schlawack |
Slides: | http://ox.cx/d |
Warnings¶
- Heavy Opinions ahead
- We’re not talking about PaaS, schema migrations
Key Concepts¶
- Responsible Deployment Cycle
- Easy != Simple
- “Simplicity is a prerequisite for realiablity.” - Dijkstra
- ”... and security.” - Every security expert ever
- Put effort into making your deployments simple.
Development¶
- Always develop your app on the target platform
- Avoid inevitable differences!
- See: Vagrant - Maci VM tool for devs.
- What if?
- Target platform: CentOS 5 (python 2.4.3 =( )
- “Python 2.4 is not supported. It came out 8 years ago. Upgrade.” - Kenneth Reitz
Stability¶
- You want a stable platform. Key infrastructure?
- Use pre-built packages?
- NO!
- Unless you’re writing a package FOR a distribution.
- System packages are often spotty, usually outdated
- Use virtualenv!
- Pin your deps hard: “Djang==1.4.3”
- Don’t rely on SemVer!!
- Update w/ pip-tools
Security¶
- It’s your job, no one else knows the app like you do.
- You must be responsible for your own service.
Deployment Prequisites¶
Package it!¶
- Git + Fabric is “cool” but not stable.
- Why?
- Build tools on production services could be dangerous
- resources
- exploitation
- Repetitive (compiling C extensions on every server? zzz)
- Duplication
- Build tools on production services could be dangerous
- Use native packages (.rpm, .deb, .pkg)
- You can tell “this server is on this version”
- Introspection
- CM integration
- Versatility
- You want reproducabliity.
- So you can scale.
- Use FPM
- You don’t want to run your own repo server?
- Use CLI tools (
rpm -i
,dpkg -i
)
Workflow¶
- check outfrom git
- create virtualenv
- install deps
- do whatever you want
- profit
- Abuse the Pipeline?
- Run tests
- less/sass/cofeescript
- compression
- cache busting
Automate!¶
Deployment (see his blog post):
from _ import Deployment def deb(branch=None): deploy = Deployment('whois', build_deps=['libp-dev'], run_deps=['libpq5']) deploy.prepare_app(branch=branch) # ...
Parcel: 3rd party lib for x-platform packaging
Configuration¶
- Don’t put your configs in the package
- Use config mgmt
- Declarative, describe the goal
- Let CM choose the path
- Salt, Puppet, Chef, etc.
- Not easy, make an informed choice.
Security¶
- Never use the same credentials between dev and prod.
- You know, just in case.
- Never run anything as root. Seriously, just don’t.
- Priveleged ports (<1024)? Drop privs after launch, use authbind.
- Use single purpose wokrers (celery, rq)
- e.g. “User creation worker”, “Service restarting worker”
- Isolate volatile tasks where logical
- Be paranoid.
- Use iptables to lock down everything
- Use file sockets (file perms), no listening ports.
- Each app should have its own user/group
- Set shell to
/bin/false
- Use fail2ban
- Set shell to
- Each app should have its own datbase and user
Test it in Staging¶
- Staging must be an exact replica of production environment
- Same platform, versions, etc.
Stability¶
- Don’t run it in foreground using screen/tmux!
- Daemonize everything
- upstart (Ubuntu)
- systemd
- supervisord
- circus
- Apache + mod_wsgi is not your only choic!
- mod_wsgi is overkill for most cases
- (uWSGI or NGiNX) + gunicorn have better separation of duties
- HTTP: uWSGI/nginx
- WSGI: gunicorn
- ssl, http -> https rediction, headers, etc.
Actually Deploying¶
- Given you’ve done everything above...
- ... Once you get to this point, it should be easy.
- It didn’t work. Undo! Undo! Rollback! Oh no!!
- Should also be as easy as reverting the package.
Metrics¶
- Predict problems before you have to solve them
- Choices:
- statsd
- graphite
- ganglia
- scales
- StatHat
- MEASURE ALL THE THINGS
- CPU, memory, requests in/out, db calls, login failures, etc.
Monitoring¶
- Pingdom, Nagios, etc.
- Alerting/reporting