<![CDATA[James Lawler]]>https://www.jameslawler.com/https://www.jameslawler.com/favicon.pngJames Lawlerhttps://www.jameslawler.com/Ghost 4.32Sat, 16 Mar 2024 18:15:23 GMT60<![CDATA[Private Repository to Build and Deploy Ghost Blog]]>https://www.jameslawler.com/blog/2021/12/17/private-repository-to-build-and-deploy-ghost-blog/61b525c544d8750001f23453Fri, 17 Dec 2021 20:27:00 GMT

badge badge badge badge

This is a follow up from a previous post about setting up a Ghost Blog on GitHub pages using GitHub Actions. In that post I described using a public GitHub repository to host both the Ghost content folder and the generated static website. In this post I will show how to keep the Ghost content folder in a private repository and only host the generated static website in a public repository.

What you need

  1. A public repository in GitHub that will hold the generated static website
  2. A private repository in GitHub that will hold your content folder and GitHub workflow

Public Repository

Simply create a new repository in GitHub. You don't need to commit or push anything to it. This will happen automatically. The only thing you need to do is go to the repository settings and enable GitHub Pages on the gh-pages branch.

Private Repository

Create a private repository in GitHub and setup your Ghost blog by following the guide from my previous post. The different is in the GitHub workflow file. Here you need to configure the Deploy to GitHub Pages step to deploy to a different repository within your account.

- name: Deploy to GitHub Pages
    uses: JamesIves/github-pages-deploy-action@4.1.7
    with:
      branch: gh-pages
      folder: static
      token: ${{ secrets.repository_token }}
      repository-name: jameslawler/jameslawler-website

By default, your GitHub workflow won't have permission to manipulate another repository. In order to do this, you need to create a Personal Access Token. The token should have at least the public_repo permission.

Once you have the token you need to make it available to your GitHub workflow. Since this repository is private, you could just put it straight in the source code. But for better security practices, I would use a secret which can be configured at the repository and then is passed to the GitHub workflow inside a secret context.

Testing it out

Once you have the public and private repositories setup, and you have the GitHub workflow modifications to connect the two repositories together, it is time to test it out. Trigger the GitHub workflow on the private repository. This will build the Ghost static site, and then push it to the gh-pages branch of the public repository. Within a few minutes, the blog will be available on your GitHub pages url.

Summary

I set this up with a two repository approach myself because I wanted to keep the Ghost content folder and database secret. The content folder contains upcoming posts, theme code, and also anyone can connect to the database file directly and look inside the tables. This way, the only public potion is the generated static files which the user will be able to see anyway when browsing the blog.

]]>
<![CDATA[Scheduled Posts with Ghost and GitHub Actions]]>https://www.jameslawler.com/blog/2021/12/11/scheduled-posts-with-ghost-and-github-actions/61b524ce44d8750001f23448Sat, 11 Dec 2021 22:23:20 GMT

badge badge badge badge

Sometimes I want posts in my Ghost blog to only publish in the future on a set date. Ghost has the feature built in, but it is intended to be used with a dynamic Ghost blog that will instantly show the new post when the scheduled date is reached. As I run a static Ghost blog, I wanted to be able to have the same possibilities. To see how I setup a static Ghost blog on GitHub Pages you can see my other posts on the topic.

Scheduled Posts

In the Ghost editor when you save an article you have the option to Set it live now or Schedule it for later. When you want to publish later, you can choose the date and time of the scheduled post.

Ghost publishing options

In order for the post to go live at the specified date and time, the Ghost server needs to be running. In order to achieve this, I have setup GitHub Actions to run automatically once a day on a fixed schedule. The workflow is the same as the previous posts with the addition of a cron schedule to the trigger section.

on:
  push:
    branches: [main]
  schedule:
    - cron: "0 20 * * *"

