Loading page...Загружаем страницу...正在加载页面...
AtlasRepo

How to Self‑Host WordPress with Docker and Strip Every Third‑Party Tracker

Description and use

The article explains how to deploy WordPress on Docker and strip all third‑party trackers, leaving only the site’s own domain.

Problem

A stock WordPress install on Docker reaches out to external services (api.wordpress.org, Gravatar, Google Fonts, etc.), leaking visitor data and violating privacy expectations.

Outcome

After applying the recipe, the WordPress site no longer contacts external trackers, reducing outbound domains to one and eliminating privacy leaks while retaining core functionality.

Workflow

  • 1. Create docker‑compose.yml with wordpress:6‑php8.3‑fpm, mariadb:11, nginx:alpine services and a dedicated bridge network.
  • 2. Mount ./wp-content:/var/www/html/wp-content to inspect theme functions.php for external font URLs.
  • 3. Add a wordpress:cli sidecar to run wp‑cli commands for plugin and cron inspection.
  • 4. Deploy a mu‑plugin (wp‑content/mu‑plugins/audit.php) that hooks pre_http_request to log every WP HTTP API call.
  • 5. Run wp cron event run --due-now to trigger scheduled update checks immediately.
  • 6. Capture outbound traffic: use browser DevTools Network tab for front‑end requests and tcpdump inside containers for DNS lookups.
  • 7. Identify external domains (e.g., api.wordpress.org, secure.gravatar.com, fonts.googleapis.com).
  • 8. Block or replace each: set DISALLOW_FILE_MODS to prevent core updates, disable Gravatar via wp-config.php, self‑host Google Fonts, remove Jetpack and its options, replace analytics with a self‑hosted tool.
  • 9. Verify by reloading the site in a private window and counting distinct external domains in DevTools; the baseline should drop to one domain (the site itself).

Evidence

A stock install of WordPress 6.x on Docker reaches out to api.wordpress.org on a schedule, loads visitor avatars from Gravatar, and the moment you add Jetpack, Akismet, Elementor or a theme that bundles Google Fonts remotely, your visitors' IP addresses start landing in logs you do not control.

Source

The fix is mechanical and takes an afternoon: a three-container compose stack, roughly a dozen constants in wp-config.php, a handful of remove_action calls in a must‑use plugin, locally hosted fonts, and a network capture to prove the page now talks to exactly one domain.

Source

Run wordpress:6-php8.3-fpm for PHP, mariadb:11 for the database and nginx:alpine as the front end, defined in a single docker-compose.yml.

Source

Drop a file in wp-content/mu-plugins/audit.php that hooks pre_http_request, writes the URL and debug_backtrace() to the PHP log, and returns null so nothing is blocked.

Source

  • Record date: 2026-10-01T07:53:05.577Z