Progress on setting up Hetzner server

cavelib-hetzner.local ¦ hetzner.caving-library.org.uk

Author: David Gibson. For page date see footer

This page gives a step-by-step installation check for the new server at Hetzner – notated here as {H}. The page is a shortened version of an earlier file on the new BCRA site, which contains notes on subdomains, and a general discussion of the BCRA migration to {H}. That page probably needs to be updated to match this one.

Because this page was constructed before the {H} sites were fully configured, it avoids such niceties as autoversion for CSS and JS so reminder to self it needs to be forcibly refreshed after changes to JS or CSS support files.

If the DNS points to {H}, but {H} is not configured to handle the request, it provides an Apache2 Debian Default Page at /var/www/html – for example, orphan.bcra.org.uk. The equivalent page at britiac4 is (for example) badsubdomain.bcra.org.uk.

Other pages in these installation notes ...
— introduction — 1. Migrating to Hetzner
— this page — 2. Progress on setting up Hetzner server
— table of domains / DNS settings / subdomain forwarding — 3. Domains and DNS
— check that protected pages work — Check Basic Auth
— For ISPconfig manual — see bcra.org.uk/migration_2025/ for ispconfig_3_1_manual.pdf  (17MB).
Other locations ...
— Misc. notes and programs to process data — /home/bcra/migration_notes
— List of hosts for XAMPP configuration — 4. xampp_notes.txp
— My local notes, probably incomplete and out-of-date —C:\_F\home\hetzner\_my_notes

There are several quick tests that we can make; although first of all we need to check whether PHP files are parsed by HTML.

Is PHP Installed?

If this string is echoed then PHP is probably running.
PHP short tags probably OK too

PHP Version 8.2.30, Handler cgi-fcgi

Are HTML files parsed for PHP?

Are sub-domain redirections working?

Some subdomains are intended to redirect to locations below the HTML root but this can be tricky to set up correctly. If PHP is running, the following diagnostics for subdomains might help...

Some other quick checks

Over the years, I have had problems with the following simple operations, caused by unexpected server settings. Thus it is as well to check them all.

Some more advanced operations

These are both 'tests' and also 'reminders to self' on how it all works.

PHP configuration settings

If PHP is running, we need to check where it is getting its configuration settings from. To do this, we set a parameter – max_execution_time – at different places in the code.

PHP reports max_execution_time = 89

However, it is not that simple, because some of the settings in my .user.ini file seem to be ignored. Its tedious, but we just have to go through them one by one. And we find ... that everything appears to be fine. So what was going on earlier? Well, one thing to watch out for is that user.ini is only parsed once every ten minutes!

For localhost only (and for this particular domain), htaccess sets the following parameters

  php_value	error_log	"/home/hetzner/clients/client5/web25/web/__error_logs/local.log"
  php_value	max_execution_time	87
  php_value	error_append_string	"<br>&nbsp;"
  php_value	user_agent		PHP/localhost
  php_value	short_open_tag 		On

The following table uses short PHP tags, as I was investigating a bug in my HTML editor, which keeps introducing random spaces and tabs int othe HTML.

Parameter and currently-reported value Set at localhost Set in ISPconfig Set in .user.ini
user_ini.filename -> .user.ini  ".user.ini"  
short_open_tag -> 1 On On  
max_execution_time -> 89 87 41 89
log_errors -> 1   On  
display_errors -> 1   Off  
error_log -> /
  var/
  www/
  clients/
  client5/
  web25/
  web/
  __error_logs/
  php_errors.log
/home/hetzner/clients/
client5/web25
/web/__error_logs/
local.log
${PHP_DOCUMENT_ROOT}

/web/__error_logs/
php_errors.log
 
date.timezone ->  currently unset  
error_reporting -> 32767   E_ALL  
default_charset -> UTF-8   "UTF-8"  
session.serialize_handler -> php   php  
error_append_string -> &nbsp;<br> <br>&nbsp; &nbsp;<br>  
memory_limit -> 222M   256M 222M
upload_max_filesize -> 6M   5M 6M
post_max_size -> 8M   7M 8M
max_input_time -> 61   59 61
file_uploads -> 1   On  
max_file_uploads -> 21   19 21
allow_url_fopen -> 1   On  
user_agent -> PHP (via user.ini) PHP/localhost PHP (via snippet) PHP (via user.ini)
default_socket_timeout -> 61   59 61

Loaded extensions and similar checks

Note to self: be sure to run this on the live server, and not at localhost!

