Skip to content

Instantly share code, notes, and snippets.

@statico
Created December 12, 2025 07:43
Show Gist options
  • Select an option

  • Save statico/8ee831c30ef111ece68690afbcffe58f to your computer and use it in GitHub Desktop.

Select an option

Save statico/8ee831c30ef111ece68690afbcffe58f to your computer and use it in GitHub Desktop.
wordpress static export using wget and cloudflare pages
#!/usr/bin/env bash
set -eo pipefail
SITE_URL="http://localhost:8080"
cd "$(dirname "$0")"
mkdir -p export
# Check if the site is up
if ! curl -s -o /dev/null $SITE_URL; then
echo "Site is not up"
exit 1
fi
# Copy favicon
cp wordpress/uploads/2017/06/favicon.png export/favicon.png
cp wordpress/uploads/2017/06/favicon.png export/favicon.ico
# Add a 404 page for CloudFlare Pages
cat > export/404.html << 'EOF'
<h1>Not Found</h1>
EOF
# Copying wp-content from the container
rsync -a \
--exclude='*.php' \
--exclude='*.tmp*' \
--exclude='cache/' \
--exclude='upgrade/' \
--exclude='upgrade-temp-backup/' \
--exclude='w3tc/' \
--exclude='w3tc-config/' \
--exclude='smush/' \
--exclude='debug.log' \
--exclude='*.log' \
wordpress/ export/wp-content/
# Use wget to crawl the site and save it to export/
# adjust-extension will dirs vs. files and CloudFlare Pages will handle this
wget \
--trust-server-names \
--recursive \
--adjust-extension \
--page-requisites \
--convert-links \
--no-parent \
--no-host-directories \
--directory-prefix=export \
--tries=1 \
--no-verbose \
--exclude-directories=wp-content,wp-admin,wp-json \
$SITE_URL
# Done
echo "Done."
#!/usr/bin/env bash
set -eo pipefail
ORIGINAL_URL="http://localhost:8080"
NEW_URL="https://mysite.com"
#NEW_URL="https://mysite.pages.dev"
cd "$(dirname "$0")"
# Replace the original URL with the new URL
find export -type f \( -name "*.html" -o -name "*.css" -o -name "*.js" \) -exec sed -i '' \
-e "s|$ORIGINAL_URL|$NEW_URL|g" \
{} \;
# Remove old stats script
find export -type f \( -name "*.html" -o -name "*.css" -o -name "*.js" \) -exec sed -i '' \
-e "s|<script src=\"https://some-stats-service/track.js\" data-token=\"ef06b08b\" defer></script>||g" \
{} \;
# Copy quote of the day script
cp qotd.js export/qotd.js
# Modify export/index.html to include the quote of the day script
#sed -i '' \
# -e "s|<\/body>|<script src=\"/qotd.js\"></script></body>|" \
# export/index.html
# Fix %3Fver= in URLs (replace %3F with ? to decode URL-encoded query strings)
# Use perl for safer handling of special characters
find export -type f \( -name "*.html" -o -name "*.css" -o -name "*.js" \) -exec perl -i -pe 's/%3Fver=/?ver=/g' {} \;
# Some filenames get saved with `?ver=...` in the actual filename. Fix that to remove it.
find export -type f -name "*\?ver=*" | while IFS= read -r file; do
newname="${file%%\?*}"
if [ "$file" != "$newname" ]; then
mv "$file" "$newname"
fi
done
#!/usr/bin/env bash
set -eo pipefail
cd "$(dirname "$0")"
wrangler pages deploy ./export --project-name=mysite
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
services:
mysite-db:
container_name: mysite-db
image: mysql:9
user: "1000:1000"
volumes:
- /Users/ian/mysite/wordpress/db/data:/var/lib/mysql
- /Users/ian/mysite/wordpress/db/custom.cnf:/etc/mysql/conf.d/custom.cnf:ro
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'sekrit'
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
security_opt:
- seccomp=unconfined
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 5s
retries: 10
mysite-wordpress:
container_name: mysite-wordpress
depends_on:
- mysite-db
ports:
- '8080:80'
image: wordpress:latest
user: "1000:1000"
restart: always
volumes:
- /Users/ian/mysite/wordpress/wordpress:/var/www/html/wp-content
- /Users/ian/mysite/wordpress/apache-config.conf:/etc/apache2/sites-available/000-default.conf
environment:
WORDPRESS_DB_HOST: mysite-db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
WORDPRESS_CONFIG_EXTRA: |
define('ALTERNATE_WP_CRON', true);
define('SS_CRON', true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment