How to build an OpenBSD, PHP, PostgreSQL, Lighttpd Development Stack

Updated on February 18, 2022
How to build an OpenBSD, PHP, PostgreSQL, Lighttpd Development Stack  header image

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.


Step 1: Install PHP

Install PHP.

# pkg_add php

Select 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-zip

Enable 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_fpm

Start PHP-FPM.

# rcctl start php74_fpm

Step 2: Install and Configure Lighttpd

Install Lighttpd using the following command:

# pkg_add lighttpd

Then, open and edit the main configuration file.

nano /etc/lighttpd.conf

Locate server.modules = (, and uncomment mod_fastcgi:

#                               "mod_setenv",
#                               "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/logs

Next, start Lighttpd in debug mode to check for errors in your configuration file.

# rcctl -df start lighttpd

Also, enable Lighttpd to start at boot time.

# rcctl enable lighttpd

Step 3: Install and Configure PostgreSQL

Install PostgreSQL.

 # pkg_add postgresql-server postgresql-client postgresql-contrib

Then, create the PostgreSQL Data directories.

# mkdir /var/postgresql/data

Grant Postgresql full permissions to the directory

# chown _postgresql:_postgresql /var/postgresql/data

Setup PostgreSQL

Log in as the PostgreSQL system user.

# su - _postgresql

Initialize PostgreSQL to the data directory.

$ initdb -D /var/postgresql/data


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 start

Now, switch back to root (Ctrl + D) or exit.

 $ exit

Enable PostgreSQL to start at boot time.

# rcctl enable postgresql

Start PostgreSQL.

# rcctl start postgresql

Create a PostgreSQL Database

Log in to the database server.

# psql -U _postgresql template1

Note that, _postgresql is the database administrator since the user created the initial configuration. Also, template 0 or template 1 are used as default template databases.

Create a new database.

CREATE DATABASE testdatabase;

Now, show all databases,


Your 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.


Exit the database console.


Now, log in as the new database user to the test database.

# psql -U admin testdatabase

Create a database.


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:



               List of relations
 Schema |  Name  | Type  | Owner
 public | sample | table | admin
(1 row)

Exit the console.


Step 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.php

Paste the following PHP code:


 phpinfo( );


Save and close the file.

Now, open your web browser, and visit your Vultr server address.


If your server is well set up, your PHP information is displayed.

Lighttpd PHP Info

Next, create a simple PHP application to test the communication between PHP and PostgreSQL databases.

# touch /var/www/htdocs/dbtest.php

Edit the file.

# nano /var/www/htdocs/dbtest.php

Paste the following PHP code:


$dbuser = 'admin';
$dbpass = 'password';
$dbserver = '';

    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.


The 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.log


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.