New blog ...

New blog ...

In 2009, I created as blog platform. Ranging from technology insights, rambling about Linux and Windows problems, and some insights into LEGO building, this contains lots of history.

I've lost track a bit in the past years, also with publishing lots of technical content on the Icinga and NETWAYS blog. Also, Wordpress has become a feature monster. Divi on top makes building websites easier ... but I don't need it.

With the shift to GitHub and GitLab, everything I write is Markdown.

This is a markdown clode block.

Bold and italic.

That's why I was looking into something lightweight with the possibility to write Markdown in the same place. I could have used GitHub/GitLab pages, though I'll keep that for future demo websites in my talks.

So I have found Ghost which has a similar look as Medium, being Open Source and free to use and decided to start fresh at

I'll dive into monitoring/observability, infrastructure as code, development workflows, CI/CD, containers, k8s, serverless and much more.

Enjoy and read you soon!

PS: Did I tell you already that I document everything? Here's the entire setup documentation written in Markdown :-) Ghost blog setup


Run Ghost as blog in Docker with an Nginx proxy up front, which manages Let's Encrypt TLS certificates.
The setup should be managed with docker-compose.

The Nginx server runs natively on the system, serving other websites on the host too.

Inspired by this article.


Ghost requirements.

  • Docker
  • Ghost container
  • MySQL 5.7 (not 8.0+)

Installation steps:

apt install apt-transport-https ca-certificates curl software-properties-common

curl -fsSL | sudo apt-key add -

add-apt-repository "deb [arch=amd64] bionic stable"

apt update

apt-cache policy docker-ce

apt install docker-ce

curl -L "$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose


apt install nginx
systemctl start nginx.service
systemctl enable nginx.service

Let's Encrypt

add-apt-repository ppa:certbot/certbot
apt install python-certbot-nginx

certbot --nginx -d -d

Ghost Container

mkdir -p /docker/ghost
cd /docker/ghost/
mkdir content mysql

Create docker-compose.yml

vim docker-compose.yml 

version: '3'

    image: ghost:latest
    restart: always
      - 2368:2368
      - ghost-db
      database__client: mysql
      database__connection__host: ghost-db
      database__connection__user: root
      database__connection__password: your_database_root_password
      database__connection__database: ghost
      - /docker/ghost/content:/var/lib/ghost/content

    image: mysql:5.7
    restart: always
      MYSQL_ROOT_PASSWORD: your_database_root_password
      - /docker/ghost/mysql:/var/lib/mysql

Start the stack.

docker-compose up -d


ufw allow OpenSSH
ufw allow 'Nginx Full'
systemctl start ufw
ufw enable

For testing, enable 2368 too.

ufw allow 2368/tcp 

ufw status numbered 
ufw delete <rule number> 


apt-get install fail2ban
systemctl enable fail2ban
systemctl start fail2ban
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

vim /etc/fail2ban/jail.local 

banaction = ufw
vim /etc/fail2ban/jail.d/custom.conf

enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
findtime = 120
fail2ban-client reload

fail2ban-client status

Nginx Configuration

vim /etc/nginx/sites-available/

server {

    # disable any limits to avoid HTTP 413 for large image uploads
    client_max_body_size 0;

    # required to avoid HTTP 411: see Issue #1486 (
    chunked_transfer_encoding on;

    location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-NginX-Proxy true;
            proxy_ssl_session_reuse off;
            proxy_set_header Host $http_host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_read_timeout 900;
            proxy_redirect off;

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

systemctl reload nginx