The OpenBSD, PHP, PostgreSQL, Lighttpd (OPPL) stack is a collection of important software that makes it possible to run dynamic applications on an OpenBSD server. With PHP as the backend script processor, PostgreSQL as a relational database, and Lighttpd as the web server, you can run modern dynamic self-hosted applications on your server.
In this article, you will learn how to build the OpenBSD, PHP, PostgreSQL, Lighttpd development stack on OpenBSD 7.0 and run PHP applications on the server.
Prerequisites
- Deploy an Open BSD 7.0 Rcs Server.
- SSH and Login as root.
- Install a modern OpenBSD text editor like Nano or Vim.
Step 1: Install PHP
Install PHP.
# pkg_add phpSelect your target version. In this article, we'll install PHP 7.4 (2).
Ambiguous: choose package for php
a 0: <None>
1: php-7.3.33
2: php-7.4.27
3: php-8.0.14
Your choice: Install common PHP extensions, most importantly the database driver php-pgsql:
# pkg_add php-pgsql php-pdo_pgsql php-gd php-intl php-xml php-zipEnable the PHP extensions.
# cp /etc/php-7.4.sample/* /etc/php-7.4/Next, enable PHP-FPM to start at boot time.
# rcctl enable php74_fpmStart PHP-FPM.
# rcctl start php74_fpmStep 2: Install and Configure Lighttpd
Install Lighttpd using the following command:
# pkg_add lighttpdThen, open and edit the main configuration file.
nano /etc/lighttpd.confLocate server.modules = (, and uncomment mod_fastcgi:
# "mod_setenv",
"mod_fastcgi",
# "mod_proxy",Then, locate the following lines:
## mod_simple_vhost module.
server.document-root = "htdocs/"
#### accesslog module
accesslog.filename = "logs/access.log"
## where to send error-messages to
server.errorlog = "logs/error.log"
# files to check for if .../ is requested
index-file.names = ( "index.html", "index.htm", "default.htm" )Change the =”htdocs/” to =”/htdocs/”, then modify index-file.names to include index.php. Your configuration lines should now look like this:
## mod_simple_vhost module.
server.document-root = "/htdocs/"
# files to check for if .../ is requested
index-file.names = ( "index.php", "index.html", "index.htm", "default.htm" )Next, find the following lines:
# chroot() to directory
server.chroot = "/var/www/"
server.username = "_lighttpd"
server.groupname = "_lighttpd"Change the server username and group name to www for easy setup of web files permissions. Your modified lines should now look like this:
server.username = "www"
server.groupname = "www"Finally, add the following configuration lines at the end of the file:
fastcgi.server = ( ".php" =>
((
"disable-time" => 0,
"socket" => "/run/php-fpm.sock",
))
)Save and close the file.
Grant Lighttpd ownership privileges to /htdocs, /logs directories under the chrooted directory /var/www/.
# chown -R www.www /var/www/htdocs
# chown -R www.www /var/www/logsNext, start Lighttpd in debug mode to check for errors in your configuration file.
# rcctl -df start lighttpdAlso, enable Lighttpd to start at boot time.
# rcctl enable lighttpdStep 3: Install and Configure PostgreSQL
Install PostgreSQL.
# pkg_add postgresql-server postgresql-client postgresql-contribThen, create the PostgreSQL Data directories.
# mkdir /var/postgresql/dataGrant Postgresql full permissions to the directory
# chown _postgresql:_postgresql /var/postgresql/dataSetup PostgreSQL
Log in as the PostgreSQL system user.
# su - _postgresqlInitialize PostgreSQL to the data directory.
$ initdb -D /var/postgresql/dataOutput:
The files belonging to this database system will be owned by user "_postgresql".
This user must also own the server process.
The database cluster will be initialized with locale "C".
The default database encoding has accordingly been set to "SQL_ASCII".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/postgresql/data ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 20
selecting default shared_buffers ... 128MB
selecting default time zone ... UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
Success. You can now start the database server using:
pg_ctl -D /var/postgresql/data -l logfile startNow, switch back to root (Ctrl + D) or exit.
$ exitEnable PostgreSQL to start at boot time.
# rcctl enable postgresqlStart PostgreSQL.
# rcctl start postgresqlCreate a PostgreSQL Database
Log in to the database server.
# psql -U _postgresql template1Note that,
_postgresqlis the database administrator since the user created the initial configuration. Also,template 0ortemplate 1are used as default template databases.
Create a new database.
CREATE DATABASE testdatabase;Now, show all databases,
\lYour new database should be listed, similar to the output below:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
--------------+-------------+-----------+---------+-------+-----------------------------
postgres | _postgresql | SQL_ASCII | C | C |
template0 | _postgresql | SQL_ASCII | C | C | =c/_postgresql +
| | | | | _postgresql=CTc/_postgresql
template1 | _postgresql | SQL_ASCII | C | C | =c/_postgresql +
| | | | | _postgresql=CTc/_postgresql
testdatabase | _postgresql | SQL_ASCII | C | C |
(4 rows)Next, create a database user with a strong password and privileges to set up new databases.
CREATE USER admin WITH PASSWORD 'strong-password' CREATEDB;Exit the database console.
EXITNow, log in as the new database user to the test database.
# psql -U admin testdatabaseCreate a database.
CREATE DATABASE phpsite;Switch to the database.
\c phpsite;Create a sample table.
CREATE TABLE sample ( username VARCHAR(50) NOT NULL, password VARCHAR (50) NOT NULL);Show database tables:
\dtOutput:
List of relations
Schema | Name | Type | Owner
--------+--------+-------+-------
public | sample | table | admin
(1 row)Exit the console.
EXITStep 4: Test the server
Using a test editor, create a new index.php in the document root directory /var/www/htdocs.
# nano /var/www/htdocs/index.phpPaste the following PHP code:
<?php
phpinfo( );
?>Save and close the file.
Now, open your web browser, and visit your Rcs server address.
http://Server-IP-AddressIf your server is well set up, your PHP information is displayed.

Next, create a simple PHP application to test the communication between PHP and PostgreSQL databases.
# touch /var/www/htdocs/dbtest.phpEdit the file.
# nano /var/www/htdocs/dbtest.phpPaste the following PHP code:
<?php
$dbuser = 'admin';
$dbpass = 'password';
$dbserver = '127.0.0.1';
$dbname='phpsite';
echo "<h2>Hello: ";
$dbconnect = pg_connect("host=$dbserver dbname=$dbname user=$dbuser password=$dbpass");
if ($dbconnect) {
echo "Database Connected Successfully</h2>";
}
else {
echo "Unfortunately database connection has failed</h2>";
}
?>Save and close the file.
Now, through your web browser session, load the PHP script.
http://Server-IP-Address/testdb.phpThe script should print a successful connection message; else, verify your database credentials in the script, and also check the Lighttpd error log.
# cat /var/www/logs/error.logConclusion
Congratulations, you have set up an OpenBSD 7.0 server with PHP, PostgreSQL, and Lighttpd to serve dynamic PHP Web pages. With the setup, you can deploy any PHP-based application like WordPress or Drupal on the server and set up multiple virtual hosts. For further information on setting up your server, refer to the Lighttpd documentation.