WordPress with uptime monitoring: WordPress, MariaDB and Uptime Kuma

A WordPress site with its MariaDB database and an Uptime Kuma monitor on the same server, behind Caddy. Two checks tell a broken proxy or certificate from a broken site.

Reviewed 14 October 2026

Why these apps together

A small business or a blog runs its own WordPress and wants to hear about downtime before visitors do, without a paid monitoring service for the first checks.

Each app page deploys its app alone. Run together behind Caddy, Uptime Kuma can watch WordPress twice: through the public address, as visitors reach it (DNS, certificate, Caddy, WordPress), and directly at the container over the network Caddy shares with both. When only the first check fails, the problem is in front of WordPress. This page gives both addresses and states what a monitor on the same server cannot see.

Apps in this stack

AppRole in the stackLoad levelCompose support
WordPressThe site, with MariaDB as its database.LightRun-tested
Uptime KumaChecks the site every minute and sends the alerts.LightRun-tested

How the apps connect

Uptime Kuma to WordPress: http://wordpress:80
An HTTP monitor on the WordPress container itself, over Caddy's edge network: it answers whether WordPress and its database respond, whatever Caddy does.
Uptime Kuma to WordPress: https://<WORDPRESS_DOMAIN>
An HTTP(s) monitor on the public address from .env: the path visitors take, through public DNS, the certificate and Caddy.

Resources for the whole server

Computed by the Stack Sizer's engine for these apps and load levels: what the apps need, the system baseline and the safety headroom. The same input in the Stack Sizer gives the same numbers.

PartvCPURAM (GiB)Disk (GiB)
WordPress20.6257
Uptime Kuma0.50.51.7
System baseline0.11.258.4
Safety headroom0.520.4752.565
Recommended total3.122.8519.665

Caddy is not included in the resource calculation of the Stack Sizer or the Deployment Spec.

Open these apps in the Stack Sizer

Files from the Compose Generator

docker-compose.yml
# Generated by the ANAROQ Compose Generator: https://anaroq.com/tools/compose-generator
# Engine @anaroq/compose 1.0.0, catalog 2026.10.10, exposure caddy.
# Apps: wordpress 1.1.0, uptime-kuma 1.1.0 (supported, not run-tested).
# No secrets in this file: copy .env.example to .env and fill it in before `docker compose up -d`.

services:
  wordpress:
    image: "wordpress:7.1.3-php8.4-apache"
    restart: "unless-stopped"
    environment:
      WORDPRESS_DB_HOST: "wordpress-mariadb"
      WORDPRESS_DB_USER: "wordpress"
      WORDPRESS_DB_PASSWORD: "${WORDPRESS_DB_PASSWORD:?set WORDPRESS_DB_PASSWORD in .env}"
      WORDPRESS_DB_NAME: "wordpress"
    volumes:
      - "wordpress-data:/var/www/html"
    networks:
      - "wordpress-internal"
      - "edge"
    depends_on:
      wordpress-mariadb:
        condition: "service_healthy"
  wordpress-mariadb:
    image: "mariadb:12.3.3"
    restart: "unless-stopped"
    environment:
      MARIADB_DATABASE: "wordpress"
      MARIADB_USER: "wordpress"
      MARIADB_PASSWORD: "${WORDPRESS_DB_PASSWORD:?set WORDPRESS_DB_PASSWORD in .env}"
      MARIADB_RANDOM_ROOT_PASSWORD: "1"
    volumes:
      - "wordpress-mariadb-data:/var/lib/mysql"
    networks:
      - "wordpress-internal"
    healthcheck:
      test:
        - "CMD"
        - "healthcheck.sh"
        - "--connect"
        - "--innodb_initialized"
      interval: "10s"
      timeout: "5s"
      retries: 3
      start_period: "10s"
  uptime-kuma:
    image: "louislam/uptime-kuma:2.5.6"
    restart: "unless-stopped"
    environment:
      UPTIME_KUMA_DB_TYPE: "sqlite"
    volumes:
      - "uptime-kuma-data:/app/data"
    networks:
      - "uptime-kuma-internal"
      - "edge"
  caddy:
    image: "caddy:2.11.7-alpine"
    restart: "unless-stopped"
    environment:
      WORDPRESS_DOMAIN: "${WORDPRESS_DOMAIN:?set WORDPRESS_DOMAIN in .env}"
      UPTIME_KUMA_DOMAIN: "${UPTIME_KUMA_DOMAIN:?set UPTIME_KUMA_DOMAIN in .env}"
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - "./Caddyfile:/etc/caddy/Caddyfile:ro"
      - "caddy-data:/data"
      - "caddy-config:/config"
    networks:
      - "edge"
networks:
  wordpress-internal: {}
  uptime-kuma-internal: {}
  edge: {}
volumes:
  wordpress-data: {}
  wordpress-mariadb-data: {}
  uptime-kuma-data: {}
  caddy-data: {}
  caddy-config: {}
.env.example
# Generated by the ANAROQ Compose Generator: https://anaroq.com/tools/compose-generator
# Engine @anaroq/compose 1.0.0, catalog 2026.10.10, exposure caddy.
# Copy this file to .env and fill in every value. Never commit .env.
# ANAROQ does not create passwords or keys: generate them on your own machine.

# --- wordpress ---
# Password of the WordPress MariaDB user (MARIADB_PASSWORD and WORDPRESS_DB_PASSWORD).
# Secret, required. For example: openssl rand -hex 24
WORDPRESS_DB_PASSWORD=
# Public host name of the site behind the reverse proxy, for example blog.example.com.
# Required.
WORDPRESS_DOMAIN=

# --- uptime-kuma ---
# Public host name of Uptime Kuma behind the reverse proxy, for example status.example.com (a subdirectory is not supported).
# Required.
UPTIME_KUMA_DOMAIN=
Caddyfile
# Generated by the ANAROQ Compose Generator: https://anaroq.com/tools/compose-generator
# Engine @anaroq/compose 1.0.0, catalog 2026.10.10, exposure caddy.
# Each site address comes from .env through the Caddy container's environment.

{$WORDPRESS_DOMAIN} {
	reverse_proxy wordpress:80
}

{$UPTIME_KUMA_DOMAIN} {
	reverse_proxy uptime-kuma:3001
}

Generated by the Compose Generator's engine for these apps behind Caddy. The files hold no secrets: copy .env.example to .env and fill it in.

Compose Analyzer result

Error0
High0
Medium0
Low10
Info0

10 findings: 0 error, 0 high, 0 medium, 10 low, 0 info.

Low10

  1. LowAQ-HLTH-002Line 8, column 5services.wordpress

    wordpress has no healthcheck.

    Fix: Add a healthcheck, so Compose and you can tell when the service is ready.

  2. LowAQ-HLTH-005Line 8, column 5services.wordpress

    wordpress does not limit the size of its logs (logging.options.max-size).

    Fix: Limit the log size so logs cannot fill the disk.

  3. LowAQ-SEC-005Line 11, column 7services.wordpress.environment

    wordpress passes secrets through environment (WORDPRESS_DB_PASSWORD).

    Fix: Where the image supports it, use secrets: or a _FILE variable instead.

  4. LowAQ-HLTH-005Line 24, column 5services.wordpress-mariadb

    wordpress-mariadb does not limit the size of its logs (logging.options.max-size).

    Fix: Limit the log size so logs cannot fill the disk.

  5. LowAQ-SEC-005Line 27, column 7services.wordpress-mariadb.environment

    wordpress-mariadb passes secrets through environment (MARIADB_PASSWORD, MARIADB_RANDOM_ROOT_PASSWORD).

    Fix: Where the image supports it, use secrets: or a _FILE variable instead.

  6. LowAQ-HLTH-005Line 46, column 5services.uptime-kuma

    uptime-kuma does not limit the size of its logs (logging.options.max-size).

    Fix: Limit the log size so logs cannot fill the disk.

  7. LowAQ-HLTH-002Line 56, column 5services.caddy

    caddy has no healthcheck.

    Fix: Add a healthcheck, so Compose and you can tell when the service is ready.

  8. LowAQ-HLTH-005Line 56, column 5services.caddy

    caddy does not limit the size of its logs (logging.options.max-size).

    Fix: Limit the log size so logs cannot fill the disk.

  9. LowAQ-PORT-005Line 62, column 9services.caddy.ports.0

    This file publishes 3 port mappings. Docker publishes ports past ufw rules.

    Fix: Filter them in the DOCKER-USER chain or at the provider's firewall, or do not publish them.

  10. LowAQ-VOL-005Line 66, column 9services.caddy.volumes.0

    caddy bind-mounts the relative path ./Caddyfile.

    Fix: That works, but the data lives in the directory you run Compose from: back it up.

The Compose Analyzer (ruleset 1.0.0) checked docker-compose.yml: 0 error, 0 high, 0 medium and 10 low findings. A recipe is published only without error and high findings.

Continue in the tools

The link opens the Compose Generator with these apps, options and exposure, and with the Deployment Spec of this sizing, so cloud-init and the Runbook start from the same state.

Open in the journey

Runbook

Before the first start

  1. Copy .env.example to .env next to docker-compose.yml and fill in every value. Compose stops with an error while a required value is missing.
  2. Create WORDPRESS_DB_PASSWORD on your own machine, for example with openssl rand -hex 24. ANAROQ never creates passwords or keys.
  3. Keep Caddyfile next to docker-compose.yml; the Caddy container mounts it read-only.
  4. Ports 80 and 443 (TCP, and 443/UDP for HTTP/3) must be reachable from the internet for Caddy's automatic HTTPS.
  5. Before starting, point the A/AAAA records of the domain in WORDPRESS_DOMAIN (wordpress) to this server; Caddy requests its certificate on first start.
  6. Before starting, point the A/AAAA records of the domain in UPTIME_KUMA_DOMAIN (uptime-kuma) to this server; Caddy requests its certificate on first start.
  7. Start the stack with docker compose up -d and follow it with docker compose ps.

After the first start

  1. Create the Uptime Kuma admin

    Open the Uptime Kuma host name from .env and create the admin account on the first screen.

  2. Monitor the container

    Add an HTTP(s) monitor with the internal address below. It stays up while WordPress and MariaDB answer, even if Caddy or the certificate fails.

    http://wordpress:80
  3. Monitor the public address

    Add a second HTTP(s) monitor with https:// and the WordPress host name from .env, and connect a notification (email, chat) to both monitors.

What the apps share

  • A monitor on the same server goes down with it: a power, network or provider outage silences both. Keep one external check, or a second Uptime Kuma elsewhere, for the server itself.
  • Uptime Kuma gets its own public host name through Caddy. Create its admin account right after the first start, before anyone else can reach the page.
  • Back up WordPress's files and database and Uptime Kuma's data volume: the monitors and their history live there.

Alternatives

  • A hosted uptime service checks from outside and sees a server outage; it complements the internal check rather than replacing it.
  • Uptime Kuma alone, on another server, watches this site from outside: its own page sizes it. Uptime Kuma

Basis

Catalog
2026.10.10
Sizing policy
2026.10.0
Compose engine
@anaroq/compose 1.0.0
Analyzer ruleset
1.0.0

Sources

How profiles, sizes and Compose files are built is described in the methodology. Read the methodology

All self-hosted apps