Installing Drupal (PHP) As A First Time Cloud Foundry User

Ram Iyengar
Cloud Foundry Foundation
7 min readAug 28, 2020

Quick Summary:

The following is the transcript of a conversation between Ram Iyengar (Ram) and Lakshmi Narasimhan Parthasarathy (LNP). The relevant parts from the conversation have been extracted to serve as a tutorial to deploy a PHP application (Drupal) using Cloud Foundry.

Conversation:

LNP: Ok. Excited to begin! What are we looking at here?

Ram: Cloud Foundry is a PaaS, that helps developers deploy apps without having to context switch out of their command line. Getting started with Cloud Foundry has two basic steps. The first is to have an account with a Cloud Foundry provider. Second, installing the Cloud Foundry cli on your local (dev) machine.

LNP: Who are your providers?

Ram: The Cloud Foundry Foundation certifies certain infrastructure providers. All certified offerings are using the same core Cloud Foundry software and ensure application and skill portability across providers. You can choose from any of our providers below.

  • Pivotal
  • Anynines
  • SAP
  • IBM Cloud
  • SUSE

Alternatively, if you would like to use your own infrastructure, Cloud Foundry is available as a service/solution on all major providers.

For the scope of this exercise, I recommend using an existing provider — such as Anynines. Please go to the Anynines website and create an account.

LNP: Done. What next?

Ram: Install the CF CLI tools from the official GitHub repo.

LNP: Done. How does the local machine connect with the remote CF platform?

Ram: Easy — all communication is via the provider API. You first authenticate with the remote endpoint and all cf commands go through the API thereafter. The login is by using this command

cf login

LNP: Now that you’re logged in and the dev instance knows which remote instance to connect with, we can deploy the Drupal application.

LNP: Hold on. I’d like to know what an application is. Because, when we deploy Drupal, we need two applications to function. We need a functioning Drupal “core” and a database, let’s say MySQL.

Ram: In Cloud Foundry parlance, we have ‘applications’ and ‘services’. In this particular case, Drupal would be the application that is deployed on Cloud Foundry and MySQL would be a service that you would later create and bind to the application.

LNP: Can you give me other examples of cf services?

Ram: Sure. Logging and Monitoring services (ELK stacks), Redis, RabbitMQ, common databases (Postgres, Mongo, MySQL, Maria DB), and Elasticsearch are the ones that come to mind immediately. You can get a list of all the available services by running the following command on your terminal.

cf marketplace

Let’s setup the app next and go from there. The first thing you need to do is to get Drupal and push it using CF.

LNP: Ok. I’m going to run the init sequence using composer. Here’s the command I’m using:

composer create-project “drupal/recommended-project:8” cf-drupal

This has scaffolded Drupal 8 to a directory called cf-drupal on my local machine.

Ram: Ok. Great. Next, you will need to add the PHP extensions that are needed by Drupal during runtime. For this, create a folder called .bp-config and add a file named options.json within it. It will have the following contents:

(Path on local (dev) machine: ~/drupal-test/.bp-config/options.json)

LNP: Great, shall I now push the app?

Ram: Yes you may. Just type cf push and specify a name for the app.

LNP: Ok. Pushing now.

cf push drupal-test

LNP: The app has been deployed successfully. But it is unlikely that it is functional yet. We haven’t added a database. How do we do that? You mentioned that it is a service and needs to be bound somehow.

Ram: Yes. The scope of the CF push is limited. The php buildpack is detected and the remote server installs HTTPD and PHP 7, finally creating our droplet. Like you correctly pointed out, although the push returns a success message, some more steps are required to make this fully functional.

LNP: Got it. How do we now create a database and connect it with the application? By default, Drupal uses MariaDB.

Ram: Use the Anynines marketplace to identify the database you need. You can do this by running

cf marketplace

Like I mentioned before. When choosing a service, be sure to verify the service plan and the ‘broker’ label.

LNP: Ok. From the list of services here, I don’t see a MariaDB. We can use MySQL instead. But that needs an addition config step. I would have to override the default values form php.ini.

Ram: That can be done. First, create the service by using this command:

cf create-service a9s-mysql101 mysql-single-small drupal-dbCreating service instance db in org ●●●●●●●●● / space test as ●●●●●●●●●…OKCreate in progress. Use ‘cf services’ or ‘cf service db’ to check operation status.

LNP: Done. I see a success message. I’m guessing we need to bind the service and the app next?

cf bind-service drupal-test drupal-db

Ram: Yes. Before that you can verify that the environment variables have been set correctly by running

