Q1, chapter 2: Set up a website with domain and SSL in docker container

Time to set up the first website on the VPS, add a domainname and an SSL-certicate. I will be install Ghost CMS.

Q1, chapter 2: Set up a website with domain and SSL in docker container
Photo by Nick Karvounis / Unsplash

Why Ghost CMS?

My first website (1999) was build with StarOffice/4.0 and had HTML with frames, I switched around 2002 to a PHP based blog script, briefly used Joombla and since 2009 I've been using WordPress for most of my websites. Until recently.

WordPress is still a great piece of software. But when I started exploring options to add a subscription model to one of my sites, I encountered Ghost. Publishing software with newsletter and subscriptions build in. It is, just as Ghost, open source. But unlike WP, it doesn't have a whole addon library. You could say that this is limited, but as I want to spend less time to make sure all the sites are running, I am open to something more simple. And it just seems to have all the features one of the sites need.

And since Ghost is build upon node.js, it can not be installed on most shared hosting plans. Perfect to show the power of Docker.

I failed several times

So far I haven't mentioned a lot of failures. However, this time I messed up several times! Why? Because it is not just copy-pasting this time, it a bit more complex.

💡
Mistake 1: I searched for a YAML for Ghost and ended up on a blog with a lot of great information. However, this YML was using MariaDB instead of the now recommended MYSQL8. It will still run, but you might end up with problems in the future.
Wrong database...

First steps: Setup the site

Ghost has, just like WordPress, a managed solution; Ghost (pro). This pays their bills. You will find the opensource information via Product > For Developers. By clicking installation instructions we'll be redirected to the docker hub, a place where a lot of docker images are stored.

The first part of the description is the CLI way of installing Ghost, but we will skipping to the example of docker-compose.yml

version: '3.1'

services:

  ghost:
    image: ghost:5-alpine
    restart: always
    ports:
      - 2369:2368
    environment:
      # see https://ghost.org/docs/config/#configuration-options
      database__client: mysql
      database__connection__host: db
      database__connection__user: root
      database__connection__password: example
      database__connection__database: ghost
      # this url value is just an example, and is likely wrong for your environment!
      mail__transport: SMTP
      mail__options__host: xxx
      mail__options__port: xx
      mail__options__secureConnection: "true"
      mail__options__auth__user: xx
      mail__options__auth__pass: xx
      mail__from: xxx
      url: https://befrankwith.me
    volumes:
      - ghost:/var/lib/ghost/content

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

volumes:
  ghost:
  db:

What happens in this YML?
image: ghost:5-alpine -> this is pointing to the image you want to install.
ghost is the name, 5 is the version (you can also specify this like 5.85 or 5.85.1).
Alpine? This is a slim linux version used. You can also leave this and use the default image.

This image is based on the popular Alpine Linux project⁠, available in the alpine official image. Alpine Linux is much smaller than most distribution base images (~5MB), and thus leads to much slimmer images in general. This variant is useful when final image size being as small as possible is your primary concern. The main caveat to note is that it does use musl libc⁠ instead of glibc and friends⁠, so software will often run into issues depending on the depth of their libc requirements/assumptions. See this Hacker News comment thread⁠ for more discussion of the issues that might arise and some pro/con comparisons of using Alpine-based images.

If I look at the different images here, the difference is ~170MB vs ~150MB. And based on testing, you can switch later.

Ports: the first number is the public port, if you are running multiple (identical) services, you can change to a different port.

💡
Mistake 2: instead of changing the first port number, I changed the second. Now my website couldn't connect to the database

Copy this to Dockge in a new stack and replace the placeholders.

💡
Mistake 3: If you change the database user and/or database in the ghost environment, you need to add these to the db environment too, otherwise it seems to be unable to connect. Problably due using defaults?

Did you change the db user and db name? Add and use the same to the db environment

    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_USER: root
      MYSQL_DATABASE: ghost

What about the SMTP settings?

All mails Ghost will send - except newsletters - will go out through the e-mailaccount you link here. From system mails like 'import complete' to mails to new sign-ups or comments.

Launch

Now start the stack. The site will be available at http://<<VPS-IP>>:2369 (or other port if you have changed this.

Note: if something is incorrect, for example the mails are not sending. Change the YML, save and restart the stack.

Setup the domainname and SSL

Go to the DNS-settings of your domain name and add an A-record pointing to your VPS' IP. For example: example.befrankwith.me A <<IP>>

Go to you Nginx Proxy Manager (<<IP>>:81) and add the details. USe the port number for Ghost from the YML.

In the tab SSL you can request a certificate. This should work now.