Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Deploy a PHP With Couchbase Application as Docker Containers

DZone's Guide to

Deploy a PHP With Couchbase Application as Docker Containers

See how to create an automatically provisioned Couchbase node and simplistic PHP application that writes and reads data from the Couchbase NoSQL node.

· Database Zone
Free Resource

Traditional relational databases weren’t designed for today’s customers. Learn about the world’s first NoSQL Engagement Database purpose-built for the new era of customer experience.

Earlier in the year, I wrote about containerizing applications written in various development technologies that communicate with Couchbase Server. For example, I had written about deploying a Golang application with Docker, a Java application with Docker, and a Node.js application with Docker. This time around we’re going to take a look at how to deploy a PHP container that communicates with a Couchbase Server container.

We’re going to create an automatically provisioned Couchbase node and simplistic PHP application that writes and reads data from the Couchbase NoSQL node.

Let’s first define the project structure that will represent both containers:

root
-- couchbase
-- -- configure.sh
-- -- Dockerfile
-- php
-- -- application
-- -- -- index.php
-- -- configuration
-- -- -- php.ini
-- -- Dockerfile
-- docker-compose.yml

Each container will have its own Dockerfile which will contain blueprint information for our setup. The docker-compose.yml file will build and deploy the containers using defined port and environment variable information.

Containerizing the PHP Application

Since this is a PHP tutorial, we’ll start by building our simple PHP application and containerizing it. Because we want to automate the deployment, we’ll be developing our php.ini file locally and copying it over during the build process.

Before we get to that part, let’s add some code to the index.php file:

<?php

    header("Content-Type: application/json");

    $cluster = new CouchbaseCluster("couchbase://" . getenv("COUCHBASE_HOST"));
    $bucket = $cluster->openBucket(getenv("COUCHBASE_BUCKET_NAME"), getenv("COUCHBASE_BUCKET_PASSWORD"));

    try {
        $result = $bucket->get("nraboy");
    } catch (CouchbaseException $e) {
        $bucket->insert("nraboy", array(
            "name" => "Nic Raboy",
            "social_media" => array(
                "twitter" => "https://www.twitter.com/nraboy",
                "website" => "https://www.thepolyglotdeveloper.com"
            )
        ));
        $result = $bucket->get("nraboy");
    }
    echo json_encode($result->value);

?>

In the above code, we’re saying that any data printed will be JSON format. We’re establishing a connection to a Couchbase cluster and opening a particular Bucket in that cluster. The catch here is that we’re using environment variables to define the cluster and Bucket. These will be set in the deployment process.

With the application connected, it will try to get a document from Couchbase by key. If that document doesn’t exist, it will be created and then obtained. The obtained document will be printed as a result.

Like I mentioned earlier, this is a simple application, nothing fancy. Now we can focus on the Docker aspect of this application.

Open the Dockerfile and include the following:

FROM php:5.6.30-apache

RUN apt-get update
RUN apt-get install -y wget lsb-release
RUN wget http://packages.couchbase.com/releases/couchbase-release/couchbase-release-1.0-2-amd64.deb
RUN dpkg -i couchbase-release-1.0-2-amd64.deb
RUN rm couchbase-release-1.0-2-amd64.deb
RUN apt-get update
RUN apt-get install -y libcouchbase-dev build-essential php5-dev zlib1g-dev
RUN pecl install pcs-1.3.3
RUN pecl install couchbase

WORKDIR /var/www/html

COPY ./configuration/php.ini /usr/local/etc/php/
COPY ./application/ /var/www/html/

RUN chown www-data:www-data . -R

The above says that we’re going to be using an Apache image. If you’ve ever used Couchbase with PHP, what comes next will look very familiar. All the dependency gather was taken straight from the Couchbase PHP documentation. The RUNcommand means that the dependencies will be gathered at build time, not run time.

With the dependencies available, the php.ini file is copied into the image as well as the index.php file. This brings us to the php.ini  file.

Instead of pasting a long and nasty chunk of configuration, it is best you just download the php.ini file from the official PHP GitHub repository. The only change we’re making is in regards to the extensions. Per the Couchbase PHP documentation, we need to add extension=couchbase.so .

Find the extensions section and add it there.

At this point, the PHP image can be built and we can deploy it as a container. However, we’re going to plan ahead and create a Compose file.

Open the docker-compose.yml file and include the following:

version: '2'

services:

    php:
        build: ./php
        ports:
            - 8080:80
        environment:
            - COUCHBASE_HOST=couchbase
            - COUCHBASE_BUCKET_NAME=default
            - COUCHBASE_BUCKET_PASSWORD=
        restart: always