cf env drupal-testGetting env variables for app drupal-test in org ●●●●●●●●● / space test as ●●●●●●●●…OKSystem-Provided:{“VCAP_SERVICES”: {“a9s-mysql101”: [{“binding_name”: null,“credentials”: {“host”: “msd3535c9.service.dc1.a9ssvc”,“hosts”: [“msd3535c9-mysql-0.node.dc1.a9ssvc”],“name”: “msd3535c9”,“password”: “●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●”,“port”: 3306,“uri”: “mysql://a9s11a8618d63aac1d260a199dffdc5:a9sfeaff25457ec48d92f42a81cdb4c9684f88585c8@msd3535c9.service.dc1.a9ssvc:3306/msd3535c9”,“username”: “a9s11a8618d63aac1d260a199dffdc5”},“instance_name”: “db”,“label”: “a9s-mysql101”,“name”: “db”,“plan”: “mysql-single-small”,“provider”: null,“syslog_drain_url”: null,“tags”: [“sql”,“database”,“object-relational”,“consistent”],“volume_mounts”: []}]}}

Ram: To override the MariaDB defaults from the php.ini file, you will have to create the following path — .bp-config/php/php.ini.d and add a drupal.ini file. The contents of the file will be:

extension=pdo.soextension=pdo_mysql.so

LNP: This format is standard for any parameterized modifications that need to be done for reconfiguring any of the php.ini directives. I see that this is calling the MySQL Php Data Objects interface.

Ram: Yes. One last configuration step — navigate to web/sites/default inside your Drupal directory on your local machine. There, copy over the default.settings file to settings.php. Make the following modifications to the settings.php file:

$services = getenv(“VCAP_SERVICES”);$services_json = json_decode($services,true);$mysql_config = $services_json[“a9s-mysql101”][0][“credentials”];$databases[‘default’][‘default’] = array (‘database’ => $mysql_config[“name”],‘username’ => $mysql_config[“username”],‘password’ => $mysql_config[“password”],‘host’ => $mysql_config[“host”],‘port’ => $mysql_config[“port”],‘namespace’ => ‘Drupal\\Core\\Database\\Driver\\mysql’,‘driver’ => ‘mysql’,);

Ram: Ok, just to walkthrough what’s happening here — internally, Drupal will pick up the settings from the Cloud Foundry environment which has all the MySQL database information written to the environment variable.

Now — push the application once again so that it picks up all the changes to the settings.

LNP: Is there a special command for pushing an application that already exists?

Ram: No, the same command will do the trick.

cf push drupal-testname: drupal-testrequested state: startedroutes: drupal-test.de.a9sapp.eulast uploaded: Wed 19 Aug 18:05:11 IST 2020stack: cflinuxfs3buildpacks: php 4.4.16type: webinstances: 1/1memory usage: 256Mstart command: $HOME/.bp/bin/startstate since cpu memory disk details#0 running 2020–08–19T12:35:31Z 0.0% 25.4M of 256M 277.8M of 512M

Once successful, just hit the route that is shown in the summary. You obviously have to go through the Drupal install process, but this is an indication that the application is functional along with a database that is backing it up.

Once you go through the install process, you can upload sample assets to verify if it is working.

LNP: Now, before we close, you mentioned that Cloud Foundry is rather ‘opinionated’ and is built on 12-factor apps as a fundamental principle. A Drupal CMS isn’t exactly 12-factor. It falls short on one particularly important part which is the file system that Drupal will write to. The way you explain it, I feel it will get overwritten with every cf push. Is this assumption right? Not just that. If we have to scale the application at a later date, which all good applications have to, then adding a new instance would mean that there are now two distinct file systems that Drupal writes to. Depending on which instance you’re being served from, you will interact with a different set of files from the CMS, which cannot be good! What’s the mechanism to make this work so that we have a functional CMS without the storage being ephemeral?

Ram: The path to a persistent file system in Cloud Foundry is by using a mounted file system. This is provided by a ‘volume service’, much like the database service we saw before.

LNP: Excellent! I would love to explore this further and take it to that logical conclusion. I am also curious to find out what this will look like on Kubernetes-enabled infrastructure.

Ram: The aim is that there should be no difference. Once you configure cf-for-k8s or KubeCF, which are the two available ways to run Cloud Foundry over Kubernetes infrastructure — the same cf push experience would be available irrespective of language, framework, underlying infrastructure.

LNP: Perfect. I hope we have an opportunity to explore those in future too.

Lakshmi Narasimhan Parthasarathy has been programming professionally for about 15 years. He has worked with teams from all over the world. He is an avid open-source contributor and is presently consulting for several companies in the areas of DevOps, CI/CD, and PHP development. He is also working on a product called ShapeBlock that aims to add value by providing a great developer experience over Kubernetes.You can reach him at lakshmi@shapeblock.com.

Ram Iyengar is a Cloud Foundry Advocate and works as part of the team at the Cloud Foundry Foundation.

Cloud Foundry Summit Europe 2020 is built by and for the Cloud Foundry community. Whether you’re new to Cloud Foundry, you’re a long-time contributor building the platform, or you’re using Cloud Foundry to attain your business goals, Cloud Foundry Summit is the place to collaborate with other developers, operators, CIOs and IT professionals to shape the future of the project, share best practices and innovate together.

Dates: Oct 21st & 22nd 2020

The best way to connect with the Cloud Foundry community is to join our Slack Workspace at https://slack.cloudfoundry.org/. Those in the Slack community help you get quickly connected with other members or someone from the Cloud Foundry Foundation.

--

--

Ram Iyengar
Cloud Foundry Foundation

culture vulture. (d)evangelist. help tech find people, and vice versa.