๐Ÿ‘ป Ghostberry.
Ghost CMS ยท Raspberry Pi ยท Cloudflare Tunnel

Self-hosted blog,
one command away.

Ghostberry installs a production-ready Ghost CMS on your Raspberry Pi, fronted by a Cloudflare Tunnel โ€” no exposed ports, hardened containers, encrypted nightly backups.

$ curl -fsSL https://raw.githubusercontent.com/dm807cam/ghostberry/main/install.sh | sudo bash

Works on Raspberry Pi OS Bookworm (64-bit) and Debian / Ubuntu. Add --harden for ufw + unattended-upgrades.

What's in the box

Sensible defaults for a homelab that you'd actually trust in production.

๐Ÿ”’

Zero exposed ports

Traffic only reaches Ghost through your Cloudflare Tunnel. DDoS protection and WAF for free.

๐Ÿ›ก๏ธ

Hardened containers

All capabilities dropped by default, no-new-privileges, memory caps, log rotation.

๐Ÿ’พ

Encrypted backups

Nightly mysqldump + content tar, AES-256 via OpenSSL pbkdf2. restore.sh included.

๐Ÿš€

Systemd-native

Starts on boot, restarts on failure, integrates with journalctl like anything else.

๐Ÿ“

Pi-aware bootstrap

Enables memory cgroups, ensures 2 GB swap, installs Docker โ€” all idempotent.

๐Ÿ“ฆ

One-file config

Everything tunable lives in .env โ€” image pins, memory caps, mail, retention.

How it works

Three things to do โ€” the installer handles the rest.

  1. Flash 64-bit Raspberry Pi OS

    Pi 4 (2 GB+) or Pi 5. Enable SSH, log in. That's the only manual prep.

  2. Create a Cloudflare Tunnel

    In the Zero Trust dashboard โ†’ Networks โ†’ Tunnels. Add a public hostname pointing to http://ghost:2368. Copy the tunnel token.

  3. Run the installer

    Paste the one-liner, give it your domain and the token, wait ~3 minutes. Then visit https://your-domain/ghost to create your admin account.

FAQ

The questions that come up before you commit to running the script.

What does the installer actually do?

It checks you're on Debian/Pi OS aarch64, enables memory cgroups in the boot cmdline if missing, ensures โ‰ฅ 2 GB of swap, installs Docker via the official convenience script, clones the repo to /opt/ghostberry, writes .env (with auto-generated 40-char DB passwords and a backup encryption key), installs a systemd unit, drops a daily backup cron, and starts the stack. Re-run it any time โ€” it's idempotent.

Why Cloudflare Tunnel?

Your Pi never opens an inbound port. The tunnel makes an outbound connection to Cloudflare; their edge routes requests back through it. You get DDoS protection, a WAF, and TLS without managing certificates โ€” and you can put Cloudflare Access in front of /ghost if you want SSO on the admin panel.

Can I add my SMTP credentials during install?

Yes. The installer prompts you with an optional SMTP section after the Cloudflare token โ€” host, port, username, password, from-address. Skip it and Ghost still runs; mail features just stay off until you add the values to .env later. For unattended installs, pre-set MAIL_HOST, MAIL_USER, MAIL_PASSWORD, MAIL_FROM as environment variables and the prompt is skipped automatically.

How are secrets handled?

Everything sensitive lives in /opt/ghostberry/.env, mode 600, owned by your user. Database passwords and the backup encryption key are generated locally with OpenSSL โ€” they never leave the device.

What if I lose the Pi?

Restore from a backup archive on a fresh Pi. The encryption key in .env is the only thing you must back up out-of-band โ€” keep it in your password manager. The installer + your encrypted archive get you back to identical state.

Will it run on a Pi Zero / 32-bit OS?

No. Ghost and MySQL 8 require 64-bit ARM and at least ~1.5 GB of RAM in practice. A Pi 4 with 2 GB works; 4 GB is comfortable.

Is curl-piped-to-bash safe?

You're trusting this repo either way โ€” the alternative (clone, then run) executes the same code. If you'd rather inspect first, the script is plain bash: read install.sh on GitHub before piping it.