This workflow will trigger on a push to the main branch, or everyday at 8pm UTC time. It is important to note that the cron schedule uses UTC time and so you will need to adjust it if you want it to match your local time. To have more granular post times, you would need to increase the frequency of the cron schedule.

Perfect Streak

The only "negative" with this approach is that it automatically makes daily commits to one of your repositories and it makes your GitHub contributions graph look not so honest.

Not so honest GitHub contribution graph

You can see that from December onwards is when I enabled the daily GitHub Action to build and deploy my static Ghost blog. But apart from that, the solution is simple and works.

Summary

Using GitHub Actions with a cron schedule allows scheduled Ghost posts to go live within an acceptable timeframe of the publish date. I would say this is fine for a personal blog with infrequent posts. In the future I want to find a way to not publish to GitHub Pages if there were no updates. Perhaps checking if any new urls have been generated since the last time.

]]>
<![CDATA[Custom Domain for Static Ghost Blog on GitHub Pages]]>https://www.jameslawler.com/blog/2021/12/04/custom-domain-for-static-ghost-blog-on-github-pages/61a3a66a5157d70001c0f8e4Sat, 04 Dec 2021 15:55:00 GMT

badge badge badge badge

In this post I will share how I run this static Ghost blog for free using GitHub Pages and a custom domain. This is a continuation from my previous post about starting a static Ghost blog on GitHub Pages.

GitHub Workflow

The only change needed for the GitHub Workflow file is to generate the static ghost site using the --url parameter pointing to your custom domain.

- name: Generate Static Site
  run: gssg --url https://www.jameslawler.com

GitHub Pages Settings

On the GitHub Pages settings page you need to specify your custom domain, for example www.jameslawler.com

Domain DNS Settings

The final step is to configure your domain name registry to point your domain name to GitHub Pages IP addresses. Depending on the domain registry they will have different interfaces to change the settings.

  • A record for @ pointing to 185.199.108.153
  • A record for @ pointing to 185.199.109.153
  • A record for @ pointing to 185.199.110.153
  • A record for @ pointing to 185.199.111.153
  • CNAME record for www pointing to your username.github.io (the username should be replaced with your actual GitHub account username):

A lot of registrars have pages showing how to setup GitHub Pages on your domain. For example with Namecheap, you can see the information here. https://www.namecheap.com/support/knowledgebase/article.aspx/9645/2208/how-do-i-link-my-domain-to-github-pages/

Summary

It can take some time (minutes to hours) for DNS records to update and for you to see your GitHub Page running on your custom domain. When it is up and running, check to make sure all the links work on your page, so you can confirm the gssg generation worked successfully.

]]>
<![CDATA[Ghost Blog on GitHub Pages using GitHub Actions]]>

badge badge badge badge

In this post I will share how I built up this website for free using Ghost CMS, GitHub Pages, and GitHub Actions.

Ghost

Ghost is a content management system for self publishing your own website - and it can be self hosted in a Docker container. To start this project

]]>
https://www.jameslawler.com/blog/2021/11/27/ghost-blog-on-github-pages-using-github-actions/61a2b6e35cc67d0001e893a0Sat, 27 Nov 2021 22:53:26 GMT

badge badge badge badge

In this post I will share how I built up this website for free using Ghost CMS, GitHub Pages, and GitHub Actions.

Ghost

Ghost is a content management system for self publishing your own website - and it can be self hosted in a Docker container. To start this project you need to be running the Ghost Docker container on your development computer. This means you need to have Docker installed locally - and there is a handy guide on the Docker website for the main operating systems.

Before starting up the Ghost Docker container you will need a directory where you can store the Ghost content (static assets, SQL database, etc). For this post I setup a new repository in GitHub to store the content so it would stay under version control.

To start the Ghost Docker container on your local machine, open a console and navigate to the directory you have setup with a GitHub repository and execute the following command.

docker run -d -p 2368:2368 -v content:/var/lib/ghost/content ghost:alpine

