Is using Git for deploying a bad practice?
I tend to use Git for deploying production code to the web server. That usually means that somewhere a master Git repository is hosted somewhere accessible over
ssh, and the production server serves that cloned repository, while restricting access to
.gitignore. When I need to update it, I simply pull to the server's repository from the master repository. This has several advantages:
- If anything ever goes wrong, it's extremely easy to rollback to an earlier revision - as simple as checking it out.
- If any of the source code files are modified, checking it as easy as
git status, and if the server's repository has been modified, it will be come obvious the next time I try to pull.
- It means there exists one more copy of the source code, in case bad stuff happens.
- Updating and rolling back is easy and very fast.
This might have a few problems though:
If for whatever reason web server decides it should serve
.git/directory, all the source code there was and is becomes readable for everyone. Historically, there were some (large) companies who made that mistake. I'm using
.htaccessfile to restrict access, so I don't think there's any danger at the moment. Perhaps an integration test making sure nobody can read the
.git/folder is in order?
Everyone who accidentally gains read access to the folder also gains access to every past revision of the source code that used to exist. But it shouldn't be much worse than having access to the present version. After all, those revisions are obsolete by definition.
All that said, I believe that using Git for deploying code to production is reasonably safe, and a whole lot easier than
ftp, or just copying it over. What do you think?
Wouldn't standard practice have your git repository exist one level up from your htdoc folder so accidentally serving it out wouldn't happen?
That's a good suggestion, and I'm doing just that for a latest personal project. But on another project my clients repository is organized differently (with htdoc being at the root of repository), so the question still applies.
How do you ensure changes made after you deploy to test won't get deployed to production?
So far I didn't have a chance to work in a team with dedicated testing server and QA (probably bad). I test thoroughly on the dev machine and only deploy new features in specific iterations. Then if there's a need for a bugfixes until the next iteration, they are done on a separate branch. E.g., version 0.6 is released, work started on 0.7. Bug is found on 0.6, fix applied in a branch 0.6 and merged into a master branch. Production then pulls branch 0.6. And until 0.7 is released, all fixes go first into branch 0.6. Sometimes (not always) I create a separate branch for production version ahead
In a traditional enterprise environment this practice would be treated with scorn. Still, as you say, there are few technical problems with it. In fact, the more general approach of deploying quickly and often is gaining traction. It even has its own buzz word: Continuous Deployment
You could always use a Package Manager suite like Gradle, Maven, Etc to deploy your files to the HTDOCS folder so you specifically ignore ./git, etc. Update your GIT on the server in a separate folder, than run you PM to deploy it to the proper location. It's why they exist.
I'm surprised that the security issue you're concerned about is the .git folder, while I would actually be more afraid that such process means your git credentials are stored on the web server and so, if a breach exists in your website, then anyone can access the Git repository (let's hope these credentials are read-only tho)
I would go as far as considering using git for deployment very good practice.
The two problems you listed has very little to do with using git for deployment itself. Substitute
.git/for the config file containing database passwords and you have the same problem. If I have read access to your web root, I have read access to whatever is contained in it. This is a server hardening issue that you have to discuss with your system administration.
git offers some very attractive advantages when it comes to security.
You can enforce a system for deploying to production. I would even configure a
post-receivehook to automatically deploy to production whenever a commit to
masteris made. I am assuming of course, a workflow similar to git flow.
git makes it extremely easy to rollback the code deployed on production to a previous version if a security issue is raised. This can be helpful in blocking access to mission-critical security flaws that you need time to fix properly.
You can enforce a system where your developers have to sign the commits they make. This can help in tracing who deployed what to production if a deliberate security flaw is found.
Nice answer, I am really looking forward to using git in my production servers! However, I'm reluctant to use automatic push as you (and several others I read) suggested. Automatic push can change your production server when you don't want to, and you could accidentaly leave your server offline. Maybe I'm missing something and overcomplicating matters, but I prefer the paranoic approach of ssh'ing into the production server, do a `git fetch origin master`, then `git diff master origin/master`. Only then I would do `git merge origin/master --ff-only`. Do you have any thoughts about this matter?
@pedromanoel I subscribe to the school of thought where anything you push to master should be production ready so that shouldn't really be a concern. What you are suggesting works as well.
Our master branch commits deploy to the Dev Web server. We have a QA, Staging and Production branch that map to their respective environments. When we want to release to production we simply have to merge in the tested code into the production branch. This has worked well for us. We use KUDU for this. Not sure what other tools are available.