Discoveries

New WordPress installation

Create a new MySQL database

CREATE DATABASE wp_lindyhoppeln CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'lindyhoppeln'@'localhost';
GRANT ALL PRIVILEGES ON wp_lindyhoppeln.* To 'lindyhoppeln'@'localhost' IDENTIFIED BY 'passphrase';

utf8mb4 is the “real” Unicode. By default, MySQL is using an old, buggy own variant.

The database name must not contain dashes (or those must be quoted).

Wordpress

For Wordpress the following is my default choice:

Configure a new domain

First nginx, in sites-available:

server {
        listen 80;
      	listen [::]:80;
        server_name www.thomas-huehn.de;
        location /.well-known/acme-challenge {
		root /var/www/thomas-huehn/html;
	}
}

server {
        listen 80;
      	listen [::]:80;
        server_name thomas-huehn.de;
        root /var/www/thomas-huehn/html;
        index index.php index.html;
        location /.well-known/acme-challenge {
      	        root /var/www/thomas-huehn/html;
        }
}

Then acme.sh:

acme.sh --issue --nginx -d www.thomas-huehn.de -d thomas-huehn.de
acme.sh --install-cert -d www.thomas-huehn.de --key-file /etc/cert-files/key-www.thomas-huehn.de.pem --fullchain-file /etc/cert-files/cert-www.thomas-huehn.de.pem --reloadcmd "service nginx force-reload"

Check whether nginx has access to /etc/cert-files/ and reload:

systemctl reload nginx

Then fill in actual root section, in case of Wordpress:

root /var/www/thomas-huehn/html;
index index.php index.html;
location / {
      try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
      include snippets/fastcgi-php.conf;
      if ($uri !~ "^/uploads/") {
	      fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
      }
}
location ~ ^/wp-json/ {
      # if permalinks not enabled
      rewrite ^/wp-json/(.*?)$ /?rest_route=/$1 last;
}

And a redirect:

 location / {
         return 301 https://www.thomas-huehn.de$request_uri;
}

Then correct nginx configuration with redirect no-www to www and TLS:

 server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name www.thomas-huehn.de;
	ssl_certificate         /etc/cert-files/cert-www.thomas-huehn.de.pem;
	ssl_certificate_key     /etc/cert-files/key-www.thomas-huehn.de.pem;
	ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDH
	root /var/www/thomas-huehn/html;
	index index.php index.html;
	location / {
		try_files $uri $uri/ /index.php?$args;
	}
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		if ($uri !~ "^/uploads/") {
			fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
		}
	}
	location ~ ^/wp-json/ {
		# if permalinks not enabled
		rewrite ^/wp-json/(.*?)$ /?rest_route=/$1 last;
	}
}
server {
	listen 80;
	listen [::]:80;
	server_name www.thomas-huehn.de;
	location /.well-known/acme-challenge {
		root /var/www/thomas-huehn/html;
	}
	location / {
		return 301 https://www.thomas-huehn.de$request_uri;
	}
}
server {
	listen 80;
	listen [::]:80;
	server_name thomas-huehn.de;
	location /.well-known/acme-challenge {
		root /var/www/thomas-huehn/html;
	}
	location / {
		return 301 https://www.thomas-huehn.de$request_uri;
	}
}

Calling acme.sh with --test targets Letsencrypt's staging server.

Real cron for Wordpress

crontab -u www-data -e
* * * * * /usr/bin/php  /var/www/thomas-huehn/html/wp-cron.php
* * * * * /usr/bin/php  /var/www/lindyhoppeln/html/wp-cron.php

In wp-config-php. pretty much at the top:

/** Disable virtual cron */
define('DISABLE_WP_CRON', true);

Repair pingback

In wp-includes/cron.php: timeout 1 instead of 0.01:

$cron_request = apply_filters(
             'cron_request',
             array(
                     'url'  => add_query_arg( 'doing_wp_cron', $doing_wp_cron, site_url( 'wp-cron.php' ) ),
                     'key'  => $doing_wp_cron,
                     'args' => array(
                             'timeout'   => 1,

#linux #wordpress