apiVersion: apps/v1 kind: Deployment metadata: name: wordpress namespace: wordpress annotations: secret.reloader.stakater.com/reload: wordpress-secrets spec: replicas: 1 strategy: # RWO volume, single writer — the rolling default would deadlock on the # new pod waiting for a volume the old pod still holds. type: Recreate selector: matchLabels: app.kubernetes.io/name: wordpress template: metadata: labels: app.kubernetes.io/name: wordpress spec: securityContext: # wp-content must be writable by Apache (www-data, uid/gid 33) for # media uploads and plugin installs. fsGroup: 33 containers: - name: wordpress image: wordpress:7.1.3-php8.5-apache@sha256:ce31904fa1e51b73543fa2e35cc8f1747589b2abf48dc747b422749b88b77e9e ports: - name: http containerPort: 80 env: # The operator names the base Service after the MariaDB resource; # the CRD's separate primaryService/secondaryService fields are the # suffixed variants for replicated setups, which this is not # (replicas: 1). Not verified against a running cluster — if it is # wrong the pod fails loudly on connect at startup rather than # degrading quietly. Confirm with `kubectl get svc -n wordpress` # on first deploy. - name: WORDPRESS_DB_HOST value: wordpress-mariadb.wordpress.svc.cluster.local:3306 - name: WORDPRESS_DB_NAME value: wordpress - name: WORDPRESS_DB_USER value: wordpress - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: # Generated by the operator from the MariaDB CR — never # stored in Git or OpenBao. name: wordpress-mariadb-app key: password - name: WORDPRESS_CONFIG_EXTRA value: | define('WP_HOME', 'https://www.renner.uno'); define('WP_SITEURL', 'https://www.renner.uno'); define('FORCE_SSL_ADMIN', true); /* Traefik terminates TLS; without this WordPress sees plain HTTP and builds http:// URLs into every page and redirect. */ if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on'; } /* Core lives in the image, not on the volume — the updater would only fail against a read-only docroot. Plugin and theme installs are unaffected. */ define('WP_AUTO_UPDATE_CORE', false); /* No add_filter() here. WORDPRESS_CONFIG_EXTRA is eval'd inside wp-config.php, long before wp-settings.php loads the plugin API, so any add_filter call is a fatal error on every request — which is exactly what happened on first deploy. xmlrpc is handled at the ingress instead, by routing /xmlrpc.php through the Authentik gate. */ envFrom: # The eight WordPress salts. Rotating them in OpenBao invalidates # every session — which is the intended lever, not a side effect. - secretRef: name: wordpress-secrets volumeMounts: - name: content mountPath: /var/www/html/wp-content readinessProbe: httpGet: path: / port: http initialDelaySeconds: 10 periodSeconds: 10 livenessProbe: httpGet: path: / port: http initialDelaySeconds: 60 periodSeconds: 30 resources: requests: cpu: 50m memory: 256Mi limits: memory: 768Mi volumes: - name: content persistentVolumeClaim: claimName: wordpress-content --- apiVersion: v1 kind: Service metadata: name: wordpress namespace: wordpress spec: selector: app.kubernetes.io/name: wordpress ports: - name: http port: 80 targetPort: http