--- name: woocommerce-headless-setup category: devops description: Deploy WordPress + WooCommerce via Docker, automatically configure HTTPS with Caddy, and programmatically generate WooCommerce REST API keys without accessing the WP Admin UI. --- # Headless WooCommerce Setup & API Key Generation This skill provides a fully automated, UI-free method to deploy a secure WooCommerce store and extract its REST API credentials (Consumer Key & Secret). This is especially useful when spinning up stores for ERP integrations (like AtomK) or testing, completely bypassing the need for brittle browser automation (Playwright/DrissionPage). ## 1. Docker Compose Stack Use Caddy for zero-config HTTPS. **Pitfall**: When using the official `wordpress:cli` image alongside the `wordpress` image, you might encounter a `no matching entries in passwd file` error if you specify `user: xfs`. Use `user: "33:33"` (the `www-data` user/group) to ensure WP-CLI has the correct permissions to write to the shared `/var/www/html` volume. ```yaml # docker-compose.yml services: caddy: image: caddy:latest restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./Caddyfile:/etc/caddy/Caddyfile - caddy_data:/data - caddy_config:/config depends_on: - wordpress db: image: mariadb:10.6 restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: secretrootpassword MYSQL_DATABASE: wordpress MYSQL_USER: wpuser MYSQL_PASSWORD: wppassword volumes: - db_data:/var/lib/mysql wordpress: image: wordpress:latest restart: unless-stopped environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: wpuser WORDPRESS_DB_PASSWORD: wppassword WORDPRESS_DB_NAME: wordpress volumes: - wp_data:/var/www/html depends_on: - db wpcli: image: wordpress:cli user: "33:33" command: tail -f /dev/null volumes: - wp_data:/var/www/html environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: wpuser WORDPRESS_DB_PASSWORD: wppassword WORDPRESS_DB_NAME: wordpress depends_on: - db - wordpress volumes: caddy_data: caddy_config: db_data: wp_data: ``` ```caddyfile # Caddyfile example.com { reverse_proxy wordpress:80 } ``` ## 2. Automated Installation via WP-CLI Once containers are running (`docker compose up -d`), execute the installation: ```bash # Install WordPress Core docker compose exec wpcli wp core install \ --url=https://example.com \ --title="My Store" \ --admin_user=admin \ --admin_password="password123!" \ --admin_email=admin@example.com \ --skip-email # Install WooCommerce and Theme docker compose exec wpcli wp plugin install woocommerce --activate docker compose exec wpcli wp theme install storefront --activate ``` ## 3. Programmatic API Key Generation Generating WooCommerce API keys usually requires clicking through the web UI. You can completely bypass this by injecting the keys directly into the database using a PHP script executed via `wp eval-file`. Create `create_wc_key.php`: ```php $user->ID, 'description' => 'Auto-generated API Key', 'permissions' => 'read_write', 'consumer_key' => wc_api_hash( $consumer_key ), 'consumer_secret' => $consumer_secret, 'truncated_key' => substr( $consumer_key, -7 ) ); $wpdb->insert( $wpdb->prefix . 'woocommerce_api_keys', $data, array('%d', '%s', '%s', '%s', '%s', '%s') ); echo "CONSUMER_KEY:" . $consumer_key . "\n"; echo "CONSUMER_SECRET:" . $consumer_secret . "\n"; ``` ### Execution The file must be accessible inside the container's file system (e.g., mapped via the `wp_data` volume). ```bash # Copy into the shared docker volume sudo cp create_wc_key.php /var/lib/docker/volumes/_wp_data/_data/ # Execute via wp-cli docker compose exec wpcli wp eval-file create_wc_key.php ``` ## 4. Programmatic Application Password Generation If you need a standard WordPress Application Password (e.g., for REST API integration that isn't WooCommerce-specific), you can generate one instantly via WP-CLI: ```bash # Outputs only the raw password (e.g., kYdQ y7ei zea7 fwaL 8Cg6 qEEd) docker compose exec wpcli wp user application-password create admin "My App Name" --porcelain ``` ## Pitfalls & Lessons Learned - **Local Port Conflicts**: If running on a VM, an existing web server (like Nginx/Apache) might be binding ports 80/443. Check with `sudo lsof -i :80`. Stop and disable it (`sudo systemctl stop nginx && sudo systemctl disable nginx`) before starting Caddy. - **Background Startup**: When running `docker compose up -d` in automation, ensure it is run as a background task (`background=true`) or it will hang the execution context. - **Avoid UI Automation for Setup**: Bypassing the WordPress Admin UI for configuration is vastly superior, significantly faster, and far more stable than trying to use headless browsers to click through setup wizards.