Website Self-Hosting with Orange Pi 3 LTS ✅
Overview
- Ghost docker container as the website engine, running the GUI and decoration.
- Cloudflare Tunnel to make the site publicly reachable on HTTPS 443 without port forwarding.
- Cloudflare handles custom domain andrewcieslak.work
- Docker runs "cloudflared" and the "ghost" container on Orange Pi 3 LTS
Step by Step instructions:
- NOTE!!! Wherever there is a "{VALUE}", this is a PLACEHOLDER that must be replaced by the value described within. Ex: {DEVICE_IP} means replace "{DEVICE_IP}" with your device IP address.
- Flash Orange Pi OS. Ensure WiFi connects on every boot of the Orange Pi through initial WiFi configuration when flashing OS, or manually through wpa_supplicant.
- Connect to the OrangePi through ssh: (OrangePi username first, device IP address 2nd)
ssh {USERNAME}@{ORANGEPI_IP}
- Install docker headless on Debian on the Orange Pi.
sudo apt update
sudo apt upgrade -y
curl -fsSL https://get.docker.com | sudo sh
sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker $USER
exit
- Re-enter ssh and then check:
docker run hello-world
- Install ghost on Orange Pi where 2368 is the Ghost port. First, create a folder for Ghost:
mkdir -p /opt/ghost
cd /opt/ghost
Create/edit compose file:
sudo nano docker-compose.yml
Paste this config. file:
version: "3.9"
services:
ghost:
image: ghost:5-alpine
container_name: ghost
restart: unless-stopped
ports:
- "2368:2368"
environment:
security__staffDeviceVerification: false
NODE_ENV: "production"
url: "https://www.{DOMAIN_NAME}"
database__client: "sqlite3"
database__connection__filename: "/var/lib/ghost/content/data/ghost.db"
server__trustProxy: "true"
volumes:
- ghost-content:/var/lib/ghost/content
volumes:
ghost-content:
Save and exit with Ctrl+O->Enter->Ctrl+X. Then launch and test Ghost with:
docker compose up -d
docker compose ps
- Install cloudflared on Orange Pi:
curl -L \
https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64 \
-o cloudflared
chmod +x cloudflared
sudo mv cloudflared /usr/local/bin/cloudflared
cloudflared --version
- Login to Cloudflare and select tunnel domain
cloudflared tunnel login
Select desired domain in browser from the given URL
- Create the tunnel
cloudflared tunnel create ghost-tunnel
This gives a tunnel UUID that must be saved.
- Create tunnel config file
sudo mkdir -p /etc/cloudflared
sudo nano /etc/cloudflared/config.yml
- Paste the following config. file
tunnel: {TUNNEL_UUID}
credentials-file: /home/{USERNAME}/.cloudflared/{TUNNEL_UUID}.json
ingress:
- hostname: {DOMAIN_NAME}
service: http://127.0.0.1:2368
- hostname: www.{DOMAIN_NAME}
service: http://127.0.0.1:2368
- service: http_status:404
- Wire DNS to the tunnel
cloudflared tunnel route dns ghost-tunnel {DOMAIN_NAME}
cloudflared tunnel route dns ghost-tunnel www.{DOMAIN_NAME}
- Launch the tunnel
cloudflared tunnel run ghost-tunnel
And test it with https://{DOMAIN_NAME} in any browser. Ghost should now be available, and adding "/ghost" to the end of the url opens the admin interface and starts to allow website editing.
- Redirect root to WWW at Cloudflare
"Rules"->"Overview"->"Redirect Rules"->"Custom filter expression"->
"When incoming requests match…"
- Field=Hostname
- Operator=equals
- Value={DOMAIN_NAME}
"Then..." - Type=Static
- URL=https://www.{DOMAIN_NAME}
- Status code=301
- Preserve query string=Checked
->Save rule.
- Once confirmed, lock in the settings via:
sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
systemctl status cloudflared
Now that I finished explaining this process and outlining it:
I realize that I likely can turn this into an executable script. The downside of this would be that it would likely only be configured for my exact install situation with the OrangePi 3 LTS OS image that I used, while this process above can likely be understood and extrapolated for more diverse use...