DEV Community

Cover image for Drupal 8 with Composer on OpenBSD

Posted on • Updated on

Drupal 8 with Composer on OpenBSD

* The cover image is originally by Little_Foxy and edited with great appreciation.


Drupal is a secure and powerful CMS aka content management system.
It's an open source platform, which is based on Symfony, a fast and robust PHP web framework, nowadays.

I wrote about installing it by building source code:

However, using composer is recommended officially.
Additionally, I found building the environment under composer would be helpful at updating the system later.

Therefore, I tried to install it via composer.

* Note: There is another way to "Add Composer to an existing site".


  • OS: OpenBSD 6.5
  • Database: Database: MariaDB 10.0
  • Web Server: httpd
  • App Server: PHP 7.3
  • CMS: Drupal 8.7

The system requirements of Drupal is:

Tutorial of Installation

Prepare database

Create database and user:

CREATE DATABASE <database> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Enter fullscreen mode Exit fullscreen mode

Install App via Composer

<drupal-dir> means your Drupal's root directory.

$ php-7.3 /usr/local/libexec/composer.phar create-project drupal-composer/drupal-project:8.x-dev <drupal-dir> --no-interaction
Enter fullscreen mode Exit fullscreen mode

* Caution: It is NOT necessary to modify the part "drupal-composer/drupal-project:8.x".

It takes minutes.
The result is:

Installing drupal-composer/drupal-project (8.x-dev bdaa8fd53b120fa556e44cbfaa42f4c56831b9bd)
  - Installing drupal-composer/drupal-project (8.x-dev bdaa8fd): Cloning bdaa8fd53b from cache
Created project in drupal
> DrupalProject\composer\ScriptHandler::checkComposerVersion
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 140 installs, 0 updates, 0 removals
  - Installing cweagans/composer-patches (1.6.7): Loading from cache
  - Installing drupal/core (8.7.7): Loading from cache
  - Installing drush/drush (9.7.1): Loading from cache
  - Installing vlucas/phpdotenv (v2.6.1): Loading from cache
paragonie/random_compat suggests installing ext-libsodium (Provides a modern crypto API that can be used to generate random bytes.)
Package phpunit/phpunit-mock-objects is abandoned, you should avoid using it. No replacement was suggested.
Writing lock file
Generating autoload files
  - .csslintrc ( Downloading (connecting.Downloading (100%)         
  - ../.gitattributes ( Downloading (Downloading (100%)         
> DrupalProject\composer\ScriptHandler::createRequiredFiles
Created a sites/default/settings.php file with chmod 0666
Created a sites/default/files directory with chmod 0777
Enter fullscreen mode Exit fullscreen mode

Next, change the permissions:

$ cd <drupal-dir>
# # files
# chown -R :www ./web/sites/default
# chmod -R g+w ./web/sites/default
Enter fullscreen mode Exit fullscreen mode

* Caution: There is no need to configure "setting.php" by doing such as cp ./web/sites/default/default.settings.php sites/default/settings.php.

Well, Drupal wants to create config dir out of the public directory called "web".
So let's prepare it:

$ mkdir ./config
# chown -R :www ./config
# chmod -R g+w ./config
Enter fullscreen mode Exit fullscreen mode

If this preparation is not completed, the error "create the directory ../config/sync failed" will occur in "Verify requirements" page of the web installer.

Build the server

You have to build a web server with OpenBSD's httpd and get a certificate of Let's Encrypt beforehand.

server "<fqdn>" {
        listen on $ext_addr port 80
        block return 301 "https://$SERVER_NAME$REQUEST_URI"
server "<fqdn>" {
        listen on $ext_addr tls port 443
        tls {
                certificate     "/etc/letsencrypt/live/<fqdn>/fullchain.pem"
                key             "/etc/letsencrypt/live/<fqdn>/privkey.pem"
        # optional:
        log {
                access  "<fqdn>-access.log"
                error   "<fqdn>-error.log"

        root "/<drupal-dir>/web"
        directory index index.php

        location "/*.php" { 
                fastcgi socket "/run/php-fpm.sock"
        location "/*.php[/?]*" { 
                fastcgi socket "/run/php-fpm.sock"
        location match "/[^\.]+/?$" {
                fastcgi socket "/run/php-fpm.sock"    
                request rewrite "/index.php/%1"
Enter fullscreen mode Exit fullscreen mode

Configure httpd.conf like this.
fastcgi socket brings requests to Drupal via PHP-FPM :)

Besides, in comparison with my past post, the root directory is different:

- root "/<drupal-dir>"
+ root "/<drupal-dir>/web"
Enter fullscreen mode Exit fullscreen mode

Well, restart the web server:

# rcctl restart httpd
Enter fullscreen mode Exit fullscreen mode

Here we're ready.

Web installer

Let's access to https://<fqdn> .
You will see the web installer running.
Just follow it :)

web installer
web installer

Database Configuration:

web installer

If you use "localhost" as database host, you might have to replace it with "".
Also, I recommend using "Table name prefix" also from the point of view of security.

web installer
web installer

The installation will start:

web installer

Wait seconds.

Site configuration will start:

web installer
web installer
web installer

Finished :)


Security verification

Reduce write permissions from a file, sites/default/settings.php, and a directory, sites/default:

# chmod g-w ./web/sites/default/settings.php
# # The target is just a directory and therefore the `-R` option is unnecessary:
# chmod g-w ./web/sites/default
Enter fullscreen mode Exit fullscreen mode

"Health check" of the system will perhaps want you to register trusted hosts.
Edit sites/default/settings.php like this:

   * Trusted host configuration.
+ $settings['trusted_host_patterns'] = array(   
+   '^<fqdn>$',   
+ );
Enter fullscreen mode Exit fullscreen mode

Here, don't forget escape sequence to use period because it means patterns.
For example, "^your.sub.domain$" should be "^your\.sub\.domain$".


The official documents about Drupal installation is:
Also, about composer:

The end of support of Drupal 8 is announced as Nov 2021.


Thank you for your reading :)
Happy computing.

Top comments (2)

backtobo profile image
Roberto Sabbi

Hi Heddi, I was very pleased to find your articles around OpenBSD. I have been a fan since 2001 (I saw the birth of PF), using it for most of my personal projects. Your article gave me the spin to set up my own web server, as I wouldn't trust anything else than OBSD in the wild. That's also the reason why I insist on using httpd.
So please, keep writing about it.
Now my question: I have set up httpd exactly as in your article, minus the obvious adaptations. Drupal works fine except for url aliases. I am using OBSD 6.6 and Drupal 8.8.5.
To my limited understanding, the issue is with the location match, not capturing properly. I also suspect that something of the original config may have gone lost with escaping. I have tried to fiddle with the lua pattern to no avail. Do you have the same issue?

nabbisen profile image
nabbisen • Edited

Hello, Roberto.
Thank you for your comments.

I'm sorrry I don't use URL aliases. Therefore, yours is the first to me.
Then I tried to test to create a Drupal alias: /test/3 (virtual path) -> / (real path). And I ran 2 cases:

  1. my.domain/test/3 -> my.domain/
    • Result: Failed
  2. my.domain/?q=test/3 -> my.domain/
    • Result: Success

So, how about using ?q=... query params?
Alternatively, If you want to configure it via httpd.conf, "request rewrite" might be available. I have met a similar issue in configuring Directus.

Besides, I'm happy to get such a chance to know better about Drupal, because I haven't used it well enough 😊

Well, I'm also pleased to get a message from OBSD earlier-users like you. Thank you, again.

I saw the birth of PF

That's great !
I'm making efforts to get familiar with PF and relayd... 😅