Where developers come to connect, share, build and be inspired.

50

FTP is so 90's. Let's deploy via Git instead!

161619 views


Update: This article has been published in Hacker Monthly issue 42.


First, create a directory on your server and initialize an empty git repository. I like to serve my websites from ~/www/, so that's what I'll do in this example.

mkdir ~/www/example.com && cd ~/www/example.com
git init

Next, let's set up your server's git repo to nicely handle deployment via git push.

git config core.worktree ~/www/example.com
git config receive.denycurrentbranch ignore

Finally, we'll set up a post-receive hook for git to check out the master branch so your web server can serve files from that branch. (Remember, ^D is Control+D, or whatever your shell's EOT character is.

cat > .git/hooks/post-receive
#!/bin/sh
git checkout -f
^D
chmod +x .git/hooks/post-receive

Keep in mind that you can add whatever you like to the post-receive hook if you have a build process. For example, one of my sinatra projects uses the following post-receive hook:

#!/bin/sh
git checkout -f
bundle install
touch ~/www/example.com/tmp/restart.txt

Back on your local machine, let's get your git repo ready for deployment.

cd ~/www-dev/example.com
git remote add origin \
ssh://user@example.com/home/user/www/example.com

For the first push to your server, run the following command.

git push origin master

Now, whenever you want to deploy changes you've made locally, simply run the following command!

git push

Comments

  • Ccc2696b05a0650afe3f82375525d754

    This is so wrong. This is looks like PHP-dev discovered git, but didn't read much about it.

    1) If you going to deploy via git, at least do git export. 2) Capistrano exists for a reason

  • Dsc_8066v-square

    This is literally the first straight-forward walkthrough on how to do this that I've seen. Excellent work, man!

  • 3c87f46f8957315b07a64f91723e04e4

    Why even FTP? Just develop live on the web server.

  • 70e1167dbde5397557b0ec6fabb3d90a

    Great method. I prefer using a bare repo outside of my public directory that has its working tree inside the pub directory.

    This way there is no .git dir there and it tells you in pro git that this is the recommended way.

    I made protip about this.

  • User-avatar

    The problem with this is the committed files are updated in a potentially long process, so the application may be broken for a few seconds or minutes if it contained large files.

    I would suggest Capistrano as well or a CI instead depend on the size of the project.

  • 6e1b896f6c4807aa4223acc428c57760

    I came up with 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

  • User-avatar

    Oh, how cool is that? Not really. Used it years ago with subversion and other SCM. You can also use Dropbox and other methods. Your tip is so 2000. But coming back to git or better SCM: never ever use the Master branch. I say never. That is so wrong. Use a dedicated branch or a tag or similar, especially in a multiuser environment. You need someone who has the knowledge who will guarantee, that the final deploy will work. You cannot guarantee that in the master, when several users have write access. You need someone who gives the final go after review.

  • 7dc85c0da8496aa25b227be94fe1c40e

    More tips:

    If you're working with a team and you're the one who deploy the code:

    1. init and setup the deploy server repo

    2. on your git repo, use git remote add deploy %serverdeployurl%

    3. optional: setup a branch for deployment if you have some extra configuration, or just use master. If you use a branch, make sure you checked out the correct branch in post-receive hook

    4. use git push deploy master (or name of your deployment branch)

  • 6f68bcccc0e7a69763df4e6b114fc8db

    Just doing a git pull --rebase in another directory (that isn't your webroot), copy to webroot, then remove the .git/ directory (plus any other sanitizing you'd like) is both low-risk and easy to script via something like Fabric or Capistrano.

  • Fc98a096fb23cd5f5231b4f25abfcd7e

    Awesome tips. Thank you.

  • 2956e2cd2664630aa968b92bbb645f2f

    @gpoulter

    (a) I Haven't looked into multi-server deployment, sorry. (b) Just use git push origin master -f to force when it's not a fast-forward. (c) If there's a build, script it and add it to the post-receive hook. It's just a shell script. (d) That's true, but this assumes all your files are in the git repo. If not, you'll have to update those manually (such as via scp), or add something in the post-receive hook to take care of it.

  • User-avatar

    Using an SCM (be it GIT, svn, hg or whatever) is an excellent means of distributing all kinds of assets - images, control files, scripts. I even know people who keep their .bashrc and .profile files (and other portable tools) in github and pull them down as they move to different client sites. The efficiency that comes with versioning, hosting and accessing through these tools can make you look super-organised

  • 121dcfb4f05ed316247772545e2cd590

    It's pretty cool, although pull deploys scale better. Simples implementation of pull deploy would be with cron job fetching the git repo and more advanced way is to use Chef or Puppet for it, so that you can also introduce configuration changes in line with code changes.

  • Ccc2696b05a0650afe3f82375525d754

    @NARKOZ They actually can be wrong.

  • Ba916cb1c1327b700cf2f753684c2b4f

    To be honest, this feels totally wrong. Writing 15 lines of command-line code, some of them totally cryptic, for a simple deployment, does not feel "simple", clean and professional. I would recommend professional Continious Integration tools and doing deployments with one click/command AND having the possibility to roll-back anytime.

  • C452638be206345b2c22e09031c68f50

    This post-receive hook method is going to cause problems when (a) there is more than one server (a remote for each) (b) the deploy is not fast-forward (conflicts) (c) there is any "build" involved in making the code ready to run (d) there are other artifacts in the working tree not from the code repo that need to be updated as well

  • C5c54a86bda8ef40b570eacf7b9be078

    +1 for the principle. Reminds me of a blog post about using a git repo from blogging. It has all the concepts of editing, posting etc.

  • 723e458e33dea7e25e15e0ae9b1e8782

    Great post. I plan on writing something similar in the future; essentially, how to "roll your own" git deployments.

    For anyone still confused, here's something I wrote that is even more simple and involves much less command line knowledge:

    http://adamjohnsondesign.com/blog/moving-ftp-git-deployment-designers-guide/

  • User-avatar

    It's a good post, but i must ask, why? FTP is in use over Git because it's simple to use, just like Windows is used by the majority even though Linux is technically better.

  • D5036b21a633e42fdef897edfea88b53

    Or Shell script: $ export name=mynewrepo; curl -L -s tiny.cc/gitdeploy

    Save to alias: $ echo -e "\n alias scr='curl -L -s \$1'\n" >> ~/.bashrc $ export name=mynewrepo2; scr tiny.cc/gitdeploy | sh

  • 17a27d13d2195b4d6d273eb18c96d3a1

    Checkout https://github.com/slimjim - my attempt at making this processes a little more easier

  • 144314100b686db946ff68c7ae1065d1

    @andoriyu 99, 400 people can't be wrong.

  • User-avatar

    FTP is dead !!!!! I use a tool ( http://dyndrop.com ) that takes exactly the same thing but even more easily. This is especially useful for my projects that I want to deploy quickly.

  • 44df94106f92a3f506f5ad346918ba8f

    The biggest problem with git is the scalability. We currently use it in an awsautoscaled environment. When the servers come up, obviously nothing is on /mnt. This causes git pack to cause high com and high io in the master as it computes from commit 0. This can be solved using shallow copy, however, there are major bugs with that if you use branches and you risk deploying the wrong code to the wrong server.

    So what is the solution? We are still working on a good one. Right now wend up mounting an nfs mount when the server bootstraps and copy over a base image of the repository avoiding git pack-objects and the delta overhead which goes with it. Is it the answer? No. The hunt for that continues.

  • 2cd3c6586f719bc64a324e8bf2d74333

    Some additional explanation would be helpful.

    • What's the purpose of changing worktree? (I'm unfamiliar with the option, I've never needed to use it.)
    • Why are you calling the server remote origin? Seems more like "destination." (This could be very confusing to people users who aren't that familiar with git remotes.)
    • An explanation of the post-receive hook would be useful (I now get that after pushing you have to checkout on the remote to actually update the working dir but that wasn't immediately apparent).
  • Aa81402492c6d39bc309b2a1b00766e8

    Why wouldn't you just use a tool like Capistrano? Capistrano can deploy from Git as well, but it follows best practices like exporting a bare copy of the repo. It also provides niceties like rollback and ordered tasks (with before/after hooks) for that moment when you realize that you need to do something outside of dumping code in to a directory. Tacking on ad hoc bash scripts is what you do when better tools aren't available.

    I'm all for exploring new ways to do the same old things, but this just strikes me as terribly incomplete and introduces some bad practices, like hosting a full copy of your git repo in the httpd document root.

  • D9314e008d15617514278285a320099a

    I think it makes more sense to deploy onto a stage, and archive the deployment files, then push them to the server in some way that is simple.That way they are assured to have been created.

    We have been using VCS to do deployments of Wow addons for years, that has worked great - but you still have to wait for the built product to be prepared so you can post it ti alternate sites. It is nice though to have your build updated every time you commit.

  • D842ec3b23a23afb16c1bafac0e2a274
    git config core.worktree $(pwd)
    

    Saves some time

  • 1249b517ac30f9a7d5b60049f3e4d972

    This works really well for an event space site I manage. It's a simple site that deploys to two places; one prod server, and github. I have two remotes set up in git config: eg:

    [remote "origin"] url = https://github.com/natalieolivo/suite116.git fetch = +refs/heads/:refs/remotes/origin/ [remote "prod"] url = "ssh://suite116@suite116.com/var/chroot/home/content/33/7051533/html" fetch = +refs/heads/:refs/remotes/prod/

    So when I need to deploy to the prod server I do a "git push prod". When I deploy to github I just do a "git push". No more ftp!

  • 1c5643af128c7ebffee890d24aefbdb8_normal

    Love it, nice job with this.

  • F357a1149b38270ad0d3aa0ec70aef0d

    it works with GoDaddy Shared Hosting (note: GoDaddy Shared hosting is come with git v1.8)

  • Fc40847cc8bfa2442e47afb4b99b0d85

    just use beanstalkapp :)

  • Gnu-and-penguin-color

    This is excellent. Thank you.

  • Poolpog_normal

    Also what is wrong with this post, though probably a problem with the blog platform not the post: Not dated, and comments are also not dated. Was this posted in 2006, 2010, or 2014? It matters.

  • David

    ftp is still the easiest and more convenient way for noob like me..=)

  • None

    Trying to get this to work and I've gone through the entire process but I still get a "'/html/newproject' does not appear to be a git repository" when I try to push. I'm ssh into godaddy shared hosting. I try to do ssh://username@hostname/html/newproject but apparently that's not right. All the git files show up if I ftp into it.

    Anyone have a solution for this?

  • 15

    Finally time to kill FTP! Also @jore no no no, developing live on the server is not always a brilliant idea, develop locally, use git to a git server with backups and then use git to deploy!!

  • 8feqa6x1_normal

    At some point of views, I proved the expertise I was searching out for. We now have been taking out like willingness on this topic. Keeping it up. http://commodityonlinetips.in/

  • None
  • None
  • X3vh8hrx_normal
  • X3vh8hrx_normal

Add a comment