I finally started using an IDE (IntelliJ) and was amazed at how much time it saved me on my last project. On my next project I want to keep with the trend of using good tools that will save me time.
I'm setting up my dev environment for a new project and I want to set up my development environment so that I spend more time coding and less time deploying and manually testing. I want to be using tools like Git, Vagrant and all the development things which save time in the long run, once you've invested in learning them.
I want to be able to have a dev environment that runs on my laptop, a staging environment that goes on the web (some integrations such as Facebook are hard to test without a live site; I also want the staging environment to be setup nearly exactly the same as production), and a production environment for release.
There are small changes that are appropriate for dev and staging environments compared to production: don't want the staging environment able to accidentally email actual customers, for instance.
I see the need to have certain places in the code where a different domain name is used depending on what environment the code is running in, or perhaps a mock API gets used rather than the actual API, perhaps emails all get dumped to a testing domain name, etc.
It seems like the safest way is to have code assume it is running in development mode, unless it has been told it is in staging or production.
What good techniques are there to tell code what environment it is running in? Environment variables? Constants included in a library?
And what build tools do people use for things like HTML, where the "compiling" might be putting in production or staging domain names, and perhaps minifying?
I like to edit my code and reload my browser as I develop - perhaps that's a crutch I should stop being used to, but I'd like a workflow that makes it easy to do that.
Also want to make it hard to screw up. I wouldn't want to accidentally deploy code in development mode into production. I've never worked with CI tools, is this a reason people use CI tools, i.e. is that something they help with? Are they worth using when you don't have a large team yet?
Suggestions that work nicely with IntelliJ especially appreciated.
The best strategy is not to tell code what environment it's running in. Let the environment tell the code what it needs to run in that environment.
Your code should never specifically check whether it's in development or staging or whatever. (If it did, you'd need to change your code whenever you added or deleted or renamed an environment). Instead, whenever your code needs to do something that depends on enviroment, it should look at configuration specific to that something. If you need a different asset server in dev and staging and production, define a configuration variable for your asset server and set that variable differently in the different environments. If you have some functionality that should only run in some environments, like sending mail, define a configuration variable that says whether to use that functionality.
Usual ways to define configuration in an environment are environment variables or config files. There is probably some standard way to define configuration in the web framework you're using; if so, use that.
Your code, whether Java or HTML or whatever, should be the same in all environments. You want to write and compile your Java once and use the compiled classes in all environments without rebuilding. Everything that is different between environments should be different in configuration, not code. (No library constants.) So there is no issue about deploying the wrong code to the wrong environment; the code is always the same.
You do need to get the right configuration on to the right environment. How to do that depends on how you do configuration (again, check your framework docs), but it is common to set up the configuration once for an environment by setting environment variables or copying configuration files into place or whatever once and not touching them at all during deployment.
The way to not screw up deployment is to fully automate, so you only have to 'push a button' (really, run a script) to deploy, and there are no manual details to get wrong.
Continuous integration, while essential, and useful even for one person (do you want to have to run your build manually every time?) doesn't have much to do with the bulk of your question. IntelliJ, while great, is not too relevant here either. Your deployment should certainly rely only on command-line tools. Current best practice is to have a full automated test suite for your application, run it automatically in CI and deploy it automatically ("continuous deployment") if the tests pass, but that is definitely getting in to another topic.