Deploying Jekyll on Dreamhost server using GIT
17 Jan 2019
Please note I’m using a linux environment. CLI commands may vary depending on your os.
I’ve been using Wordpress on Dreamhost for my personal website for some years and with shared hosting I can have unlimited websites on subdomains and emails without having to worry about managing the server. So while I very much would like to switch to a hosting platform like netlify, or a VPS, I’ve been using Dreamhost for a long time and am comfortable launching small projects on it and hesitant to switch for now. However, I like the simplicity of using Jekyll and deploying through Github Pages, but I want to instead deploy it to my existing Dreamhost server.
Set up SSH
First you have to set up your Dreamhost server and enable ssh. We will set up a passwordless login for it.
First generate a public SSH key on your local machine. If you don’t have one:
$ ssh-keygen -t rsa
Copy your ssh id to your Dreamhost.
$ ssh-copy-id <user>@<host>
You should be able to ssh with a password now.
Make remote repo on Dreamhost
On your server create a repo where to push the code:
$ ssh <user>@<host> $ cd ~ $ mkdir <mydomain_com>.git $ cd <mydomain_com>.git $ git init --bare
Create a post-receive hook
With our empty repo we want to set up a hook that gets triggered every time changes are pushed to the repo. Essentially when we perform a git push the code will be stored to a temp domain and then the build folder will be copied to your domain.
Ignoring images but keeping them persistent
I’m using images on my website but I don’t want to gum up my GH account with a bunch of images, so I’ve ignored the img directory in my
.gitignore file. I want to keep my img directory in my domain’s public folder, but the hook we will make will delete everything. To bypass this in the hook I will temporarily move the images before I delete my public folder and move them back after copying over my static files.
Create a post-receive hook:
$ ssh <user>@<host> $ cd ~ $ vi <mydomain_com>.git/hooks/post-receive
Then paste in:
#!/bin/bash # Replace this line with your real domain name DOMAIN=mydomain.com echo echo "~~ Updating $DOMAIN ~~" echo # Clearing git env unset GIT_DIR unset GIT_WORK_TREE # temp domain storing the entire jekyll tree (all repo content) cd ~/$DOMAIN-jekyll git pull # temporarily move img directory cd ~/$DOMAIN/public mv <img_directory> .. # get to the static build directory cd _site # delete domain contents # viewable website in public directory rm -rf ~/$DOMAIN/public/* # copy that to our real domain path cp -R * ~/$DOMAIN/public/ # move image directory back to public cd ~/$DOMAIN/ mv img public echo echo "~~ Done ~~" echo
Then make the script executable:
$ chmod +x <mydomain_com>.git/hooks/post-receive
Create a remote
Next you have to create the remote. In your server clone the repo that we made.
$ cd ~ $ git clone <mydomain_com>.git <mydomain.com>-jekyll
This is where all your code pushed will live. Only the static files will be copied to your real domain for public viewing.
Add remote endpoint on local repo
On your local machine add the remote repo.
git remote add live ssh://<user>@<host>/~/<mydomain_com>.git
Now you can push straight to your dreamhost domain:
$ git push live master
With this setup I can do version control with Github but easily push to my live website. A caveat about this method is that I have to build locally before pushing new posts whereas Github pages automatically publishes for you with the github-pages gem.
Thanks to Bruno Fagundez for his excellent write-up for this topic.