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.
Join the DZone community and get the full member experience.
Join For FreeEarlier 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 RUN
command 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.js, Golang, 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.
Published at DZone with permission of Nic Raboy, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments