How to Deploy High-Performance WordPress on Netcup (Plesk Webhosting vs Docker + Redis Stack)
Netcup gives you two distinct architectural paths for hosting WordPress, and choosing the right one upfront prevents painful migrations later. Path A uses Netcup Managed Webhosting (Webhosting 2000 or 4000), providing managed Plesk Obsidian, inclusive .de domains, managed Postfix/Dovecot mail, and zero Linux kernel maintenance. Path B uses a Netcup KVM server (such as the 8 GB ECC RAM VPS 1000 G12.5 or the 4-core dedicated AMD EPYC RS 1000 G12.5) to run an isolated Docker Compose stack with PHP 8.3 OPcache, MariaDB 11 tuned InnoDB buffer pools, and persistent in-memory Redis Object Caching for sub-50ms Time to First Byte (TTFB). Below are the complete production runbooks for both architectures.
PREREQUISITES // ENVIRONMENT REQUIREMENTS
CHECKLIST- ✓ Either a Netcup Managed Webhosting plan (Webhosting 2000 / 4000 / 8000 with Plesk Obsidian) OR a Netcup KVM server (VPS 1000 G12.5 or RS 1000 G12.5 with 8 GB ECC RAM)
- ✓ A domain name (either one of the free bundled
.dedomains on Webhosting or an external domain pointed via DNS)
Key Takeaways
EXECUTIVE BRIEFING-
01 Choose Path A (Managed Plesk Webhosting 2000 or 4000) for corporate sites, blogs, and agency portfolios where bundled
.dedomains, managed IMAP email, and Plesk WordPress Toolkit staging save hours of systems administration. - 02 Choose Path B (VPS 1000 G12.5 or RS 1000 G12.5 + Docker/Redis) for high-concurrency WooCommerce stores, LMS portals, and membership sites that require a persistent in-memory Redis object cache and dedicated AMD EPYC Zen 5 CPU threads.
-
03 On both architectures, disabling WordPress’s synchronous
DISABLE_WP_CRONpage-load hook and replacing it with a real system cron job eliminates random 3-second page stalls.
📑 Quick Jump Table of Contents (3 Sections) ▼
1. Architecture Selection: Netcup Managed Webhosting vs KVM Server
Before installing WordPress, evaluate the architectural boundaries between Netcup’s managed Plesk Obsidian webhosting cluster and a self-managed KVM server. The right choice depends on whether your traffic consists primarily of cacheable anonymous pageviews or authenticated, database-intensive user sessions.
Content-driven sites—such as blogs, documentation portals, corporate landing pages, and agency portfolios—serve identical HTML to 95%+ of visitors. When paired with an Nginx-backed page caching plugin on Netcup Webhosting 2000 or 4000, PHP and MySQL are bypassed entirely after the first request, allowing shared NVMe storage to serve hundreds of thousands of monthly visitors with zero sysadmin overhead.
By contrast, dynamic WooCommerce stores, LearnDash LMS platforms, and BuddyPress communities set session cookies (woocommerce_items_in_cart, wp_woocommerce_session_, wordpress_logged_in_) that force Nginx to bypass full-page HTML caches. Every cart update, checkout step, or filtered product search executes 60 to 150 SQL queries against wp_postmeta and wp_options.
For those dynamic workloads, running your own Redis 7 persistent object cache and a dedicated MariaDB 11.4 daemon with a 2 GB–4 GB innodb_buffer_pool_size on an 8 GB ECC RAM VPS 1000 G12.5 or dedicated-core RS 1000 G12.5 keeps the entire database index pinned in DDR5 RAM, eliminating disk-read latency during checkout spikes.
| Technical Dimension | Path A: Webhosting 2000 / 4000 (Plesk Obsidian) | Path B: VPS 1000 G12.5 / RS 1000 G12.5 (KVM + Docker/Redis) |
|---|---|---|
| Compute & Memory Isolation | Shared multi-tenant Plesk environment | 8 GB ECC RAM + 6 vCPUs (VPS 1000) or 4 Dedicated EPYC Cores (RS 1000) |
| Included Free Domains & Email | 3 Free .de (WH 2000) / 6 Free .de (WH 4000) + Managed Mail | None bundled (self-host or use external mail) |
| PHP Worker Memory Limit | 512 MB (WH 2000) / 1,024 MB (WH 4000) | Configurable up to full 8 GB ECC server RAM |
| Persistent Object Cache | APCu / File Cache (No persistent Redis daemon) | Dedicated In-Memory Redis 7 / Valkey Daemon |
| Database Tuning (innodb_buffer_pool) | Managed shared MariaDB cluster | Dedicated MariaDB 11 tuned to 2 GB–4 GB RAM with O_DIRECT |
| OS & Security Maintenance | 100% Managed by Netcup (Plesk Obsidian) | Self-managed Linux kernel, UFW & backups |
2. Path A Runbook: Deploying & Tuning WordPress on Netcup Webhosting (Plesk Obsidian)
After provisioning Webhosting 2000 or Webhosting 4000, log in to the Netcup Customer Control Panel (customercontrolpanel.de), navigate to Products → Webhosting, and click Login to Plesk. Before launching the WordPress installer, claim your inclusive .de domains under Domains → Order Domain in the CCP so they automatically bind to your webhosting contract and generate the corresponding DNS zone and virtual host inside Plesk.
Once your domain is active in Plesk, open PHP Settings for the virtual host and select PHP 8.3 FPM application served by Nginx. Raise memory_limit to the tariff ceiling (512M on Webhosting 2000 or 1024M on Webhosting 4000), set max_execution_time to 120, and confirm that Zend OPcache (opcache.enable = on) is active. OPcache stores precompiled PHP bytecode in shared memory so the PHP engine does not re-parse and compile thousands of .php core and plugin files on every visitor request.
Next, open the WordPress Toolkit tab in Plesk to install WordPress and apply one-click filesystem hardening. Specifically, disable PHP script execution inside /wp-content/uploads/ (which blocks remote code execution if a vulnerable plugin allows an attacker to upload a disguised .php shell), disable xmlrpc.php (eliminating multicall brute-force amplification against user passwords), and set DISALLOW_FILE_EDIT in wp-config.php.
Finally, flip the Take over wp-cron.php switch inside Plesk WordPress Toolkit. By default, WordPress simulates scheduled tasks by firing a synchronous loopback HTTP request to wp-cron.php during normal visitor page loads—causing random 2-to-4-second TTFB stalls. Plesk’s takeover sets DISABLE_WP_CRON to true and registers a native operating-system cron job that executes scheduled publishing, WooCommerce webhooks, and plugin updates out-of-band every 10 minutes.
- ▪ 1. Claim Your Bundled
.deDomains First: In CCP under Domains → Order Domain, register your inclusive.dedomains so they automatically bind to your webhosting tariff. - ▪ 2. Issue Wildcard Let’s Encrypt SSL + HTTP/2: In Plesk under Websites & Domains → SSL/TLS Certificates, enable Let’s Encrypt for both the apex domain (
example.de),www, and webmail, and toggle "Redirect from HTTP to HTTPS (SEO-safe 301)". - ▪ 3. Tune PHP 8.3 FPM Settings in Plesk: Open PHP Settings for your domain, select PHP 8.3 FPM application served by Nginx, set
memory_limitto512M(on Webhosting 2000) or1024M(on Webhosting 4000), setmax_execution_timeto120, and verifyopcache.enable = onwithopcache.memory_consumption = 192. - ▪ 4. Install via WordPress Toolkit & Enable Security Hardening: Open WordPress → Install, complete the setup, and check all boxes under the Security tab (Disable PHP execution in
wp-content/uploads, Disable XML-RPC pingbacks, Change default database prefix, and Disable file editing in WP Admin). - ▪ 5. Replace WP-Cron with a Native Plesk Scheduled Task: Toggle Take over wp-cron.php inside Plesk WordPress Toolkit so background tasks run via a real Linux cron trigger every 10 minutes rather than slowing down visitor page requests.
3. Path B Runbook: High-Concurrency WordPress + MariaDB 11 + Redis 7 on Netcup KVM
When deploying on an 8 GB ECC RAM Netcup VPS 1000 G12.5 or RS 1000 G12.5, orchestrating WordPress 6.7+ (PHP 8.3), MariaDB 11.4 LTS, and Redis 7.4 inside an isolated Docker Compose bridge network (wp_internal) gives you complete control over memory allocation. Notice that the wordpress container binds strictly to 127.0.0.1:8080:80 so it sits safely behind your host-level Nginx or Caddy TLS 1.3 reverse proxy while MariaDB and Redis have zero host port mappings.
Database memory tuning is where a dedicated KVM server outperforms shared hosting by an order of magnitude. On an 8 GB server, allocating --innodb-buffer-pool-size=2G (or up to 4G on database-heavy WooCommerce stores) pins your entire wp_posts, wp_postmeta, and wp_wc_order_stats working set in RAM. Pairing this with --innodb-flush-method=O_DIRECT tells MariaDB to bypass the host Linux kernel’s filesystem page cache when writing to NVMe storage (preventing double-buffering of the same 2 GB dataset in RAM), while --innodb-flush-log-at-trx-commit=2 flushes redo logs to the OS kernel buffer on every transaction commit and syncs to physical NVMe once per second—multiplying write throughput by 3–4×.
When sizing PHP concurrency on an 8 GB server (after reserving 2 GB for MariaDB, 512 MB for Redis, and ~800 MB for the Ubuntu kernel and Nginx), roughly 4.5 GB of RAM remains available for PHP workers. Because a typical WooCommerce PHP worker consumes 70 MB–90 MB of resident set size (RSS) memory when Zend OPcache (opcache.memory_consumption = 192) is shared across workers, your server can comfortably sustain 45 to 50 concurrent PHP processes without ever touching swap.
Finally, wiring Redis 7.4 (--maxmemory 512mb --maxmemory-policy allkeys-lru) into wp-config.php via the Redis Object Cache drop-in caches serialized PHP objects and autoloaded wp_options rows in RAM. On a complex WooCommerce product page, persistent Redis object caching drops redundant MySQL queries from 90+ per request down to fewer than 5, cutting server-side PHP generation time from 380 ms to under 40 ms.
services:
mariadb:
image: mariadb:11.4
restart: unless-stopped
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --innodb-buffer-pool-size=2G
- --innodb-log-file-size=256M
- --innodb-flush-log-at-trx-commit=2
- --innodb-flush-method=O_DIRECT
- --max-connections=150
environment:
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MARIADB_DATABASE: wp_production
MARIADB_USER: wp_user
MARIADB_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/mysql
networks:
- wp_internal
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7.4-alpine
restart: unless-stopped
command: ["redis-server", "--maxmemory", "512mb", "--maxmemory-policy", "allkeys-lru"]
networks:
- wp_internal
wordpress:
image: wordpress:6.7-php8.3-apache
restart: unless-stopped
depends_on:
mariadb:
condition: service_healthy
redis:
condition: service_started
ports:
- "127.0.0.1:8080:80"
environment:
WORDPRESS_DB_HOST: mariadb:3306
WORDPRESS_DB_NAME: wp_production
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
WORDPRESS_CONFIG_EXTRA: |
define('WP_REDIS_HOST', 'redis');
define('WP_REDIS_PORT', 6379);
define('WP_CACHE', true);
define('DISABLE_WP_CRON', true);
define('DISALLOW_FILE_EDIT', true);
define('WP_MEMORY_LIMIT', '512M');
if (isset($$_SERVER['HTTP_X_FORWARDED_PROTO']) && $$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$$_SERVER['HTTPS'] = 'on';
}
volumes:
- wp_html:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini:ro
networks:
- wp_internal
volumes:
db_data:
wp_html:
networks:
wp_internal:
driver: bridge Command Explanation: Binds WordPress safely to 127.0.0.1:8080 (to sit behind your host Nginx or Caddy TLS proxy), configures MariaDB 11 with a 2 GB InnoDB RAM buffer pool and O_DIRECT NVMe I/O, and wires Redis 7 to wp-config.php.
SECURITY NOTE: Create /opt/stacks/wordpress/.env with chmod 0600 .env containing strong 32-character random strings (openssl rand -base64 24) for DB_ROOT_PASSWORD and DB_PASSWORD before running docker compose up -d.
# 1. Write custom PHP OPcache and upload limits
cat << 'EOF' > /opt/stacks/wordpress/uploads.ini
upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 512M
max_execution_time = 180
opcache.enable = 1
opcache.memory_consumption = 192
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.revalidate_freq = 2
EOF
# 2. Schedule a real system cron job every 5 minutes to replace WP-Cron
cat << 'EOF' | sudo tee /etc/cron.d/wordpress-cron
*/5 * * * * root docker exec wordpress-wordpress-1 php /var/www/html/wp-cron.php >/dev/null 2>&1
EOF Command Explanation: Configures PHP 8.3 OPcache to cache up to 20,000 PHP files in shared memory and executes scheduled WordPress tasks out-of-band via cron so real visitors never wait for background tasks during page loads.
Setting --innodb-buffer-pool-size=2G and --innodb-flush-method=O_DIRECT keeps your entire WordPress database index and product catalog pinned in DDR5 ECC RAM while avoiding double-buffering in the host Linux page cache.
Common Troubleshooting Scenarios
DIAGNOSTIC RUNBOOK [SYMPTOM] WordPress enters an infinite ERR_TOO_MANY_REDIRECTS loop behind Nginx or Cloudflare
Root Cause: WordPress receives plain HTTP on port 8080 from the reverse proxy without seeing HTTPS=on, causing it to redirect to https:// repeatedly.
Resolution: Ensure your reverse proxy sends X-Forwarded-Proto: https and include the HTTP_X_FORWARDED_PROTO check shown in WORDPRESS_CONFIG_EXTRA above.
[SYMPTOM] Uploading themes or plugins triggers 413 Request Entity Too Large
Root Cause: Either Nginx’s default client_max_body_size (1 MB) or PHP’s upload_max_filesize (2 MB) rejected the archive.
Resolution: Add client_max_body_size 128M; inside your Nginx server block and verify uploads.ini is mounted into /usr/local/etc/php/conf.d/uploads.ini.
[SYMPTOM] Redis Object Cache plugin shows Status: Not Connected inside WP Admin
Root Cause: The object-cache.php drop-in was installed before WP_REDIS_HOST was defined in wp-config.php, or the redis container is on a different Docker bridge network.
Resolution: Verify that both wordpress and redis belong to wp_internal in compose.yaml and run docker exec wordpress-wordpress-1 wp redis enable --allow-root (or click Enable Object Cache in the plugin settings).
Frequently Asked Questions
VERIFIED Q&AHow do I activate the Redis Object Cache inside WordPress after launching the Docker stack?
Log in to /wp-admin, go to Plugins → Add New, install the free Redis Object Cache plugin by Till Krüss, and click Enable Object Cache. Because WP_REDIS_HOST is already set to redis in WORDPRESS_CONFIG_EXTRA, it will immediately report Status: Connected.
Can I migrate an existing WordPress site to Netcup without downtime?
Yes. Deploy your target WordPress instance on Netcup first, use rsync or Duplicator/All-in-One WP Migration to copy wp-content and the database, test the site locally by pointing /etc/hosts to your new Netcup IP, and then lower your DNS TTL to 300 seconds before switching the A/AAAA records.
Is Netcup Webhosting 2000 fast enough for a blog with 50,000 monthly visitors?
Easily. When paired with a page-caching plugin (such as WP Super Cache, Cache Enabler, or W3 Total Cache) so anonymous visitors are served static HTML from Netcup’s SSD storage, Webhosting 2000 (512 MB PHP memory limit and 3 bundled .de domains) can handle hundreds of thousands of monthly pageviews.
When should I upgrade from Webhosting 4000 to an RS 1000 G12.5 Root Server for WordPress?
Webhosting 4000 provides 1,024 MB PHP memory and 6 inclusive .de domains, which is plenty for agency sites and small shops. Upgrade to the RS 1000 G12.5 (8 GB DDR5 ECC RAM and 4 dedicated AMD EPYC Zen 5 cores) when you need persistent Redis object caching, custom Elasticsearch/Meilisearch product search, or dedicated CPU threads for high-concurrency WooCommerce checkouts.
REFERENCES // VERIFIED TECHNICAL SOURCES
- [1] Official WordPress Docker Image Documentation (https://hub.docker.com/_/wordpress)
- [2] Netcup Webhosting 1000–8000 Official Specifications (https://www.netcup.com/en/hosting)