Tag: EWWW

  • The PC Takes Care of Itself — Backup, Cache, Image Compression

    The PC Takes Care of Itself — Backup, Cache, Image Compression

    The PC Takes Care of Itself — Backup, Cache, Image Compression

    Self-hosting Build Series Part 4. Automation solves operations.


    TL;DR

    • Backup: Daily mariadb-dump at 03:00 → gzip → Obsidian Vault. 30-day rotation. Content safe even if the mini-PC dies.
    • DB Cache: Memory caching of repeated queries with Redis Object Cache. Page response speeds up by 30%.
    • Page Cache: Generating static HTML with WP Super Cache. No PHP processing from the second visitor onward.
    • Images: Automatic WebP conversion with EWWW. Average size reduction of 30-70%.
    • One setup, and forget it.

    1. The Real Work of Self-Hosting is Operation

    Initial setup takes 30 minutes, but the real work begins afterward. Who backs up daily, clears caches, and compresses images? Humans forget. So, automate.

    

    2. Backup — wp-backup.sh

    /home/worker/scripts/wp-backup.sh:

    #!/bin/bash
    set -euo pipefail
    
    BACKUP_DIR="/home/user/문서/Obsidian Vault/KnowledgeVault/Meta/backups/wordpress"
    DATE=$(date +%Y-%m-%d)
    LOG_DIR="/home/worker/logs"
    WEEK=$(date +%Y-W%V)
    LOG_FILE="$LOG_DIR/kimcorp-${WEEK}.log"
    
    mkdir -p "$BACKUP_DIR" "$LOG_DIR"
    
    START=$(date +%s)
    TARGET="$BACKUP_DIR/wp-${DATE}.sql.gz"
    
    # mariadb-dump → gzip
    if sudo docker exec wordpress-db-1 \
       mariadb-dump --single-transaction -u root -p"${DB_ROOT_PW}" wp \
       | gzip > "$TARGET"; then
        SIZE=$(du -h "$TARGET" | cut -f1)
        ELAPSED=$(( $(date +%s) - START ))
        echo "$(date '+%Y-%m-%d %H:%M') | [wp-backup] | OK | ${SIZE} | ${ELAPSED}s" >> "$LOG_FILE"
    else
        echo "$(date '+%Y-%m-%d %H:%M') | [wp-backup] | FAIL-L2 | dump error" >> "$LOG_FILE"
        exit 1
    fi
    
    # Rotate older than 30 days
    find "$BACKUP_DIR" -name "wp-*.sql.gz" -mtime +30 -delete
    

    Permission: chmod +x. Crontab:

    0 3 * * * /home/worker/scripts/wp-backup.sh
    

    Automatically executed daily at 03:00. First backup verification:

    ls -la "$BACKUP_DIR"
    # wp-2026-05-27.sql.gz  20K
    

    20KB represents an empty initial database. With 100 articles plus image metadata, the usual size ranges from 500KB to 5MB.

    Why Store in Obsidian Vault?

    The Obsidian Vault is already my note system = automatically synchronized to other PCs and phones (when using OneDrive or Syncthing). There’s no need for a separate backup medium. Even if the mini-PC dies, backup copies remain intact on my laptop and phone.


    3. Redis Object Cache — Caching DB Queries

    WordPress sends an average of 50 to 200 DB queries to display a page once. Out of these, 80% are repetitive (menus, options, settings).

    The Redis Object Cache caches these repetitive queries in memory:

    wp config set WP_REDIS_HOST redis --allow-root
    wp config set WP_REDIS_PORT 6379 --allow-root
    wp config set WP_REDIS_PREFIX byeolgorae: --allow-root
    wp config set WP_CACHE true --raw --allow-root
    wp plugin install redis-cache --activate --allow-root
    wp redis enable --allow-root
    

    Verification:

    wp redis status --allow-root
    # Status: Connected
    # Client: PhpRedis (v6.x)
    

    Experience: Page response times decrease from 300ms to 200ms (30% faster).


    4. WP Super Cache — Page Caching

    While Redis caches DB queries, WP Super Cache caches the finished HTML itself.

    Visit Redis Only Redis + Super Cache
    First visitor Execution of PHP + Redis cache miss → DB → response Execution of PHP + generation of static HTML
    2nd visit onward Execution of PHP + Redis cache hit → response (~200ms) No PHP processing. Direct response with static file (~50ms)

    After installation, activate via GUI:
    – Settings → WP Super Cache → Easy tab
    – Select “Caching On (Recommended)” radio button
    – Update Status

    Cannot be activated via wp-cli (command not registered). Requires a single manual click from my side.

    ⚠ Pitfall: Logged-in users (like myself) do not receive the page cache (this is intentional). After publishing, there might be confusion when I ask “Why can’t I see it?” Switching to incognito mode reveals the correct display.


    5. EWWW Image Optimizer — Automatic Image Compression

    Automatically converts uploaded images to WebP format + performs lossless compression.

    Format Size of the same photo
    JPEG (original) 800KB
    WebP (EWWW) 250KB (-69%)
    AVIF (EWWW paid) 150KB (-81%)

    If left with the default settings after installation, it works fine. Automatically converts new image uploads. Bulk conversion of older images can be done via the Bulk Optimize menu.

    Experience: Mobile page LCP (Largest Contentful Paint) improves from 2.5 seconds to 1.2 seconds.


    6. Summary — One Setup, Zero Operations

    Task Setup Time After
    wp-backup.sh + cron 10 minutes Automates daily at 03:00
    Redis Object Cache 3 minutes Permanent automation
    WP Super Cache GUI activation 1 minute Permanent automation
    EWWW Image Optimizer 1 minute Automatic with new image uploads

    A total of 15 minutes once = automation of operations completed.


    FAQ

    Q. How to restore the backup?

    gunzip -c wp-2026-05-30.sql.gz | sudo docker exec -i wordpress-db-1 mariadb -u root -p"${DB_ROOT_PW}" wp
    

    One line. Real restoration is recommended to be rehearsed about once a quarter.

    Q. Are images in wp_content/uploads also backed up?
    This script only backs up the database. For images, just add one line: tar -czf uploads-$DATE.tar.gz wp-content/uploads/. If handling manually via the Obsidian Vault, no separate backup is necessary.

    Q. Can I use WP backup plugins like UpdraftPlus?
    It is possible. However, backing up within WP means that if WP fails, the backup also fails. A system-level cron is safer. UpdraftPlus can be installed as a backup but kept inactive.

    Q. What if Redis runs out of memory?
    For the Star Whale traffic scale (less than 10,000 monthly), it stays under 100MB. Even if memory fills, it automatically cleans up via LRU (Least Recently Used). No need to worry.

    Q. Isn’t it redundant to use WP Super Cache with Cloudflare CDN?
    Not redundant. The CDN serves static files (images, CSS), while Super Cache handles HTML. Keeping both active is the correct approach.


    Next Preview

    Part 5 — Star Whale Analytics: Visitor Statistics with Umami. Self-hosted instead of Google Analytics. No cookies + I own the data.


    One-Line Summary

    With a setup time of 15 minutes, backup, DB caching, page caching, and image compression run automatically daily. Operating time is zero, page speed increases by 30%, image sizes are reduced by 70%, and data remains secure.