Warning: The technique illustrated in this walkthrough is insecure. I’ve created a revised version without this problem, but am leaving this post here for awareness. Read this article and my comments immediately below to learn about the security problem and avoid it in your future work, and don’t hesitate to ask me anything if you’re unsure about the problem.
This walkthrough assumes you have an existing project and Git repository, and that you want to set up easy and quick remote deployment – maybe to a web server.
This technique can be used for any project where you’re comfortable with simply pushing updates to a location and seeing them immediately active.
This works great for code bases like the one for this blog or any basic website you may be managing. However with larger projects that need automated testing and CI, etcetera, it may not be sufficient.
If this suits your needs, you’ll save a whole heap of time whenever you need to update a destination with your changes.
The final assumptions are that Git is installed and usable at the destination (if it’s not, you can easily add it following this guide), and that you won’t actually be coding or making any direct changes at the destination. Instead we’ll push in any changes and trust me, when you see how easy it is, you won’t need to make on-the-server/spot changes ever again – even for hotfixes and tiny bugs.
I’ll propose a hypothetical situation and walk you through the setup and usage for it. In reality you’ll have to adapt this guide to your own situation. You shouldn’t think of this as a bad thing though, as it will give you the opportunity to extend the solution however you feel and let it do more work for you.
I’ve got a website, www.bilalakil.me, that I update frequently. I code these updates from my home PC (hypothetical scenario >.>) or from Cloud9 when I’m on the go – so I never actually work on the webserver itself, I just upload my changes to it.
For my changes to become visible I’m used to (but not happy with) manually uploading them to my webserver under the
~/www/wp-content/themes/bilalakil/ folder, using my username:
useruser and a password which I’ll never tell you.
I just wish I can easily and quickly get my webserver using my local or Cloud9 changes without having to deal with any tedious, annoying uploading or file syncing… sigh.
I want to push my changes to it.
Open your terminal and follow these instructions. You’ll have to appropriate them for your individual and unique situation though, so try to understand what’s going on.
- SSH into destination server:
Enter your password when prompted. We’re targeting the server that you want to deploy your pushes to – we’ll set up a Git repository here.
- Clone your existing repository as a bare repository:
git clone --bare https://email@example.com/bilalakil/superepository.git/ ~/deployment.git/
You’ll probably need to enter your password when prompted here too. In this case, it’d be a Bitbucket password.
- Create and enable the post-update hook:
mv post-update.sample post-update
cat << EOF > post-update
git --git-dir=.git fetch
git --git-dir=.git reset --hard origin/master
The CD command in the post-update script should be targeting the final destination for your deployed code. That should be where you would’ve manually uploaded your code if you didn’t know about this procedure.
- CD to final destination:
As mentioned in the previous step, this is where you want the contents of your Git repository to end up and be operational after deployment.
- Initialise working-copy Git:
- Add deployment folder as origin and reset to it:
git remote add origin ~/deployment.git/
git reset --hard origin/master
This will discard any differences between what was already at the destination and what the master branch of your Git repository looked like. Your destination folder will now be up to date with what you specified as your origin.
You should keep in mind one of the aforementioned assumptions: you shouldn’t be making edits from the destination. They’ll be lost in that last step and whenever you push to the deployment repository.
The server should now be ready to receive pushes to the deployment repository and automagically have those changes mirrored to where they’re needed.
From each of your working copy Git repositories that you’ll push to the setup server from, you need to:
- Add the deployment repository as a remote:
git remote add deployment firstname.lastname@example.org:/home/useruser/deployment.git/
- Push to it when you want your code to be immediately deployed:
git push deploymentor
git push deployment <localbranchname>:masterif you’re working on a branch other than master.
Note that under this setup you must push to the deployment master branch even if the branch you’re working on isn’t master, because that’s what the final destination will target and reflect with it’s
reset --hard command.