diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index b5d0a0c..5d102d9 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -30,30 +30,36 @@ fi # Default WordPress URL if not provided WORDPRESS_SOURCE_URL=${WORDPRESS_SOURCE_URL:-"https://wordpress.org/latest.zip"} -# Function to download and install WordPress +# Function to install WordPress: from the core baked into the image when +# present (fast, offline), otherwise downloaded from WORDPRESS_SOURCE_URL. install_wordpress() { - echo "WordPress not found. Downloading and installing from: $WORDPRESS_SOURCE_URL" - wget -O wordpress.zip "$WORDPRESS_SOURCE_URL" - - # Create a temporary directory for extraction - TEMP_DIR="/tmp/wordpress" - mkdir -p "$TEMP_DIR" - unzip wordpress.zip -d "$TEMP_DIR" - - # Find WordPress files - WP_ROOT=$(find "$TEMP_DIR" -name wp-config-sample.php -exec dirname {} \; | head -n 1) - - if [ -z "$WP_ROOT" ]; then - echo "Error: WordPress files not found in the downloaded archive." - exit 1 + if [ -f /usr/src/wordpress/wp-includes/version.php ]; then + echo "Installing bundled WordPress core from /usr/src/wordpress" + cp -r /usr/src/wordpress/. /var/www/html/ + chmod -R u+w /var/www/html + else + echo "WordPress not found. Downloading and installing from: $WORDPRESS_SOURCE_URL" + wget -O wordpress.zip "$WORDPRESS_SOURCE_URL" + + # Create a temporary directory for extraction + TEMP_DIR="/tmp/wordpress" + mkdir -p "$TEMP_DIR" + unzip wordpress.zip -d "$TEMP_DIR" + + # Find WordPress files + WP_ROOT=$(find "$TEMP_DIR" -name wp-config-sample.php -exec dirname {} \; | head -n 1) + + if [ -z "$WP_ROOT" ]; then + echo "Error: WordPress files not found in the downloaded archive." + exit 1 + fi + + # Move WordPress files to the correct location + mv "$WP_ROOT"/* /var/www/html/ + + # Clean up + rm -rf "$TEMP_DIR" wordpress.zip fi - - # Move WordPress files to the correct location - mv "$WP_ROOT"/* /var/www/html/ - - # Clean up - rm -rf "$TEMP_DIR" wordpress.zip - # chown -R nobody:nobody /var/www/html # Import database if WORDPRESS_DB_URL is set if [ -n "${WORDPRESS_DB_URL:-}" ]; then diff --git a/modules/containers.nix b/modules/containers.nix index bba3afa..1489e4e 100644 --- a/modules/containers.nix +++ b/modules/containers.nix @@ -15,10 +15,22 @@ d1DriverSrc ? null, # Package set providing the Rust toolchain for the native extensions. rustPkgs ? pkgs, + # WordPress core is baked into the image (at /usr/src/wordpress) so cold + # starts don't re-download it, and so the exact static-asset set is known + # (the Cloudflare Worker serves those files from Worker Assets — keep this + # version in sync with wordpress-cloudflare's WORDPRESS_VERSION). + wordpressVersion ? "7.0.1", + wordpressHash ? "sha256-vkzmfQpcj/qYT26PXi+V2ji/F5tKJhk0zZJ9QkHwQoY=", }: let phpBuild = import ../lib/php.nix { inherit pkgs php; }; + # WordPress core, extracted (fetchzip strips the leading "wordpress/" dir). + wordpressCore = pkgs.fetchzip { + url = "https://wordpress.org/wordpress-${wordpressVersion}.zip"; + hash = wordpressHash; + }; + phpExtensions = if d1DriverSrc == null then null @@ -94,6 +106,12 @@ pkgs.dockerTools.buildLayeredImage { mkdir -p var/www/html cp ${../conf/wp-config.php} wp-config.php + # Bake WordPress core into the image. The entrypoint installs it into the + # docroot on first boot (no runtime download). + mkdir -p usr/src + cp -r ${wordpressCore} usr/src/wordpress + chmod -R u+w usr/src/wordpress + # The APCu persistent object cache drop-in. The entrypoint installs it # as wp-content/object-cache.php unless WORDPRESS_OBJECT_CACHE=none. cp ${../conf/object-cache.php} object-cache.php diff --git a/mu-plugins/cloudflare-page-cache.php b/mu-plugins/cloudflare-page-cache.php new file mode 100644 index 0000000..b3ac373 --- /dev/null +++ b/mu-plugins/cloudflare-page-cache.php @@ -0,0 +1,118 @@ + array( 'X-WP-Cache-Secret' => $secret ), + 'blocking' => false, + 'timeout' => 2, + ) + ); +} + +/* + * Purge on content and configuration changes. A version bump invalidates + * the whole cache, so there is no need to enumerate affected URLs. + */ +foreach ( + array( + 'save_post', + 'deleted_post', + 'trashed_post', + 'untrashed_post', + 'comment_post', + 'edit_comment', + 'wp_set_comment_status', + 'switch_theme', + 'customize_save_after', + 'activated_plugin', + 'deactivated_plugin', + 'wp_update_nav_menu', + ) as $wp_cf_cache_hook +) { + add_action( $wp_cf_cache_hook, 'wp_cf_cache_purge', 10, 0 ); +}