Set Up Subdomain Website Hosted on VPS with Git Deployment

The previous series Set Up VPS on Linode (Part 1, Part 2, Part 3) explains how to set up the server environment with necessary dependencies on a Linode VPS virtual machine. This article takes one step further to lay out the steps to launch a new website from this virtual machine with git-based deployment.

Basic parameters

VPS provider: Linode

Existing website:

IP for existing website:

New subdomain under existing website:

Server for the virtual machine: Apache

Username on the server: user000

Local working directory: ~/Sites/newsite

1. Configure DNS

First we need to create a working URL for the new website, which is a subdomain under an existing website.

Login to Linode's dashboard. Go the right linode virtual machine => DNS Manager.

In A/AAAA Records section, create a new A record.

Hostname: newsite

IP Address:

TTL: default or 300 (5 minutes) will now point to the same virtual machine at IP address The Apache-based server needs to be configured to handle traffic from

2. Set up working directory on server

Create the folders that will contain the files for the website

mkdir /var/www/
mkdir /var/www/
mkdir /var/www/
mkdir /var/www/

Make sure the folders have the right ownership www-data, which is the default for apache:

chown -R www-data:www-data /var/www/
chown -R user000:www-data /var/www/
chown -R user000:www-data /var/www/

3. Configure virtual host on Apache

The traffic routing at the server side is accomplished with virtual host on Apache. My Linode is set up with Ubunto 16.04.02 LTS.

ssh into the server, then,

cd /etc/apache2/sites-available`
cp 000-default.conf 

Open with vim, uncomment the following lines with these changes:

DocumentRoot /var/www/
ErrorLog /var/www/
CustomLog /var/www/ combined

Enable this new virtual host configuration file with sudo a2ensite

Restart the apache server so that the new virtual machine will take effect: sudo service apache2 restart

4. Set up git deployment

Login to Github's account, create a new private repo newsite with a README. It has a git address

On local machine (Macbook Pro 2017), cd ~/Sites, then clone the git repo with git clone

Add a .gitignore file and some initial placeholder files like index.html. Make the initial commit with git add ., git commit, and git push to push the changes to remote origin on master branch.

On server on VPS, create another remote for this local git repo.

cd /var/www/
mkdir site.git && cd site.git
git init --bare
cd hooks
touch post-receive

In vim, copy and paste the following code into the newly created hook post-receive,

NC="\033[0m" # no color

while read oldrev newrev ref
    # only checking out the master branch
    if [[ $ref = refs/heads/$BRANCH ]];
        echo -e "Ref $ref received. ${BGREEN}Deploying ${BRANCH} branch to production...${NC}"
        git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f
        echo -e "Ref $ref received. ${BYELLOW}Doing nothing.${NC} Only the ${BRANCH} branch may be deployed on this server."

Back on the local machine, cd ~/Sites/newsite, add a new remote:

git remote add live zire@kratos:/var/www/

Check two remotes are now added to this local git repo with git remote -v

Deploy the code to VPS virtual machine with a simple git push live.

5. Final Notes

There are various ways to do deployment from local machine to server. The ideal work flow is that changes are pushed to github's repo, which triggers a web hook from github to perform a Continuous Integration ("CI") action. This action will need to be completed through some third party SaaS and this web hook will push the changes from github to the virtual machine on VPS provider. I feel this is too much work for a simple webpage project.

Another method is to git push to multiple remotes, as suggested by very spirited discussions on Stack Overflow. I think this is also a bit of overkill.

Some SO users also suggested that the second step (from github server to VPS) can be achieved by ssh into VPS, git pull the code from github. This works but involves too many manual steps.

Alternatively, one can also just use rsync -avP --delete localfile serverpath to do the same work as git push from local machine/github to VPS. This is not so elegant.

My approach is to manually run git push twice, first one to remote origin, and the second one to remote live. Two commands shall be executed right after each other to ensure the same code base is updated simultaneously on Github, which handles version control, and VPS, which serves the actual files to web audience. It's simple enough for a small project.

Go Top

If you enjoy reading articles like this, a small donation in ETH will go a long way to make sure I spend enough time working on this. My Ethereum address: 0xae56b1f221a48f3dbbaaea110b049d5c1aba6efe.

<< Swap VPS IP from Within China