Git-based fabric deploys are awesome
dan.bravender.us
dan.bravender.us
One other valid problem I've heard raised about git-based
deploys is that you can end up with cruft in your working
copy that sticks around like .pyc files where the
original .py file is deleted and there is the chance that
this file could still be imported even though the
original .py was deleted.
I'm shocked. If a py file is modified, the pyc is rebuilt. So we know it's poking at the original source file. Why not fail to import if the original source is missing?Maybe this behavior is meant to support binary-only distribution of Python applications, but there really should be an option to override this behavior.
Edit: Did a bit more research and found this:
(1) http://docs.python.org/release/1.5.1p1/tut/node43.html
It is possible to have a file called "spam.pyc" without
a module "spam.py" in the same module. This can be used
to distribute a library of Python code in a form that is
moderately hard to reverse engineer.
Makes sense.(2) http://docs.python.org/using/cmdline.html#cmdoption-B
If given, Python won’t try to write .pyc or .pyo files
on the import of source modules.
So you can mitigate that behavior by removing existing pyc files and using "-B".Removing existing pyc files when deploying sounds sensible, but I'm not sure if -B is really a good idea in this case, as each new worker process will have to parse the code again instead of just using the bytecode.
export PYTHONDONTWRITEBYTECODE=1
may be more convenient than passing -B.as pointed out, hooks are a perfect fit for this.
My solution? Simple, I've got a a Fabric command that deletes all .pyc files in the repo after pulling.
def clean_pyc(): run('find . -name "*.pyc" -exec rm {} \;')
And that's that :)
Hopefully your CI server is building them. Packages (whether native or otherwise) come in quite handy for loads of reasons. Native package managers mature? and have fantastic tools available
Packages do take time to build, but your CI server should be doing that. For most kinds of deployments, you can rely on unix's copy-on-write filesystem by installing the package and then restarting you process manager (ie: supervisor or apache). This means your program is only down between restarts (assuming you have no migrations to apply). The outage due to a deployment is then typically a couple of seconds, assuming your program is quick to start up. This is a sufficiently short downtime period for many situations.
There are lots of additional benefits with using packages, especially native ones, like dpkg/deb. You can add specific dependencies onto the package (for example python 2.7), which will be checked at install time. Multiple language programs are often handled better. The program is easily un-installable. If your CI server is building the package, you can download it for manual testing (for example, for UAT).
RHEL/CentOS 6 uses Upstart (and the next major version will use systemd).
The con is that I dont get a lot of advanced dependency management in case of worker threads, but unless you go to specialized tools like God or Bluepill, it is good enough.
2) What do you do if you have 1,000 servers and your upstart script has to change? Fabric is nice to have in situations like that.
Well before you get to that level you should be using configuration management software (cfengine, puppet, et al.) to handle your servers.
I don't get it. What did they do, that took longer than git commit / git push? It's not like you're compiling anything in python and when you do have deps to compile, they would take that time on deployment anyway.
That gives you a more atomic process and several points to back out gracefully if something goes wrong, without having to worry about *.pyc files or any similar cruft.