I run my code through a continuous deployment system that pushes code that I believe is ready to a testing server where my tests are run. If that goes well, then the code is pushed to a staging server where a similar or duplicate setup of production is orchestrated for each build. Once things look good and pass all the functional, behavioral and other custom automated testing and benchmarking it is automatically pushed out to production. Then production tests are run that are non damaging and check to insure that the new changes are actually implemented, if there are any issues the push can be automatically rolled back along with a report issued on the why it was rolled back along with a listing of any performance or unforeseen security issues that may have occurred.
I will at times have two staging environments if it is a website ( one that uses internal content links and proxies if behind a CDN/proxy service and one that goes through a staging proxy/CDN so I can test for any changes between two. For anything else I like to have an internal and staging setup to insure the probability of a hardware/middleware component causing an issue is decreased.
These multiple environments are little to no issue because they are all automatically setup either from scratch or a pre-built configuration managed image to speed up the orchestration time.