Your Ghost blog, the easy way

Photo by Lan Gao / Unsplash
Your Ghost blog, the easy way

In this article we are going to learn how to get up and running with your own instance of Ghost CMS. We even will have a webhook to publish our newsletter without using the official Mailgun integration (because it's no longer free to use).

First we will need, of course, our VPS or personal server up and running. We already talked about it in previous articles.

Once we have portainer in place is as easy as adding a new stack via docker compose:

version: '3.1'

services:

  ghost:
    image: ghost:5-alpine
    restart: always
    ports:
      - 2368:2368
    environment:
      # see https://ghost.org/docs/config/#configuration-options
      database__client: mysql
      database__connection__host: db
      database__connection__user: root
      database__connection__password: changeme
      database__connection__database: ghost
      mail__transport: SMTP
      mail__options__host: smtp.exemple.com
      mail__options__port: 465
      mail__options__auth__user: username@exmple.com
      mail__options__auth__pass: XXX
      mail__from: Exemple Corp. <username@exmple.com>
      # this url value is just an example, and is likely wrong for your environment!
      url: https://changeme
      # contrary to the default mentioned in the linked documentation, this image defaults to NODE_ENV=production (so development mode needs to be explicitly specified if desired)
      #NODE_ENV: development
    volumes:
      - ghost-content:/var/lib/ghost/content

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: changeme
    volumes:
      - ghost-mysql:/var/lib/mysql

  #optional, for sending newsletter for free
  ghosler:
    restart: unless-stopped
    container_name: ghosler
    ports:
      - 2369:2369
    image: itznotabug/ghosler:0.94
    volumes:
      - ghosler-logs:/usr/src/app/.logs
      - ghosler-analytics:/usr/src/app/files
      - ghosler-configuration:/usr/src/app/configuration

  #optional webhook, for sending newsletter for free with sendgrid or postmark
  ghost-webhook: 
    image: jvmonjo/ghost-webhooks
    restart: always
    ports: 
      - 3000:3000
    environment:
      EMAIL_PROVIDER: #postmark or sendgrid
      MAIL_SERVER_API_KEY: 
      MAIL_TEMPLATE_ID: 
      MAIL_FROM: 
      GHOST_URL: 
      DATABASE_CONTAINER_NAME: 
      MYSQL_USER: 
      MYSQL_PASSWORD: 
      MYSQL_DATABASE: 

volumes:
  ghost-content:
  ghost-mysql:
  ghosler-logs:
  ghosler-analytics:
  ghosler-configuration:

When we have our containers up and running, we only need to go to our nginx manager website and add a proxy host pointing to Ghost port, and optionally, another one pointing to our webhook instance.

I have adapted the webhook app from https://github.com/rufusgerm/ghost-webhooks and I've made it my own fork to use it with Postmark. I even compiled with Docker and uploaded to Docker Hub if you want to use mine.

I've then adapted a Newsletter template on Postmark that include this variables:

PostmarkTemplateModel = {
            username: user.name,
            emailFrom: emailFrom || "",
            website_url: process.env.GHOST_URL || "https://example.com",
            header_image: newsletter.header_image,
            user_email: user.email,
            user_uuid: user.uuid,
            created_at: newsletter.created_at,
            newsletter_uuid: newsletter.uuid,
            newsletterName: newsletter.name,
            title: newsletter.title,
            excerpt: newsletter.excerpt,
            html: newsletter.html,
            feature_image: newsletter.feature_image,
            authorName: newsletter.author.name,
            authorImage: newsletter.author.image,
            postUrl: newsletter.url,
        }

I've had to make some tweaks in the original code to retrieve some variables from the database to be able to print a customized, on a user basis, unsubscribe link, just to mimic the original Ghost newsletter template, and to include the newsletter header image.

Or even better, you can use Ghosler, a fantastic service for sending newsletter using any smtp service, and that has been recently dockerized.

I'll keep updating this stack for a while, since I'm determined to make it my personal blog stack.

The theme that I'm using is also a fork from https://github.com/zutrinken/attila, that I have adapted to suit my needs and personal taste. It's available here if you like it: https://github.com/jvmonjo/attila.

And don't forget to subscribe if you are not already!