This is where you write code. The product you're building can be run here, and any changes to it can be tested with minimal delay. Integrations to external services are replaced with mockups or stubs to avoid daily work being interrupted by network issues or server downtime. In particular, any databases are local. However, highly available public services may be used as such.
Continuous Integration (CI) builds your product and runs all automated tests as soon as anything changes in the codebase. Failures are reported immediately. CI also runs end-to-end integration tests.
The Testing environment used by dedicated testers doubles as a production-like playground for developers. External integrations are by default set up to staging-level versions of other services. Developers can experiment with and try out new integrations here—this environment is also known as Integration Testing.
This one's optional. Depending on your approval process, the demonstration environment can be used to allow for stakeholders to review changes on their own schedule before approval for production.
This one goes by many names: staging, QA, or pre-production. If a release breaks something in production, it will break identically here. Thus the staging environment is set up exactly like production (except for necessary configuration parameters), and kept like production between releases. Mysterious production issues can be debugged here. Dedicated testers can also use this environment.
The real deal. Never ever modified in any way without rehearsing in staging first. Regular clean-up is scheduled for accumulating data, such as logs and temporary files.
We've found that this set helps developers to come up with the best technical solutions and resolve issues quickly, and users will only ever notice a new release by the product's increased awesomeness.
Do you think we're missing something essential? Is there something you would leave out?