get_loaded_extensions() reports ...

Array
(
    [0] => Core
    [1] => date
    [2] => libxml
    [3] => openssl
    [4] => pcre
    [5] => zlib
    [6] => filter
    [7] => hash
    [8] => json
    [9] => pcntl
    [10] => random
    [11] => Reflection
    [12] => SPL
    [13] => session
    [14] => standard
    [15] => sodium
    [16] => cgi-fcgi
    [17] => mysqlnd
    [18] => PDO
    [19] => xml
    [20] => calendar
    [21] => ctype
    [22] => curl
    [23] => dom
    [24] => mbstring
    [25] => FFI
    [26] => fileinfo
    [27] => ftp
    [28] => gd
    [29] => gettext
    [30] => iconv
    [31] => imap
    [32] => intl
    [33] => exif
    [34] => mysqli
    [35] => pdo_mysql
    [36] => pdo_sqlite
    [37] => Phar
    [38] => posix
    [39] => pspell
    [40] => readline
    [41] => shmop
    [42] => SimpleXML
    [43] => soap
    [44] => sockets
    [45] => sqlite3
    [46] => sysvmsg
    [47] => sysvsem
    [48] => sysvshm
    [49] => tidy
    [50] => tokenizer
    [51] => xmlreader
    [52] => xmlwriter
    [53] => xsl
    [54] => zip
    [55] => Zend OPcache
)

gd_info() reports ...

Array
(
    [GD Version] => 2.3.3
    [FreeType Support] => 1
    [FreeType Linkage] => with freetype
    [GIF Read Support] => 1
    [GIF Create Support] => 1
    [JPEG Support] => 1
    [PNG Support] => 1
    [WBMP Support] => 1
    [XPM Support] => 1
    [XBM Support] => 1
    [WebP Support] => 1
    [BMP Support] => 1
    [AVIF Support] => 1
    [TGA Read Support] => 1
    [JIS-mapped Japanese Font Support] => 
)

A test of exec() (example from https://www.php.net/manual/en/function.exec.php) gives

whoami
Returned with status 0 and output:
Array
(
    [0] => web25
)

and another ...

du --human-readable --summarize  /var/www/clients
Returned with status 1 and output:
Array
(
    [0] => 481M	/var/www/clients
)

Note: that's not very helpful, because to see the full disc usage requires us to be logged in as root, when it should report approx 190GB.

A test for GhostScript (example from Google AI) gives

Ghostscript not found.

For Info: Server Error 'no HTTP Host'

During testing, I noticed that there were a number of PHP errors caused by the code trying to access $_SERVER["HTTP_HOST"] when that was unset. That "shouldnt ever happen" but stackoverflow reports that it can happen if ... "the client is either very, very old (HTTP 1.0 doesn't support HTTP_HOST) or has made a request directly to your web site's IP."

To avoid cluttering the PHP error log I have implemented two tests ...

Obviously a better way to handle this would be to specify a rewrite in htaccess to look at {HTTP_HOST} and issue a 403 error if it is unset.

Server settings, via PHP

This is my previously-used presentation format of some similar data

If this string is echoed then PHP is probably running.
PHP short tags probably OK too.
HTTP_HOST -> hetzner.caving-library.org.uk
SERVER_ADDR -> 65.109.241.61
gethostbyaddr() -> srv1.bcra.org.uk
QUERY_STRING -> 
phpversion() -> 8.2.30
php_sapi_name() -> cgi-fcgi
php_uname() -> Linux srv1 6.1.0-44-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.164-1 (2026-03-09) x86_64
max_execution_time -> 89
error_log -> /var/www/clients/client5/web25/web/__error_logs/php_errors.log
PHP_SELF -> /_installation/2_progress.php
DOCUMENT_ROOT -> /var/www/caving-library.org.uk/web
SCRIPT_URI -> 
session.save_path -> /var/www/clients/client5/web25/tmp
upload_tmp_dir -> /var/www/clients/client5/web25/tmp
memory_limit -> 222M
open_basedir -> /var/www/clients/client5/web25/web
:/var/www/clients/client5/web25/private
:/var/www/clients/client5/web25/tmp
:/var/www/caving-library.org.uk/web
:/srv/www/caving-library.org.uk/web
:/usr/share/php5
:/usr/share/php
:/tmp
:/usr/share/phpmyadmin
:/etc/phpmyadmin
:/var/lib/phpmyadmin
:/dev/random
:/dev/urandom