10 ms·
Let's deploy via Git
- tux1968 13y agoI'm a huge Git fan and use it every day, but Git was never designed as a deployment tool. There may be situations where you want the entire history of your development to be included on your live server, but often this just isn't appropriate. Also, when deploying to multiple servers you have to invent adhoc methods to handle configuration differences. Even native ssh seems like a more prudent deployment method than Git. This smacks of using the closest hammer at hand, rather than choosing the best tool.
- kaoD 13y agoI agree on the configuration issue, but you can export the working tree[1] in the hook to avoid including the Git history (and in fact it is a sensible choice). The configuration can be handled in the post-receive hook too. I advise against using Git as a deployment tool for serious development (you should use Puppet instead), but for quick hacking and personal projects it's perfectly fine. [1] http://stackoverflow.com/questions/160608/how-to-do-a-git-export-like-svn-export http://stackoverflow.com/questions/160608/how-to-do-a-git-ex...
- tux1968 13y agoWhen you Git push to a live server as the article in question suggests you're sending the entire repo history not just the latest commit. The remote hook only checks out the latest change, but the entire history is sitting right there on the live server. Which is silliness in most cases. As is suggested in the SO article you link, it's more appropriate to locally export the version you want to deploy and use ssh (or whatever) to transfer it to the live server. Nobody ever seems to try to justify _why_ you would want to use git-push, they just go about explaining how you do it.
- Aqueous 13y agoIn this example they are checking out into a work tree that is detached from the central repo, which is bare (or could be.) Therefore there is no .git directory in the work tree and the history is inaccessible from the outside world. I don't see how having the entire history sitting in a private directory on the server is silly, as long as only you can access it. Honestly we are just talking about transferring files here. However you automate it, as long as it gets the files from point a from point b, is fine. I happen to find it most convenient to use git since that is how I send and receive code changes everywhere else, and it seems foolhardy to introduce another file transferring tool without a really good reason why. Moreover it lets me very easily tell exactly what revision is sitting on the server, and also causes me to pause before I push. It is also really easy to integrate git, through hooks, with a continuous integration setup.
- kaoD 13y ago> _why_ you would want to use git-push Faster deployment. As I said you shouldn't use this for critical services, but it works great for quick hacking. It's also very convenient for non-production (i.e. testing/staging) machines, to automate continuous integration.
- gkop 13y ago> _why_ you would want to use git-push Many of us like to have some recent past releases sitting on the production servers in order to make instant rollbacks if we discover a bug after the code has been deployed. Git provides that for free.
- bradleyland 13y agoThis is almost exactly what Capistrano does. What's hilarious is that this entire thread reads like a discussion that could have lead to the development of Capistrano. * Capistrano can deploy via git (it uses export) * Capistrano keeps a configurable number of releases around in case you need to rollback * Capistrano provides an ordered task system with before/after hooks at every one of its pre-defined tasks * Capistrano can be just as lightweight as using git to deploy: cap deploy git push Two additional characters! * You may not need all the stuff that Capistrano provides today, but as your project grows, you will need it. Why waste your time with a compromised deployment hack when better tools are available and easy to use?
- tacticus 13y agoPuppet does add some significant runtime lag unless you add in other orchestration tools. additionally if operations include cross host dependencies puppet is probably the wrong tool to use.
- snprbob86 13y ago> There may be situations where you want the entire history of your development to be included on your live server, but often this just isn't appropriate. Are you concerned about being wasteful with disk space? Or is there some other concern here? Some security issue perhaps?
- tux1968 13y agoBoth reasons. Mostly it's because it seems people are using Git to deploy without a good reason. At least I haven't heard of an advantage enjoyed by those using Git for deployment. There are some obvious disadvantages, so what is the compensation? It seems the only reason is that it's easy to type "git push". But of course any deployment method can be wrapped in an equally easy script command. Okay, I have to admit to knowing of one advantage, and that is that only the delta of your changes will be transmitted over the wire, rather than a complete checkout. It's just that in practice the savings aren't usually enough to warrant the potential downsides. For my money i'd prefer rsync or any number of other solutions.
- RussianCow 13y agoWhat are the potential downsides? I've been deploying with Git for over a year and am interested in learning why it's not a good idea.
- Marc_Paradise 13y agoSecurity. Are you 100% sure that there is nothing you are exposing via your git repo that you want to keep away from the person who manages to hack your server or discover some means to reach the repo externally? Getting hacked is not inevitable, but if you treat your systems as if it were you'll be a lot safer if it does ever occur.
- zzzeek 13y agoIf you push via git or via rsync, you're typically going over SSH in both cases. As far as the .git directory, my post-receive hook also does a "cp -R" of the files to the actual web-served directory (there's a build step in between anyway), so there's no .git exposed. As far as security, as long as one knows to handle the .git directory, there's no difference.
- Xymak1y 13y agoThe issue here is that there is still numerous web hosts who don't grant you SSH access, so you're not able to set up any git repository there anyway and are still stuck with FTP. Hopefully this will go away soon, or at least more in the direction of Heroku and the likes.
- chris_j 13y agoWhich web hosts are they and what advantages do they have over web hosts that do grant ssh access?
- Xymak1y 13y agoTake Hetzner (large German provider) as an example - while they do offer managed servers and root servers, those are much more expensive. I'm not advocating the use of such products, but merely pointing out that they're still around a lot.
- ahoge 13y agoThey also offer VPS ("vServer") for about 8€/month. You can ssh into those, can't you?
- wise_young_man 13y agoI'm planning on writing about this in more depth later, but this is essentially the route every cloud hosting company is taking right now and I think it's a bad to only allow that kind of deployment. Don't get me wrong, I love Capistrano, git deploy hooks, ruby gems that do deploys (heroku), but most cloud hosts are only offering this mechanism to deploy apps. FTP became popular because of the ease of use for designers and webmasters. You don't always need to deploy your entire application for simple changes. Another big one is the ajax file editor in the browser. For trivial changes a simple file change would suffice. When you do an entire deploy for app like this, depending on your dependencies and payload, it could take a long time. What if you had the wrong price and need to make a change immediately? Of course maybe now there are multiple environments which play a factor too. I do realize that was before we had multiple web servers running the app and that is part of the reason, but there are still ways to make it work (file mounts). I'm hoping more deployment options in the future and that cloud hosts realize the need is still there from traditional hosting.
- sjtgraham 13y ago> For trivial changes a simple file change would suffice. Doesn't scale past one developer or one box.
- wise_young_man 13y agoMy thought is that could work together with other tools. Say you do your next deploy with heroku, it says there are unsaved changes and asks you to first do a 'heroku pull' to pull the changes and you can then commit them or you could blow them away with 'heroku push -f'. I'd say 80% of the sites online are managed by one or two people. They may need the scalability of the cloud for traffic bursts, but we can't say cloud is the future if all of our existing tools and workflows are completely broken. For the past year I was building a cloud competitor to Heroku. We had a traditional host (like HostGator) and we talked to those customers about moving to the new cloud infrastructure and all the benefits to why. Most people said it was too complicated and were stuck in their work flows (FTP and file managers). Which is why I wanted to chime in with FTP is not dead.
- bliker 13y agoI personally prefer git-ftp. It is common that ssh is still only luxury.
- LoganCale 13y agoSeconding git-ftp. I use it almost daily and find it excellent for deploying on shared hosting where ssh either isn't provided or is a hassle to set up. git-ftp is an awesome, awesome tool. https://github.com/resmo/git-ftp https://github.com/resmo/git-ftp
- pvnick 13y agoThis is a pretty neat hack, but not really good for a true production deployment system. Rsync is a far superior alternative. That being said, git should definitely be incorporated into the workflow such that, for example, you have a "live" branch which always reflects what is to be on production frontend nodes. From there you do 1) git pull origin live 2) rsync to live servers 3) build/configure/restart/etc. Set -e on that script obviously... Edit: I should also mention, if you are stuck on something like restricted hosting with CPanel which severely limits your deployment options (some of my clients are in this boat), then http://ftploy.com/ http://ftploy.com/ is a really cool solution. But you should really get your ass off cpanel asap. Double edit: Some of the replies below have made some good points that I had not considered which weaken my argument. So while I'm now more ambivalent than dismissive towards the idea of using git to deploy, there are several modifications that should be made to this particular system to make it production-ready. See avar's and mark_l_watson's comments below and mikegirouard's comment elsewhere for some ideas.
- Aqueous 13y agoI've been using this method of deployment for several production sites for a couple of years now. I don't really see why rsync is better, or how using git is meaningfully different from having a live branch that you Rsync from. As long as you're checking out into a detached work tree it is functionally identical to rsync.
- bretthoerner 13y agoAnd why is rsync superior?
- pvnick 13y agoPart of my reasoning is that rsync is specifically made for this kind of thing, whereas git is specifically made to synchronize coding among multiple developers. So my argument is partly theoretical and less practical. But for an argument based in pragmatism, rsync has tools such as the --delay-updates flag, which allows your entire deployment procedure to become a pass-or-fail atomic operation. This kind of assurance slows my hair loss as a systems administrator. AFAIK git has no such tools, but I'm certainly open to being corrected.
- lifeisstillgood 13y agoAaargh ! Build on a build server Scp to live server along with generated config Install with native package tool and hook into native service manager Use salt / puppet / chef to do everything after initial build on your target servers. Be nice.
- robinson-wall 13y ago> Install with native package tool I'm sad that so few people seem to build native OS packages for deployments. My build system creates a release package and sticks it in an apt repo, then puppet installs latest version of package when it runs.
- AgentIcarus 13y agoI've just started looking at this sort of thing - can I ask what technology you decided on for the apt repo? (I'm especially interested in whether the restriction most of them impose on having multiple versions of a package is something you are dealing with).
- Tobu 13y agoI use mini-dinstall for repos. Multiple versions would complicate things however; I'd probably do it by combining multiple suites.
- robinson-wall 13y agoLate reply, sorry. I went with reprepro to maintain my apt repo. It's nice, but has one major drawback which may be a showstopper, depending on your use case. It can only keep one version of a package at a time in each distribution.
- rdtsc 13y agoSecond that. I think it only comes with maturity. If there is a small start-up and they have a couple of Ubuntu servers they'd start with just syncing their source repo, running 'make && make installs' by hand via ssh. After a while if they use python, node or ruby, maybe start generating language specific packages (pip, virtualenv, etc). Next phase is when the need for upgrade/downgrade transactions comes about, handling transitive dependencies (my package needs another package, which in turn requires a third package to be upgraded, which is a base system package to be upgraded). Now 'make && make install's looks silly and mess up the file system with left-over files. Deployment ssh scripts become a tangled mess and so on. Then slowly they think "It would be cool if there was a system created that can transitively handle package versions, and maybe provide transactions with pre and post install scripts". If they are lucky, someone will point them to apt or rpms or they'll write a broken version of those things from scratch.
- clubhi 13y agoI'm from the 80s. I bet you want to replace me also.
- jebblue 13y agoI'm trying git to get my feet wet with it but man this looks way complicated to me. I didn't even know about "git config" or even that there was a checkout command for git. I usually cd into the directory I want to turn into a repo and use "git init" then after changing files, run gitk or if in Eclipse I use EGit. I'm not even sure what happens in gitk when I do a commit, is it that long "push master origin" stuff? Does that mean master is my local repo and master origin is like the overall master? I guess with SVN it's clear even at the command line but with git there are just so _many_ options. Then there's custom scripts to make all this work? I'll stick with scp or rsync for distribution for now. The author might want to look into Hudson or Jenkins, they work wonders.
- ihodes 13y agoCheck out the git book here: http://git-scm.com/book http://git-scm.com/book Worth the read if you're interested.
- jfdi 13y agoI had written a very similar article a while back which includes some django specific points and is also intended to be really simple to read thru: http://thomaswilley.com/?p=9 http://thomaswilley.com/?p=9
- krapp 13y agoFTP still works. FTP isn't 'broken.' This 'replacement' adds huge unnecessary complexity and doesn't work on nearly as many servers as FTP does (which is all of the servers) And yes, I have deployed with git, so i'm not speaking out of complete backwards ignorance. I can still see a use for both.
- viraptor 13y agoActually it is broken by today's standards. No encryption, two connections, nat issues, no standard (everyone does best-effort output parsing), etc. It doesn't work on "all of the servers" either. All of my servers have ssh/scp available and will never have ftp.
- krapp 13y agoNo encryption What about ftps? two connections Not a problem if you're only occasionally updating one site at a time, though I'd agree it doesn't scale up the way git would. nat issues, no standard valid points. I've never had issues with either but I don't work on the kind of projects a lot of HN users do, so I really tend to only care if it stripped the line breaks or not. it doesn't work on "all of the servers" either. All of my servers have ssh/scp available and will never have ftp. I stand corrected. It is good to actually see the arguments against FTP at least.
- viraptor 13y agoNot sure what's the current state of ftps deployment, but when I checked mid-200X, it was still a very rare occurrence. Maybe it's a bit better now. It's hard to find out from google, because they claim I want to look for "ftp" rather than "ftps" and they're the same thing :/
- jakobe 13y agoI'm not sure I like the approach of serving files from your repository. I'm not sure about how git works in detail, but are repository updates even atomic? When I deploy my website, I use a different approach: My webroot is just a symlink. My deployment script exports the repository to a directory with a unique name for every commit. When the export succeeds, the symlink is updated to point to the new directory. The advantage: Changing to the new version is instantaneous. If something should go wrong, I can immediately revert by changing the symlink back to the old dir.
- gkop 13y agoYou can combine this approach with updating the code with a git pull to get all the benefits of git. Capistrano, the conventional Ruby deploy script, does this by default.
- bluetooth 13y ago> but are repository updates even atomic? No, they are not. During the push, there will be a short amount of time in which some parts of the website will be operating on new code, while others will be operating on old code. If many components are in play (ie using libraries) you may end up breaking things if a new request comes in at the right time.
- gboudrias 13y agoIn the Drupal community, we're all stumbling over each other to find the best Git deployment strategy. I'm surprised that Git deployment would still be news for anyone. I don't know who this article can reach that's not already competent enough to be using Git (at least for dev). On the other hand, if your site is just static (HTML/JS) files, I think it makes great sense to use Git to deploy, as there is no configuration to worry about.
- cpa 13y agoAnd add some directives to your http server to not serve your .git directory, too!
- Tobu 13y agoI had good hopes when I saw `core.worktree`, but that was just cargo-culting. The right way to do it is to set the worktree to an outside location.
- mikegirouard 13y agoI use git to deploy about 30 sites and have found it to be a really useful workflow. It's particularly useful over SSH when using key-based authentication. For my post-receive hook, I always add a tag to mark a deployment: git tag deployment-`date +'%Y%m%d%H%M%S'` You can see all past deployments with a git log: git log prod/master --oneline --decorate On all my developer machines, I have them add a `git-deploy` script to their $PATH, which looks a little something like: #!/bin/bash git push $1 +HEAD:master git fetch $1 You can just run `git deploy prod` (assuming your deployment repository is named 'prod'). The extra `git fetch` will pull down the auto-generated tags so you can see them locally w/a simple `git tag` Edit: Forgot to mention, that since git ships w/a bash shell for Windows, most of this should work for Windows-based dev setups as well.
- avar 13y agoYou might be interested in checking out git-deploy. It's a tool we wrote to manage tag creation and completely pluggable rollouts/rollbacks with sync hooks you write: https://github.com/git-deploy/git-deploy https://github.com/git-deploy/git-deploy It's basically a more advanced version of what you're doing.
- huhtenberg 13y agoPedantic nitpick - git remote add origin git push origin master It shouldn't be called "origin", because it isn't really an origin. A more fitting name would be "live".
- crististm 13y agoYeah, Python and other technologies are also 90's or even older - what is your point? Proven technologies that work are belittled to promote today's agenda? I would tend to dismiss this kind of articles and suggestions even if they are OK - only because they promote by appeal to a fashion.
- stevewilhelm 13y agoOr use Heroku.
- andyhmltn 13y agoThat's no way to fix a problem
- wubbfindel 13y agoHere's one reason not to use git for deploy - if you don't want your source code on production servers where clients can access it, or where it could be found by hackers. I work on a closed source system, so we will never deploy our code via git and then build on the server. So, in this case build locally (or on a build server), and rsync from there using deploy scripts.
- inthewind 13y agoThat's all well and true, but you could export and build, then use Git for deployment instead of Rsync (if you wanted to.)
- macnix 13y agoI came up with deliver https://github.com/gerhard/deliver https://github.com/gerhard/deliver to address this very problem. It's bash utility that automates git-based deploys and comes with pre-built strategies for the most common deployment scenarios: generated sites (think Jekyll), shared (WordPress, PHP etc.), ruby, node-js, S3 etc. I did a talk on it at my London Ruby User Group in March: https://speakerdeck.com/gerhardlazu/deliver https://speakerdeck.com/gerhardlazu/deliver
- zrail 13y agoThat's very cool. I really dig the minimalism of it. I'm currently using a system that involves about the same amount of config and leans on Capistrano for the heavy lifting, but I think I might investigate using deliver for my next project.
- darkstalker 13y agoDon't forget to hide your .git directory. You could accidentally expose all your source code to the web.
- Wintamute 13y agogit push/pull is easy, but there's no getting around the fact that Git is a distributed version control tool, not deployment software. Using Git for deployment is probably fine for simple deployments where you're just getting a bunch of static files onto a single box, but as soon as you stray into the realm of non-trivial web application deployments then things change. Factors like database migration, dev/prod environment parity, dynamically spinning up new server instances and continuous integration etc. mean that the act of simply copying your files become the least of your worries. Sure Git will play an important part in getting a snapshot of the codebase from a dev's workstation into the deployment flow, but that's where it ends and tools like Chef and Puppet take over.
- EnderMB 13y agoMy thoughts exactly. This workflow is nothing more than hacking Git using post-commit hooks to do something it was never built for. If you want to deploy using Git then the smart thing to do is to use one of the many continuous integration tools out there that were built specifically for this kind of workflow. I use TeamCity to run my tests and to build/deploy my website whenever I push to my default branch. This works really well for some of my sites, and although I'm looking for a way to refine this so I can also deploy database changes between local/staging/web servers I can't think of a better way of doing this.
- jpb0104 13y agoI'm surprised Fabric [http://fabfile.org http://fabfile.org] has not been mentioned in this thread. I'm not a Python developer but I love Fabric specifically for a tool to handle deploying code. If you feel like a Git deployment is lacking, be sure to check out Fabric, especially for multi-server deploys.
- Ixiaus 13y agoFabric is great for running commands. But what a lot of programmers do not realize is that deployment is a process. That process involves running automated tests, packaging all of the assets, using package managers to upgrade/downgrade based on versioned release schemes, database migration, post-upgrade scripts, and quick/painless rollback (downgrade) if there's a major blocking bug for users.
- hmind 13y agoAnd here I was thinking that this was obvious and most people used something like Capistrano... It's shocking to me the amount of people not using some sort of SCM-based deployment method. =P
- jasonlotito 13y agoI'm more surprised that people aren't using something more reliable and proven, like the package manager their system already uses. Why introduce another piece?
- klj613-- 13y agogit is a SCM and should not be on production systems. instead you should have a build server which builds up a package (rpm, deb, tarball?) which is then used to deploy across the production environments. you should also not compile JS/CSS etc on production system that is what the build server is for. anything installed on a production system should be 'required' for the app to actually run. - that said, you can use capistrano (and other tools like this) to update 'demo' environments and dev environments (with git) however the actual TEST and STAGING environments should mirror the PROD environment (packaging).
- j-kidd 13y agoOn one end, you have stone age developers who need Visual Studio on production systems because that's the only tool they know. On the other end, you have hipster developers who need Git on production systems because that's the only tool they know.
- nodesocket 13y agoShouldn't it be: git --bare init On the server?
- tgasson 13y agoNo, because it needs to be checked out (that's the deployment). As a usual git server, yes --bare is the way to go. In this case you could alternatively use --bare in a ~/repos/example.com dir and set the $GIT_WORKING_DIR environment variable to ~/www/example.com for checkout.
- krallja 13y ago> (Remember, ^D is Control+D, or whatever your shell's EOT character is.) Use a heredoc http://tldp.org/LDP/abs/html/here-docs.html http://tldp.org/LDP/abs/html/here-docs.html
- zobzu 13y agomake a tag, push the tag, at least.. at the very least :P
- jackbauer 13y agogit push. no no rather tag and checkout/sync etc
- chadfowler 13y agoA beautiful thing that this demonstrates is that no matter how old a concept is, there's always room to explain it clearly so that those who didn't already understand it have the benefit of finally being enlightened. I learned this many years ago as an author, thinking that my most basic ideas weren't worth writing down. It turns out that what's obvious to one person isn't obvious to everyone else. Thanks for the reminder and for the clear explanation of how git deploy might work!
- miog 13y agoBalls of steel deployment
- dutchbrit 13y agoTerrible idea..
- inthewind 13y agoWas looking for an email address for the author! And failed. Anyway just wanted to comment - that there's no publish date attached to the article - or one that is at least obvious. I have no idea when it was authored.