The above defines a service called php with port mappings and environment variables. These variables match what we have in the PHP application. The image will be built from the Dockerfile found in the PHP project.

If you set the COUCHBASE_HOST to something remote, we’re good to go, but for this example, we’re going to use another container.

Containerizing Couchbase Server

The goal in containerizing Couchbase is that we’ll be automating it. There already exists a Docker image for Couchbase, but it isn’t pre-provisioned which can take time during a deployment process.

Open the Dockerfile file the Couchbase project and include the following:

FROM couchbase

COPY configure.sh /opt/couchbase

CMD ["/opt/couchbase/configure.sh"]

The above says that we’re going to use the official Couchbase image, but we’re going to copy a script into it and then run it at runtime. This script will provision the instance automatically.

Open the configure.sh file and include the following commands:

set -m

/entrypoint.sh couchbase-server &

sleep 15

curl -v -X POST http://127.0.0.1:8091/pools/default -d memoryQuota=512 -d indexMemoryQuota=512

curl -v http://127.0.0.1:8091/node/controller/setupServices -d services=kv%2cn1ql%2Cindex

curl -v http://127.0.0.1:8091/settings/web -d port=8091 -d username=$COUCHBASE_ADMINISTRATOR_USERNAME -d password=$COUCHBASE_ADMINISTRATOR_PASSWORD

curl -i -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD -X POST http://127.0.0.1:8091/settings/indexes -d 'storageMode=memory_optimized'

curl -v -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD -X POST http://127.0.0.1:8091/pools/default/buckets -d name=$COUCHBASE_BUCKET -d bucketType=couchbase -d ramQuotaMB=128 -d authType=sasl -d saslPassword=$COUCHBASE_BUCKET_PASSWORD

sleep 15

curl -v http://127.0.0.1:8093/query/service -d "statement=CREATE PRIMARY INDEX ON `$COUCHBASE_BUCKET`"

fg 1

Couchbase Server has its own RESTful API, which we’re trying to consume with a bunch of cURL commands. We are defining memory quotas, which services exist in the node, and authentication information.

Notice that many of the commands include environmental variables like $COUCHBASE_ADMINISTRATOR_USERNAME. This is because we’re going to pass them in via the docker-compose.yml file just like we did with the PHP application.

Open the docker-compose.yml file and make it look like the following:

version: '2'

services:

    couchbase:
        build: ./couchbase
        ports:
            - 8091:8091
            - 8092:8092
            - 8093:8093
        environment:
            - COUCHBASE_ADMINISTRATOR_USERNAME=Administrator
            - COUCHBASE_ADMINISTRATOR_PASSWORD=password
            - COUCHBASE_BUCKET=default
            - COUCHBASE_BUCKET_PASSWORD=

    php:
        build: ./php
        ports:
            - 8080:80
        environment:
            - COUCHBASE_HOST=couchbase
            - COUCHBASE_BUCKET_NAME=default
            - COUCHBASE_BUCKET_PASSWORD=
        restart: always

We’ve included another service called couchbase with a bunch of port mappings and environment variables. There is something important to note here though. Remember the COUCHBASE_HOST in the PHP section? It has a host which must match the service name of our database which is couchbase.

Deploy the Containers With Docker

With the foundation in place, it is time to deploy the two containers so we have a functional set of microservices.

From the Docker CLI, execute the following:

docker-compose run -d --service-ports --name couchbase couchbase
docker-compose run -d --service-ports --name php php

The above commands will build and deploy each of the images with the ports defined in the Compose file. From the web browser, http://localhost:8091 should get you to the Couchbase Server dashboard, and http://localhost:8080 should get you to your PHP application.

With success, you should see information saved to the database and displayed on the screen.

Conclusion

You just saw how to containerize and deploy a PHP application that communicates with a Couchbase NoSQL container. While our choice of application was simple, it can easily be extended to something more complicated using any of the available PHP frameworks.

This same guide can be seen with Node.jsGolang, and Java. If you’d like to learn more about containerizing Couchbase Server, I wrote a more thorough version here.

For more information on the Couchbase PHP SDK, check out the Couchbase Developer Portal.

Learn how the world’s first NoSQL Engagement Database delivers unparalleled performance at any scale for customer experience innovation that never ends.

Topics:
database ,containerization ,couchbase ,docker ,php ,tutorial

Published at DZone with permission of Nic Raboy, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}