New blog ...
In 2009, I created legendiary.at 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 dnsmichi.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 :-)
dnsmichi.at Ghost blog setup
Goal
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.
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 https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
apt update
apt-cache policy docker-ce
apt install docker-ce
curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Nginx
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 dnsmichi.at -d www.dnsmichi.at
Ghost Container
mkdir -p /docker/ghost
cd /docker/ghost/
mkdir content mysql
Create docker-compose.yml
vim docker-compose.yml
version: '3'
services:
ghost-server:
image: ghost:latest
restart: always
ports:
- 2368:2368
depends_on:
- ghost-db
environment:
url: https://dnsmichi.at
database__client: mysql
database__connection__host: ghost-db
database__connection__user: root
database__connection__password: your_database_root_password
database__connection__database: ghost
volumes:
- /docker/ghost/content:/var/lib/ghost/content
ghost-db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: your_database_root_password
volumes:
- /docker/ghost/mysql:/var/lib/mysql
Start the stack.
docker-compose up -d
Firewall
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>
fail2ban
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
[nginx-botsearch]
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/dnsmichi.at.conf
server {
server_name dnsmichi.at www.dnsmichi.at;
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/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_pass http://0.0.0.0:2368/;
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/dnsmichi.at/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/dnsmichi.at/privkey.pem; # 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/dnsmichi.at.conf /etc/nginx/sites-enabled/dnsmichi.at.conf
systemctl reload nginx