A setup to allow pushing to live/staging from a local repo. This is mostly a reference that I can return to later, but maybe it will be helpful to you too!
The process could use some improvements
- Handle conflicts automatically in the post-receive script
- You've created a bare repo on a local development environemnt already, which serves a whole site. Lately, I like using Statamic as a CMS because it doesn't use a database. Perfect for Git tracking.
- You know how to use basic Git functions.
- You have a basic understanding of how to navigate a shared hosting environment using SSH and a shell console.
- Oh, and your hosting environment has Git installed.
I've enjoyed setting up hosting on VPS servers where I have a bit more control over my hosting environments. This allows me to set where the webroot is and configure as I need to. It also means I have the ability to clone projects using git.
The basic idea is that you set up a repos folder above the publicly-accessible webroot directory on your host. This way, pushing to your 'live' or 'staging' remote automatically updates the files in those environments after you've tested on local development. Using Git's post-receive hooks via a simple shell script, the site is automatically updated.
For the sake of this documentation, we'll assume these folders are in the hosting server user's home directory (~). This may be under something like /var/www/vhosts/sitename.tld. If your SSH user's home directory isn't where files are served from, you could always create a symbolic link such as 'www' in your home directory to make it easier to navigate to.
- ~/httpdocs
- ~/repos
The httpdocs folder is set up as your webroot on the host. This is where files are served to visitors. The httpdocs folder pulls from the project's repository in the repos folder and is automatically updated whenever a new commit is pushed to the repos folder.
Navigate to /repos folder and create the bare repo
cd repos
git init --bare sitename.git
Set up the post-receive shell script. Navigate to /repos/sitename.git/hooks/ and create the post-receive script.
cd sitename.git/hooks
vi post-receive
In the editor, add this shell script code:
#!/bin/bash
# Move to the publicly-accessible folder
cd "/var/www/vhosts/sitename.tld/httpdocs"
git stash # Attempt to stash the local changes (I don't think this works)
# Clean the current directory and pull the latest master commit
unset GIT_DIR
git reset --hard # Reset to the head commit
git clean -f -d # Remove all untracked files and directories
git fetch
git pull origin master # Pull from the repository
Ensure the permissions on the post-receive script allow it to execute
chmod ugo+x post-receive
Now, whenever you push to this repository, the post-receive script will be executing. It will reset everything on local dev and pull the latest commit that you've pushed.
Navigate to the httpdocs folder and clone from the bare repository you set up. You'll get a warning that you cloned an empty repository. That's just fine, we'll add to the repo soon.
cd ~/httpdocs
git clone ../repos/sitename.git
On local development environment, add the remote as the live/staging site's git repo. This uses the SSH/SCP file convention, incorporating the user, hostname, and navigates to the repository location.
git remote add live [email protected]:repos/sitename.git
Push your local changes to the new live remote
git push live
Double-check that your changes went live. If all went according to plan, you are now set!
Getting Git tracking both ways is the ideal setup. Here is how to do that in your live environment.
Set up the live git user in the repository (not as global, in case you have other git repos on your live server)
git config user.name "Live Site"
git config user.email "[email protected]"
Add a new remote to push back from live. I've called it vault for this example.
git remote add vault [email protected]:sitename.git
Push changes as needed to the new vault repo.