Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

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 .git/ and .gitignore. When I need to update it, I simply pull to the server's repository from the master repository. This has several advantages:

  1. If anything ever goes wrong, it's extremely easy to rollback to an earlier revision - as simple as checking it out.
  2. 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.
  3. It means there exists one more copy of the source code, in case bad stuff happens.
  4. 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 .htaccess file 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 rsync, ftp, or just copying it over. What do you think?

share|improve this question
8  
Wouldn't standard practice have your git repository exist one level up from your htdoc folder so accidentally serving it out wouldn't happen? –  Fiasco Labs Nov 14 '13 at 8:13
    
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. –  Septagram Nov 14 '13 at 8:20
    
How do you ensure changes made after you deploy to test won't get deployed to production? –  Graham Hill Nov 14 '13 at 10:05
1  
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 –  Septagram Nov 14 '13 at 10:38
    
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 –  paj28 Nov 14 '13 at 12:47

4 Answers 4

up vote 21 down vote accepted

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.

  1. You can enforce a system for deploying to production. I would even configure a post-receive hook to automatically deploy to production whenever a commit to master is made. I am assuming of course, a workflow similar to git flow.

  2. 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.

  3. 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.

share|improve this answer
    
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 Jun 11 at 13:07
    
@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. –  Terry Chia Jun 17 at 11:51

There's nothing wrong with deploying from a git repo, in fact it's a pretty common practice and as you say a lot less prone to errors than copying files over ftp or rsync.

Given the information you've provided I'd note the following points:

  • Don't just pull in the latest master. Production should be deployed from a release tag. Use git flow or similar to get a little more process around the deployment of the code and creation of the tags. Because tags are an immutable reference to your code at a given time it's more stable than pointing to a master branch that could be updated by an errant commit.

  • As for serving the .git directory this shouldn't be a big issue. Just redirect anything prefixed with .git to a 404 in .htaccess.

  • Your git authentication should be ssh key based so no repo passwords need to be stored on the server.

Hurray for git deployment workflows!

share|improve this answer

You can use the --separate-git-dir=<git dir> argument when calling git clone. This will place a symbolic link in the .git directory (symbolic to Git, I don't think it's a symbolic link to your OS), and you can specify the <git dir> to somewhere outside of the document root.

share|improve this answer

Here is the script I use to make git to push to prod.

https://gist.github.com/Zamicol/d9fac0c7857e1085f767

It assumes that anything pushed to the master branch is ready for production. All other pushed branches are ignored. You can modify this hook script to suit your needs.

As far as your concerns, I place my git directory under /var/git and my production files somewhere else (like /var/www) and restrict access to these directories.

You could also have your git repo on a separate server from your production server and then use something like scp and ssh in the script above to move your files from the git server to the production server. This would allow you to still use git to push to prod while keeping your code separate from your production.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.