Synopsis #
Deploy WordPress on OpenBSD with the base web server httpd(8)
, PHP-FPM from packages, and MariaDB from packages. OpenBSD runs the web server in a chroot(2)
at /var/www, so name resolution and interprocess communication must work from within that environment.
Privileged commands use doas; configure administrative access
first.
Preparation: Name Resolution in the httpd Chroot #
Ensure that processes running inside /var/www can resolve hostnames. Create the chroot’s /etc and provide resolver configuration per resolv.conf(5)
. Optionally create /etc/hosts entries per hosts(5)
.
doas sh <<'ROOT'
install -d -o root -g wheel -m 0755 /var/www/etc
cp -p /etc/resolv.conf /var/www/etc/resolv.conf
install -d -o root -g wheel -m 0755 /var/www/etc/ssl
cp -p /etc/ssl/cert.pem /var/www/etc/ssl/cert.pem
printf '127.0.0.1\tlocalhost\n' > /var/www/etc/hosts
ROOT
The resolver file enables DNS and the CA bundle enables HTTPS certificate verification from the PHP chroot. Refresh these copies when the host resolver configuration or trust bundle changes.
Install Required Packages #
Install PHP 8.3, the default PHP branch in OpenBSD 8.0, with matching extensions, MariaDB server and client tools, and basic utilities. Selecting the same PHP branch for every extension avoids mixing incompatible modules.
doas pkg_add php%8.3 php-curl%8.3 php-mysqli%8.3 \
php-zip%8.3 php-gd%8.3 php-intl%8.3 \
mariadb-server mariadb-client unzip
Configure PHP and PHP-FPM #
The package installs /etc/php-8.3.ini. Enable the installed extension configurations with symbolic links:
doas sh <<'ROOT'
cd /etc/php-8.3.sample
for module in curl mysqli zip gd intl; do
ln -sf ../php-8.3.sample/$module.ini ../php-8.3/
done
ROOT
PHP-FPM reads /etc/php-fpm.conf, which already defines a www pool and includes /etc/php-fpm.d/*.conf. Edit the existing pool rather than adding a second [www] definition. Confirm these settings in /etc/php-fpm.conf, retaining its other process-management settings:
doas vi /etc/php-fpm.conf
[www]
user = www
group = www
listen = /var/www/run/php-fpm.sock
listen.owner = www
listen.group = www
listen.mode = 0660
chroot = /var/www
Check the configuration, then enable and start the PHP-FPM daemon:
doas php-fpm-8.3 -t
doas rcctl enable php83_fpm
doas rcctl start php83_fpm
# Verify the service is enabled
doas rcctl ls on | grep php
# Verify the service is running
doas rcctl check php83_fpm
See rcctl(8) for service management.
Configure httpd #
Create /etc/httpd.conf with a single server stanza. The FastCGI socket path is relative to the chroot; PHP-FPM listens at /var/www/run/php-fpm.sock, which appears as /run/php-fpm.sock to httpd(8)
. Refer to httpd.conf(5)
for directive details.
doas vi /etc/httpd.conf
types { include "/usr/share/misc/mime.types" }
server "default" {
listen on egress port 80
root "/wordpress"
directory index index.php
location "*.php" {
fastcgi socket "/run/php-fpm.sock"
}
}
Start and enable the web server:
doas rcctl enable httpd
doas rcctl start httpd
# Verify the service is enabled
doas rcctl ls on | grep httpd
# Verify the service is running
doas rcctl check httpd
For a public site, configure HTTPS with a trusted certificate before completing setup or logging into administration. Follow the httpd TLS instructions and keep the WordPress document root and FastCGI location. Use plain HTTP only for isolated local testing.
Initialize MariaDB #
Initialize the database, start the server, and run the secure setup program. These tools are provided by the MariaDB packages.
doas mariadb-install-db
doas mkdir -p /var/run/mysql
doas chown _mysql:_mysql /var/run/mysql/
doas rcctl enable mysqld
doas rcctl start mysqld
doas mariadb-secure-installation
See MariaDB for additional configuration and diagnostics.
Download and Install WordPress #
Fetch the latest WordPress release, extract it, and place it under the httpd document root inside the chroot.
cd /tmp
ftp https://wordpress.org/latest.zip
doas unzip latest.zip
doas mv wordpress /var/www/
For improved security, keep WordPress core files read-only to the web server. A safe default is ownership by root:wheel, with write access granted only to directories that must be writable at runtime (typically wp-content/uploads; optionally plugin-specific cache/upgrade paths).
doas find /var/www/wordpress ! -name wp-config.php -exec chown -h root:wheel {} \;
doas find /var/www/wordpress -type d -exec chmod 755 {} \;
doas find /var/www/wordpress -type f ! -name wp-config.php -exec chmod 644 {} \;
# Runtime-writable content (minimum required)
doas install -d -o www -g www -m 0755 /var/www/wordpress/wp-content/uploads
# Optional: only if a plugin/theme requires write access
doas install -d -o www -g www -m 0755 /var/www/wordpress/wp-content/cache
doas install -d -o www -g www -m 0755 /var/www/wordpress/wp-content/upgrade
Avoid making the entire document root writable by www. When updates are performed through the admin UI, temporarily relax permissions only for required paths, then restore read-only ownership.
(ftp(1) is available in the OpenBSD base system. See ftp(1)
.)
Create the WordPress Database and User #
Connect to MariaDB and create a database and a dedicated user account with privileges limited to that database. Replace StrongPassword with a strong, unique database password.
doas mysql -u root -p
CREATE DATABASE wordpress;
CREATE USER 'wordpress'@'127.0.0.1' IDENTIFIED BY 'StrongPassword';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'127.0.0.1';
FLUSH PRIVILEGES;
EXIT;
Using 127.0.0.1 ensures TCP is used, which avoids reliance on the server’s UNIX socket from within the httpd chroot.
Configure WordPress #
Copy the sample configuration and edit the database parameters. Use the loopback address 127.0.0.1 for the database host to avoid socket path issues across the chroot boundary.
doas install -o root -g www -m 0640 /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php
doas vi /var/www/wordpress/wp-config.php
/** WordPress database name */
define('DB_NAME', 'wordpress');
/** Database username */
define('DB_USER', 'wordpress');
/** Database password */
define('DB_PASSWORD', 'StrongPassword');
/** Database hostname (use TCP) */
define('DB_HOST', '127.0.0.1');
wp-config.php contains the database password. Keep its owner as root:www and mode as 0640 so PHP-FPM can read it without making it world-readable. Keep these settings when changing core-file permissions. See the WordPress configuration-file security guidance
.
Complete the Installation #
Open the site’s HTTPS address in a browser. Follow the setup wizard to create the administrator account and enter the site details.
If permissions prevent writes, confirm that the document root is /var/www/wordpress, that uploads are writable by www, and that PHP-FPM is running and reachable at /run/php-fpm.sock from the chroot.
References #
Consult the Handbook-hosted manual pages for base utilities and configuration files discussed in this chapter: