This is a short rundown for setting up deployment for a jekyll blog using a self-hosted git repository and a vserver running nginx. Deployment is done with capistrano (version 3).
Github is probably the most common and most convenient way to host your code for your jekyll blog, but sometimes you might want to keep everything under your own control or you're just curious what barebones git does for you.
For setting up a git repository on a linux machine I used this guide. A short wrapup:
- add a git user
$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh
- add public keys of your account on the local machine to the authorized_keys file.
$ cat your_pub.key >> .ssh/authorized_keys
- setup a bare git repository on the remote machine
$ cd /home/git/repos
$ mkdir project.git
$ cd project.git
$ git --bare init
Replace project.git with the desired name for your jekyll git repository. Additional repositories for development need to be setup the same way.
- init a git repo on your local machine and add [email protected]:/home/git/repos/project.git as remote repository.
On the webserver it's recommended to have a deploy user, who has write access to the directory the webserver is serving the virtual host from. For the rest of this description let's assume the domains are located in /srv/www/
Setup the deploy user and ssh keys:
$ sudo adduser deploy
$ su deploy
$ cd
$ mkdir .ssh
$ cat your_pub.key >> .ssh/authorized_keys
Change permissions for the domain directory (www-data is the webserver default group on Ubuntu)
$ sudo chown -R deploy:www-data /srv/www/www.domain.com
And install jekyll on the webserver:
$ gem install jekyll
This is a simple jekyll directory structure:
...
_config.yml
_layouts/
_posts/
_site/
assets/
css/
index.html
lib/
...
Jekyll generates its ouput in _site. Run jekyll build
to generate your site on your local machine. This folder contains the actual html/css files that are served by the webserver. That's why we need to point the document root of the website to _site.
root /srv/www/www.domain.com/current/_site;
Capistrano keeps a number of releases (aka versions that were deployed) and automatically updates the symlink current with the latest deployed version.
/srv/www/www.domain.com
|-- current -> /srv/www/www.domain.com/releases/20140302004028
.
|-- releases
| |-- 20140226220012
. . .
| | |-- _site
. . .
| `-- 20140302004028
. .
| |-- _site
. .
. .
|-- repo
|-- revisions.log
`-- shared
What we do on the webserver when running capistrano is checking out the source code from our git repository for jekyll and running jekyll build
on the webserver to generate the website. This obviously requires a jekyll installation on the webserver.
Capistrano only needs to be installed on your local machine, not necessarily on the webserver. Unless you want to deploy from your webserver to your webserver as well.
For detailed setup and installation instructions I recommend following the official capistrano documentation.
If you've got capistrano already installed, run cap install
within the folder of your jekyll project on your local machine. This adds additional files and folders to the jekyll project:
Capfile
...
config/
lib/
...
The config
folder contains deploy.rb. Here we define a task for updating _site by running jekyll build
on the remote machine:
set :application, 'powerxequality'
set :repo_url, '[email protected]:~/repos/powerxequality.git'
set :scm, :git
set :format, :pretty
namespace :deploy do
task :update_jekyll do
on roles(:app) do
within "#{deploy_to}/current" do
execute :jekyll, "build"
end
end
end
end
after "deploy:symlink:release", "deploy:update_jekyll"
This line makes sure that the update_jekyll task is run, when doing a deployment.
after "deploy:symlink:release", "deploy:update_jekyll"
Capistrano distinguishes between different stages. The two most common are development and production, but the naming as well as the number of stages is up to you.
After finishing your newest post, commit the changes to your git repository and push it to the remote repository.
Then publishing the post is now as simple as running:
$ cap deploy production
Done.
Not so bad but what about this simple script?