This command will run up the latest version of Ghost using the alpine Docker image. It will run on the standard 2368 port and mount the current contentdirectory into the Docker container at /var/lib/ghost/content. This means that any changes to the Ghost instance (new posts, theme, etc) will be exposed to the current working folder and can be committed to GitHub.

After running the command, you should be able to access the locally running version of Ghost at http:// localhost:2368/. At first you will need to setup an account (only saved in your local database), and then you will be able to add new pages, posts, and change the navigation settings etc. You will also be able to configure the theme for your website.

GitHub Workflow

Once there is a locally running instance of Ghost, the next step is to get it running in GitHub Pages. The key to do this is using GitHub Actions with the help of a GitHub workflow. To setup a GitHub workflow you need to add a .github\workflows folder. Each GitHub workflow is just a yaml file within this directory.

name: Deploy Ghost and Generate Static Site

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check out Model Repository
        uses: actions/checkout@v2
      - name: Run Ghost
        run: docker run -d -p 2368:2368 -v ${{ github.workspace }}/content:/var/lib/ghost/content ghost:alpine
      - name: Sleep for 10 seconds
        uses: jakejarvis/wait-action@master
        with:
          time: "10s"
      - name: Install ghost-static-site-generator
        run: npm install -g ghost-static-site-generator
      - name: Generate Static Site
        run: gssg --url https://jameslawlercom.github.io --subDir 2021-11-27-ghost-blog-on-github-pages-using-github-actions
      - name: Deploy to Github Pages
        uses: JamesIves/github-pages-deploy-action@4.1.7
        with:
          branch: gh-pages
          folder: static

In the first section, the trigger is configured. This means that this GitHub workflow will run when a commit is made on the main branch.

on:
  push:
    branches: [main]

The scripts section defines the different scripts that will run one after the other during the GitHub workflow. The first simply checks out the latest version of the code to the build instance.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check out Model Repository
        uses: actions/checkout@v2

The next script is similar to the command we use to run Ghost locally. This will actually run up the instance of Ghost on the GitHub Actions build virtual machine. The main difference here is the use of the build parameter ${{ github.workspace }} to access the path to the working directory of the build folder.

- name: Run Ghost
  run: docker run -d -p 2368:2368 -v ${{ github.workspace }}/content:/var/lib/ghost/content ghost:alpine

As Ghost can take a few seconds to start up, a wait script is added to pause the process for 10 seconds.

- name: Sleep for 10 seconds
  uses: jakejarvis/wait-action@master
  with:
    time: "10s"

Once enough time has passed, the next script installs globally a npm script that can crawl the Ghost instance and generate a static version of the website.

- name: Install ghost-static-site-generator
  run: npm install -g ghost-static-site-generator

The next script will run this tool to do the crawl and generate a static version of the website into a folder called static. The --url property is used to specify the base domain of the static website (in this case a GitHub Pages site). The --subDir property is used to specify a sub folder of the static website (in this case the name of the GitHub Pages project name).

- name: Generate Static Site
  run: gssg --url https://jameslawlercom.github.io --subDir 2021-11-27-ghost-blog-on-github-pages-using-github-actions

Finally the last script will deploy the static folder which contains our website to the gh-pages branch of the repository so that it is available on GitHub Pages.

- name: Deploy to Github Pages
  uses: JamesIves/github-pages-deploy-action@4.1.7
  with:
    branch: gh-pages
    folder: static

GitHub Pages

The last stage of this project is to enable GitHub Pages on your repository.  This is done via the Pages tab in the repository settings.

Summary

After updating your blog using the Ghost admin website and push push to the main branch the changes, the ghost blog will be started in a docker container on the GitHub Actions server, a static version will be crawled automatically and then saved to the GitHub pages branch of the repository. A few minutes later, your website will be running on your GitHub Pages website.

There is a demonstration repository available here which demonstrates the GitHub Actions and GitHub Pages project.

]]>