Drupal 8 with Composer on OpenBSD
Tags: drupal, cms, openbsd, composer
Published: 2019-10-08 01:12:44

---
title: Drupal 8 with Composer on OpenBSD
published: true
description: Drupal is a secure and powerful CMS. 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.
tags: drupal, cms, openbsd, composer
series: Drupal on OpenBSD
cover_image: https://thepracticaldev.s3.amazonaws.com/i/hqdg6xybd6rz1uj0dlvp.png
---

*\* The cover image is originally by [Little_Foxy](https://pixabay.com/users/Little_Foxy-8812002/) and edited with great appreciation.*

---

## Introduction

[Drupal](https://www.drupal.org) is a secure and powerful CMS aka [content management system](https://en.wikipedia.org/wiki/Content_management_system).
It's an open source platform, which is based on [Symfony](https://symfony.com/), a fast and robust [PHP](https://www.php.net/) web framework, nowadays.

I wrote about installing it by building source code:

{% link nabbisen/drupal-on-openbsd-4n39 %}

However, [using composer](https://www.drupal.org/docs/develop/using-composer) is [recommended officially](https://www.drupal.org/docs/8/install/step-1-get-the-code).
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](https://www.drupal.org/docs/8/install/add-composer-to-an-existing-site)".*

#### Environment

- __OS__: OpenBSD 6.5
- __Database__: Database: [MariaDB](https://mariadb.org/) 10.0
- __Web Server__: [httpd](https://man.openbsd.org/httpd.8)
- __App Server__: PHP 7.3
    - __CGI__: [PHP-FPM](https://php-fpm.org/)
    - __Package Manager__: [Composer](https://getcomposer.org/)
- __CMS__: Drupal 8.7

The system requirements of Drupal is:
https://www.drupal.org/docs/8/install/before-a-drupal-8-installation

---

## Tutorial of Installation

#### Prepare database

Create database and user:

```sql
CREATE DATABASE <database> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES ON <database>.* TO <dbuser>@'localhost' IDENTIFIED BY '<dbpassword>';
FLUSH PRIVILEGES;
```

#### Install App via Composer

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

```console
$ php-7.3 /usr/local/libexec/composer.phar create-project drupal-composer/drupal-project:8.x-dev <drupal-dir> --no-interaction
```

*\* 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 (https://git.drupalcode.org/project/drupal/raw/8.7.7/.csslintrc): Downloading (connecting.Downloading (100%)         
...
  - ../.gitattributes (https://git.drupalcode.org/project/drupal/raw/8.7.7/.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
```

Next, change the permissions:

```console
$ cd <drupal-dir>
# # files
# chown -R :www ./web/sites/default
# chmod -R g+w ./web/sites/default
```

*\* 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:

```console
$ mkdir ./config
# chown -R :www ./config
# chmod -R g+w ./config
```

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](https://dev.to/nabbisen/setting-up-openbsds-httpd-web-server-4p9f) with OpenBSD's httpd and [get a certificate](https://dev.to/nabbisen/lets-encrypt-certbot-for-openbsds-httpd-3ofd) of [Let's Encrypt](https://letsencrypt.org/) beforehand.

```apache
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"
        }
}
```

Configure [httpd.conf](https://man.openbsd.org/httpd.conf) like this.
`fastcgi socket` brings requests to Drupal via PHP-FPM :)

Besides, in comparison with [my past post](/nabbisen/drupal-on-openbsd-4n39), the root directory is different:

```diff
- root "/<drupal-dir>"
+ root "/<drupal-dir>/web"
```

Well, restart the web server:

```console
# rcctl restart httpd
```

Here we're ready.

#### Web installer

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

![web installer](https://thepracticaldev.s3.amazonaws.com/i/9kbd5yt08y0bczp7gejb.png)
![web installer](https://thepracticaldev.s3.amazonaws.com/i/tq7za7flsqwx8oogcp4r.png)

Database Configuration:

![web installer](https://thepracticaldev.s3.amazonaws.com/i/6jdiu1jmprmrn8kh33zb.png)

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

![web installer](https://thepracticaldev.s3.amazonaws.com/i/8pw5qdq9160wm1699vxd.png)
![web installer](https://thepracticaldev.s3.amazonaws.com/i/pwf0caslwkvgb3cg86j9.png)

The installation will start:

![web installer](https://thepracticaldev.s3.amazonaws.com/i/vfujxe6nmj1g7djrhbmw.png)

Wait seconds.

Site configuration will start:

![web installer](https://thepracticaldev.s3.amazonaws.com/i/8ncn8urimzrn1iw37kiw.png)
![web installer](https://thepracticaldev.s3.amazonaws.com/i/1jp9d6tgbzl0vqp7cxiu.png)
![web installer](https://thepracticaldev.s3.amazonaws.com/i/a7bzcrvo6zlf77qa36b5.png)

Finished :)

![finished](https://thepracticaldev.s3.amazonaws.com/i/6tqdbvgdjlxz0zkk6xtq.png)

#### Security verification

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

```console
# 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
```

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

```diff
  /**
   * Trusted host configuration.
  ...
   */
+ $settings['trusted_host_patterns'] = array(   
+   '^<fqdn>$',   
+ );
```

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

---

## References

The official documents about Drupal installation is:
https://www.drupal.org/docs/8/install
Also, about composer:

- https://www.drupal.org/docs/develop/using-composer/using-composer-to-install-drupal-and-manage-dependencies
- https://www.drupal.org/docs/develop/using-composer/using-composer-with-drupal

The end of support of Drupal 8 is announced as [Nov 2021](https://www.drupal.org/blog/plan-for-drupal-9#2).

## Conclusion

Thank you for your reading :)
Happy computing.