diff --git a/.env b/.env index 8281e95..ada66ac 100644 --- a/.env +++ b/.env @@ -25,7 +25,6 @@ export NGINX_CACHE=nginx_cache export NGINX_CONF=./nginx/nginx.conf export NPP_NGINX_CONF=./nginx/default.conf export NPP_NGINX_PARAMS_CONF=./nginx/fastcgi_params -export NPP_NGINX_IP=172.19.84.1 export NPP_HTTP_HOST=localhost # WP-CLI Settings @@ -56,14 +55,15 @@ export NPP_GID_=33749 # NPP Development environment export NPP_DEV_ENABLED_=1 +export NPP_HACK_HOST_=1 export NPP_DEV_PLUGIN_NAME_=fastcgi-cache-purge-and-preload-nginx export NPP_DEV_PLUGIN_DIR_="${NPP_WEB_ROOT_}/wp-content/plugins/${NPP_DEV_PLUGIN_NAME_}" export NPP_DEV_TMP_CLONE_DIR_="/tmp/${NPP_DEV_PLUGIN_NAME_}" export NPP_DEV_PLUGIN_FILE_="${NPP_DEV_PLUGIN_DIR_}/${NPP_DEV_PLUGIN_NAME_}.php" export NPP_DEV_GITHUB_REPO_="https://github.com/psaux-it/nginx-fastcgi-cache-purge-and-preload.git" -# Plugins to auto Install (comma seperated) - Dev Tools -export NPP_PLUGINS_="${NPP_DEV_PLUGIN_NAME_},query-monitor,plugin-check,wp-crontrol,health-check" +# Plugins to auto Install (comma seperated) +export NPP_PLUGINS_="${NPP_DEV_PLUGIN_NAME_}" # Themes to auto Install (comma seperated) export NPP_THEMES_="blue-note" diff --git a/docker-compose.yml b/docker-compose.yml index 803f26e..9ce3eed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,13 +33,13 @@ services: if (defined('WP_CLI') && WP_CLI && !isset($$_SERVER['HTTP_HOST'])) $$_SERVER['HTTP_HOST'] = "${NPP_HTTP_HOST}"; - NPP_WEB_ROOT=${NPP_WEB_ROOT_} - NPP_NGINX_CACHE_PATH=${NPP_NGINX_CACHE_PATH_} - - NPP_NGINX_IP=${NPP_NGINX_IP} - NPP_HTTP_HOST=${NPP_HTTP_HOST} - NPP_USER=${NPP_USER_} - NPP_UID=${NPP_UID_} - NPP_GID=${NPP_GID_} - NPP_PLUGINS=${NPP_PLUGINS_} - NPP_THEMES=${NPP_THEMES_} + - NPP_HACK_HOST=${NPP_HACK_HOST_} - NPP_DEV_ENABLED=${NPP_DEV_ENABLED_} - NPP_DEV_PLUGIN_NAME=${NPP_DEV_PLUGIN_NAME_} - NPP_DEV_PLUGIN_DIR=${NPP_DEV_PLUGIN_DIR_} @@ -63,8 +63,10 @@ services: - /dev/fuse:/dev/fuse networks: npp_network: + extra_hosts: + - "host.docker.internal:host-gateway" post_start: - - command: /scripts/wp-cli.sh + - command: /scripts/wp-post.sh working_dir: ${NPP_WEB_ROOT_} user: root mem_limit: "2GB" @@ -132,7 +134,7 @@ services: depends_on: - wordpress volumes: - - ${WORDPRESS_HOME}:${NPP_WEB_ROOT_} + - ${WORDPRESS_HOME}:${NPP_WEB_ROOT_}:ro - ${NGINX_CACHE}:${NPP_NGINX_CACHE_PATH_} - ${NGINX_CONF}:/etc/nginx/nginx.conf - ${NPP_NGINX_CONF}:/etc/nginx/conf.d/default.conf @@ -150,7 +152,6 @@ services: - MOUNT_DIR=${MOUNT_DIR_} networks: npp_network: - ipv4_address: 172.19.84.1 mem_limit: "1.5GB" mem_reservation: "1GB" cpus: "1.0" @@ -178,7 +179,3 @@ networks: name: npp-wp driver: bridge enable_ipv6: false - ipam: - config: - - subnet: "172.19.0.0/16" - gateway: "172.19.0.1" diff --git a/wordpress/Dockerfile b/wordpress/Dockerfile index ae90fae..1fe9b20 100644 --- a/wordpress/Dockerfile +++ b/wordpress/Dockerfile @@ -43,6 +43,7 @@ RUN apt-get update && apt-get install -y \ # Install dependencies for service health checks mariadb-client \ netcat-traditional \ + iputils-ping \ # Install common dependencies curl \ # Install dev deploy dependencies @@ -104,11 +105,11 @@ RUN install-php-extensions ${PHP_EXTENSIONS} # Copy the scripts into the container COPY wordpress/entrypoint-wp.sh /entrypoint-wp.sh -COPY wordpress/wp-cli.sh /scripts/wp-cli.sh +COPY wordpress/wp-post.sh /scripts/wp-post.sh # Make sure scripts are executable RUN chmod +x /entrypoint-wp.sh -RUN chmod +x /scripts/wp-cli.sh +RUN chmod +x /scripts/wp-post.sh # Remove build time dependencies to keep image consistent RUN apt-get purge -y \ diff --git a/wordpress/entrypoint-wp.sh b/wordpress/entrypoint-wp.sh index 90781e8..e381d03 100755 --- a/wordpress/entrypoint-wp.sh +++ b/wordpress/entrypoint-wp.sh @@ -44,7 +44,6 @@ for var in \ NPP_GID \ NPP_NGINX_CACHE_PATH \ NPP_USER \ - NPP_DEV_ENABLED \ MOUNT_DIR; do if [[ -z "${!var:-}" ]]; then echo -e "${COLOR_RED}${COLOR_BOLD}NPP-WP-FATAL:${COLOR_RESET} Missing required environment variable(s): ${COLOR_LIGHT_CYAN}${var}${COLOR_RESET} - ${COLOR_RED}Exiting...${COLOR_RESET}" diff --git a/wordpress/wp-cli.sh b/wordpress/wp-post.sh similarity index 81% rename from wordpress/wp-cli.sh rename to wordpress/wp-post.sh index d1f318c..35c8c2d 100755 --- a/wordpress/wp-cli.sh +++ b/wordpress/wp-post.sh @@ -64,8 +64,8 @@ for var in \ NPP_UID \ NPP_GID \ NPP_DEV_ENABLED \ - NPP_NGINX_IP \ NPP_HTTP_HOST \ + NPP_HACK_HOST \ NPP_DEV_PLUGIN_NAME \ NPP_DEV_PLUGIN_DIR \ NPP_DEV_TMP_CLONE_DIR \ @@ -90,37 +90,97 @@ done # We need to sure '/var/www/html' exists for 'wp-cli' wait_for_service "wordpress" 9001 -# To enable NPP - Nginx Cache Preload action: -# ##################################################################### -# For Development Environment: -# - Cause HTTP_HOST is localhost, -# - Map the WordPress container's 'localhost' to Nginx's IP. -# - Note: This is a tricky hack and only used for the development environment! +# Resolve host +resolve_host() { + local host="$1" + local ipv4="" + local ip_fallback="" + local result=() + + # Try to get IPv4 address + ipv4="$(ping -4 -c 1 "$host" | grep -oP '(?<=\()[^)]+' | head -n 1)" + + # Fallback to find IP + ip_fallback="$(getent hosts "${host}" | awk '{ print $1 }')" + + # No IP found + if [[ -z "${ipv4}" && -z "${ip_fallback}" ]]; then + return 1 + # If both IPv4 and fallback IP are found + elif [[ -n "${ipv4}" && -n "${ip_fallback}" ]]; then + if [[ "${ipv4}" == "${ip_fallback}" ]]; then + # If both IPs are equal, return only one + result+=("${ipv4}") + else + # If both IPs are different, return both + result+=("${ipv4}") + result+=("${ip_fallback}") + fi + # If only one IP is found + elif [[ -n "${ipv4}" ]]; then + result+=("${ipv4}") + else + result+=("${ip_fallback}") + fi + + printf "%s\n" "${result[@]}" +} + +# To enable NPP Plugin Nginx Cache Preload action: +# ################################################################################################################## +# The NPP WordPress plugin uses "wget" with "WP_SITEURL" from inside the WordPress container to Preload Nginx Cache. +# This means that if "WP_SITEURL" is set to "localhost", wget will attempt to fetch URLs from +# the containers own loopback interface rather than reaching the Nginx server that handles +# Cache Preload requests. # -# For Production Environments: (Nginx sits on host or container) -# - I assume you use a publicly resolvable FQDN for WordPress (WP_SITEURL & WP_HOME); -# - Ensure outgoing traffic is allowed from the container. -# - Verify that /etc/resolv.conf in the container is correctly configured. -# - Verify that the container has internet access. -# + That's all for Cache Preload works like a charm. -####################################################################### -if [[ "${NPP_DEV_ENABLED}" -eq 1 ]]; then - IP="${NPP_NGINX_IP}" - LINE="${IP} ${NPP_HTTP_HOST}" +# To handle that; +# +# Development Environments: +# - During "wp core install", the "--url" parameter is hardcoded as "https://localhost", +# so WP_SITEURL ends up being "https://localhost" within the container. +# - In this scenario, Nginx Cache Preload requests will try to access "https://localhost", which +# incorrectly refers to the wordpress container itself. +# - To work around this, we update the wordpress containers "/etc/hosts" file to remap "localhost" to either +# "host.docker.internal" or the actual "Nginx container IP". This forces to retrieve resources +# from the correct endpoint, enabling the Nginx Cache Preload action during development. +# - Keep in mind! Below settings will not work here because of priority issue in /etc/hosts +# extra_hosts: +# - "localhost:Nginx_LAN_IP" +# +# Production Environment: +# - WP_SITEURL is typically set to an FQDN (example.com) pointing to Nginx. +# - If the WordPress container has WAN access, can resolve external domains, and allows outgoing traffic, +# Cache Preload requests will correctly reach Nginx over the WAN route. +# - If the wordpress container lacks WAN access, external DNS resolution, or outgoing traffic: +# - WP_SITEURL (example.com) must resolve internally to Nginx LAN IP. (Nginx can sits on host or as a container) +# - Solutions: +# 1. Internal DNS resolver mapping WP_SITEURL to Nginx's LAN IP. +# 2. Manually adding WP_SITEURL to /etc/hosts inside the wordpress container. +# 3. Recommended docker way, edit wordpress service in docker-compose.yml, +# extra_hosts: +# - "example.com:Nginx_LAN_IP" +################################################################################################################### +if [[ "${NPP_HACK_HOST}" -eq 1 ]]; then + # Create array + mapfile -t ip_array < <(resolve_host host.docker.internal) + + # Create temporary file + TEMP_HOSTS="$(mktemp /tmp/hosts.XXXXXX)" HOSTS="/etc/hosts" - # Check if the Nginx static IP defined - if ! grep -q "${IP}" "${HOSTS}"; then - # Map localhost to Nginx Static IP - echo -e "${LINE}\n$(cat ${HOSTS})" > /tmp/hosts.new - cat /tmp/hosts.new > "${HOSTS}" - rm -f /tmp/hosts.new - echo -e "${COLOR_GREEN}${COLOR_BOLD}NPP-WP:${COLOR_RESET} Mapped '${COLOR_LIGHT_CYAN}${NPP_HTTP_HOST}${COLOR_RESET}' to Nginx IP '${COLOR_LIGHT_CYAN}${IP}${COLOR_RESET}' in ${COLOR_LIGHT_CYAN}${HOSTS}${COLOR_RESET}." - else - echo -e "${COLOR_YELLOW}${COLOR_BOLD}NPP-WP:${COLOR_RESET} Mapping already exists: '${COLOR_LIGHT_CYAN}${NPP_HTTP_HOST}${COLOR_RESET}' -> '${COLOR_LIGHT_CYAN}${IP}${COLOR_RESET}'." + # Hack /etc/hosts kindly, not make container upset + # Map to host.docker.internal + if (( ${#ip_array[@]} )); then + for IP in "${ip_array[@]}"; do + echo "${IP} ${NPP_HTTP_HOST}" >> "${TEMP_HOSTS}" + done + + cat "${HOSTS}" >> "${TEMP_HOSTS}" + cat "${TEMP_HOSTS}" > "${HOSTS}" + echo -e "${COLOR_GREEN}${COLOR_BOLD}NPP-WP:${COLOR_RESET} ${COLOR_RED}Hacked!${COLOR_RESET} Mapped ${COLOR_LIGHT_CYAN}${NPP_HTTP_HOST}${COLOR_RESET} to host.docker.internal ${COLOR_LIGHT_CYAN}${ip_array[@]}${COLOR_RESET} in ${COLOR_LIGHT_CYAN}${HOSTS}${COLOR_RESET}." fi fi -####################################################################### +#################################################################################################################### # Check ownership of webroot for consistency check_ownership() {