For this blog, I’m using Jekyll, a Ruby based static site generator that uses markup pages to generate static html pages.

I wanted to automate the build and deployment process using Jenkins.

As i’m using Proxmox in my homelab, I can install various container images, one of which is Turnkey linux Jenkins which simplfies the setup.

After deploying the container and logging in as root and I can begin setting up the prerequisites for Jekyll.

Prerequsites for Jekyll

Install Ruby dev env and lftp

sudo apt-get install ruby-full build-essential lftp

Install Jekyll gem

gem install jekyll bundler

Local Development site

I want to have a local development site to view changes before pushing to the live site. For this I am using Jenkins pipelines to configure a local deployment on the develop branch. Turnkey linux Jenkins image includes apache2 which is proxying the Jenkins tomcat instance which I can use to host the development Jekyll blog.

Add a site configuration and create a directory to hold our development site that is writable by the jenkins user: drwxrwxr-x 2 jenkins www-data 2 Feb 13 21:21 jekyll-dev

/etc/apache2/sites-available/jekyll-dev.conf

Listen 8000

<VirtualHost *:8000>
    DocumentRoot "/var/www/jekyll-dev"
</VirtualHost>

Then symlink it to the sites-enabled folder. root@jenkins .../apache2/sites-enabled# ln -s ../sites-available/jekyll-dev.conf jekyll-dev.conf

Restart apache with apachectl restart

Double check apache is listening on the new port

root@jenkins .../apache2/sites-enabled# netstat -altp | grep 8000
tcp6       0      0 [::]:8000               [::]:*                  LISTEN      340/apache2

In Jenkins create new job that is a multibranch pipeline and configure it to use our GIT repo with our Jekyll blog, I’m selfhosting a gogs.io GIT server.

gogs

The branches must have a Jenkins pipeline file in the root of the repo. I’ll be using rsync to copy the generated static html files over to our web directory. For deployment to production i’ll be using lftp.

Jenkinsfile

pipeline {
    agent any

    stages {

		stage('Install Bundles') {
            steps {
                echo 'Installing bundles..'
sh 'bundle install --path ~/.gem'
            }
        }
        stage('Building site') {
            steps {
                echo 'Building..'
sh 'bundle exec jekyll build'
            }
        }
        stage('Deploy') {
			when {
                branch 'develop'
            }
            steps {
                echo 'Deploying to dev....'
sh 'rsync -avzh ./_site/ /var/www/jekyll-dev/
            }
			
			when {
                branch 'master'
            }
            steps {
                echo 'Deploying....'
            }
        }
    }
}

Dev deployment

Assuming the above configuration goes correctly, upon triggering the Jenkins build it should build our site and rsync it to our local web directory

jenkins_blog_build dev_site

Prod deployment

To deploy to my webserver I need to FTP the site over, rsync won’t work for this. On my webhost I have created an FTP user to send the site files. I then need to add the FTP user credentials to Jenkins.

dev_site

Finallly, within our Jenkinsfile, we need to reference the Jenkins credentials to FTP our site by the id we used when setting up the credentials: ftp_prod_blog. Using the withCredentials function, we can pass the username and password to the lftp command to mirror the local site to the remote webserver.

Within the Jenkins file in our step for master branch deployment add the following:

withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId:'ftp_prod_blog', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
					sh 'lftp -e "mirror -R ./_site/ ~/" -u $USERNAME,$PASSWORD <FTPSITE>:21'
				}

Hopefully as you are now reading this, the prod deployment was successful!

prod_site

Now my deployment is automated via Jenkins I no longer need to manually generate the static html files and FTP them to my host.