This. I'm tired of Django projects not being packaged/released correctly, and deploy scripts that simply git clone in production (yiikes).
This. I'm tired of Django projects not being packaged/released correctly, and deploy scripts that simply git clone in production (yiikes).
I agree the annoyance wrt needing the same environment as the target. We tend to have two platforms that are supported: CentOS 5.x and MacOS. Keeping the build machine on the same platform as the deployment machines is simple. Creating the eggs for MacOS developers is more difficult, but still not too bad. That might seem odd, since we could just use pypi.python.org, but we have an internal PyPi server so that we can easily share internal libraries. Adding a line to a project's setup.cfg makes this trivial for the application developers.
There's another annoyance with sdists. I don't want to compile during deployments. So, I build everything that can possibly be built as an egg as one, and fall back to sdist for everything else. I push those to the internal PyPi server. At deploy time, I create a virtualenv and easy_install the appropriate artifacts. I know the correct artifacts because I `pip freeze` the requirements at build time.
We're also extra paranoid, so our stage and production VPCs are on different AWS accounts. We have one PyPi server per VPC and flow artifacts forward as needed.
> What's wrong with a git clone deployment, why is deploying as a package better, (...)
The advantage is that you can have a release process, where you update the package's __version__, compile/minify the files you need, build documentation, and so on, until you have a deployable branch that you can tag and upload to the repository. This way you have a reproducible history of releases, it's easier to inspect which version is deployed, you have hooks for installation (for instance, you can abort installation if the tests fail on production), etc. Mainly this:
Crank out code -> Run a makefile/fabfile to update version/compile/minify/build whatever -> Export a tag -> Build an sdist/bdist -> Install on production
I believe too many things grew inside Django (e.g. collectstatic) that really shouldn't be part of the framework at all. Another thing that bothers me is South: you need to push a release to production, then run a migration, because the migration is part of the codebase. Well, the migration really should be part of the installation process. There are corner cases where this is an issue - for instance, worker processes reloading before your migration is complete would use the new, wrong model definitions, and suddenly you have a broken release on production.
For all effects, your Django project should just be a valid Python package that you can pip install in a virtualenv inside your server (lets say, /opt/<myproject>) and you're done with it. This way you can freeze the environment on production, pip can handle upgrade/downgrade, you don't have to care about *.pyc hell, etc.
> and how does one implement it correctly?
I should probably upload a project template with a workable setup.py to github.