Self-Host your own Ghost Blog
Tags: ghost, mysql, traefik, docker
Published: 2022-07-03 10:04:58

We are going to install Ghost CMS with Mysql database in Docker and reverse proxy it with the help of Traefik.

## Prerequisites

- A domain name.
- (Optional) If you want to have a newsletter then you need a SMTP server. I would suggest you [Mailgun](https://www.mailgun.com/) as it goes pretty well with Ghost.
- A server with Traefik installed. Follow this [guide](https://fossian.com/simplify-deployment-traefik-walk-through/) for hosting Traefik on your server.

{% embed https://fossian.com/simplify-deployment-traefik-walk-through/ %}

## Step-1: Create required directories and files

Directory Tree:
```
├── ghost-blog
│   ├── docker-compose.yml
│   └── blog
│       ├── config.production.json
│       └── content
```

```bash
mkdir -p ghost-blog/blog/content && \
  cd ghost-blog && \
  touch ./blog/config.production.json && \
  nano ./docker-compose.yml
```

Paste the following to the `docker-compose.yml`
```yaml
version: '3.7'

services:
  ghost:
    image: ghost:5.2.3
    restart: always
    depends_on:
      - db
    environment:
      NODE_ENV: production
    networks:
      - default
      - web
    volumes:
      - ./blog/content:/var/lib/ghost/content
      - ./blog/config.production.json:/var/lib/ghost/config.production.json
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=web"
      - "traefik.http.routers.ghost-secure.entrypoints=websecure"
      - "traefik.http.routers.ghost-secure.rule=Host(`fossian.com`)"
      - "traefik.http.routers.ghost-secure.service=ghost-service"
      - "traefik.http.services.ghost-service.loadbalancer.server.port=2368"

  db:
    image: mysql:oracle
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: your_mysql_root_password
      MYSQL_USER: ghost
      MYSQL_PASSWORD: ghostdbpass
      MYSQL_DATABASE: ghostdb
    networks:
      - default
    volumes:
      - ./data:/var/lib/mysql
      
networks:
  web:
    external: true
```

> Make sure you change domain name in 4th label under `ghost` service. Also change the database credentials under `db` service.

I am using Mysql instead of MariaDB as Ghost has announced that they are going to remove support for other databases from upcoming major releases. Also, the image used for Mysql here is `mysql:oracle`. It has support for multi-architecture so you can also host it on Oracle cloud's Ampere chips (arm64) based instances or your raspberry pi (arm64) as well.

Now edit the Ghost Configuration file `config.production.json`
```bash
nano ./blog/config.production.json
```
```json
 {
  "url": "https://fossian.com",
  "server": {
    "port": 2368,
    "host": "0.0.0.0"
  },
  "database": {
    "client": "mysql",
    "connection": {
      "host": "db",
      "port": 3306,
      "user": "ghost",
      "password": "ghostdbpass",
      "database": "ghostdb"
    }
  },
  "mail": {
    "transport": "SMTP",
    "options": {
      "service": "Mailgun",
      "auth": {
      	"user": "postmaster@example.mailgun.org",
      	"pass": "1234567890"
      }
    }
  },
  "logging": {
    "path": "/var/lib/ghost/content/logs/",
    "level": "info",
    "rotation": {
      "enabled": true,
      "count": 15,
      "period": "1d"
    },
    "transports": ["stdout", "file"]
  },
  "paths": {
    "contentPath": "/var/lib/ghost/content"
  }
}
```

> - Make sure you change the url on 2nd line to your blog URL and database credentials according to what you filled in `docker-compose.yml`.
- Also, edit the SMTP credentials in `mail` key. If you are using mailgun then you just need to change the user and pass which you will get from mailgun dashboard after signing up. If you are using any other service like sendgrid then make sure you check Ghost's official configuration docs.

{% embed https://ghost.org/docs/config/#mail %}

If you don't want to have a newsletter or a membership feature in your blog then change the content of `mail` key as shown:

```json
"mail": {
    "transport": "Direct",
},
```

Now simply run `docker-compose` to deploy your Ghost blog!
```bash
docker-compose up -d
```

Wait for 1 minute and access your Ghost blog at `https://yourdomain`

![Ghost Blog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8tugca30z5yslqmfeqg.png)

Don't forget to log in to your dashboard at `https://yourdomain/ghost`

## Wrapping Up

That's pretty much it! Feel free to comment below if you have any issues. And checkout my blog [Fossian](https://fossian.com/) where I post about Cloud, Linux and Open Source!

{% embed https://fossian.com %}