This section uses the Guestbook application as an example to explain how to build container images in the Linux environment.
The Frontend component stores all the application logic for the Guestbook application and performs read/write operations with the Redis components.
Service names instead of IP addresses are used for component communication.
To check the Docker version, run the following command:
docker version
Example Docker version information:
Client: Version: 1.12.1 API version: 1.24 Go version: go1.6.3 Git commit: 23cf638 Built: Thu Aug 18 05:22:43 2016 OS/Arch: linux/amd64
In the command output, the Version field indicates the Docker version.
If the displayed version is earlier than 1.10.0 or the Docker is not installed, download Docker 1.10.0 or a later version at https://www.docker.com/ and install it by following the instructions provided at https://docs.docker.com/engine/installation/.
The purpose of 1 through 5 is to build a local code file of the Frontend component.
Code file structure of the Frontend component:
-- |---guestbook.php |---controllers.js |---index.html
mkdir guestbook
cd guestbook
mkdir frontend
cd frontend
vi guestbook.php
Content in the guestbook.php file:
<?php set_include_path('.:/usr/local/lib/php'); error_reporting(E_ALL); ini_set('display_errors', 1); require 'Predis/Autoloader.php'; Predis\Autoloader::register(); if (isset($_GET['cmd']) === true) { $host = 'redis-master'; header('Content-Type: application/json'); if ($_GET['cmd'] == 'set') { $client = new Predis\Client([ 'scheme' => 'tcp', 'host' => $host, 'port' => 6379, ]); $client->set($_GET['key'], $_GET['value']); print('{"message": "Updated"}'); } else { $host = 'redis-slave'; $client = new Predis\Client([ 'scheme' => 'tcp', 'host' => $host, 'port' => 6379, ]); $value = $client->get($_GET['key']); print('{"data": "' . $value . '"}'); } } else { phpinfo(); } ?>
In the guestbook.php file, one $host is set to redis-master (service name of the Redis_master component) and the other $host is set to redis-slave (service name of the Redis_slave component). CCE maps the service name of a component into its IP address so that components can access each other.
A service name must start with a lowercase letter and but it must not end with a hyphen (-). Only lowercase letters, digits, and hyphens (-) are allowed.
vi controllers.js
Content in the controllers.js file:
var redisApp = angular.module('redis', ['ui.bootstrap']); /** * Constructor */ function RedisController() {} RedisController.prototype.onRedis = function() { this.scope_.messages.push(this.scope_.msg); this.scope_.msg = ""; var value = this.scope_.messages.join(); this.http_.get("guestbook.php?cmd=set&key=messages&value=" + value) .success(angular.bind(this, function(data) { this.scope_.redisResponse = "Updated."; })); }; redisApp.controller('RedisCtrl', function ($scope, $http, $location) { $scope.controller = new RedisController(); $scope.controller.scope_ = $scope; $scope.controller.location_ = $location; $scope.controller.http_ = $http; $scope.controller.http_.get("guestbook.php?cmd=get&key=messages") .success(function(data) { console.log(data); $scope.messages = data.data.split(","); }); });
vi index.html
Content in the index.html file:
<html ng-app="redis"> <head> <title>Guestbook</title> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script> <script src="controllers.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.js"></script> </head> <body ng-controller="RedisCtrl"> <div style="width: 50%; margin-left: 20px"> <h2>Guestbook</h2> <form> <fieldset> <input ng-model="msg" placeholder="Messages" class="form-control" type="text" name="input"><br> <button type="button" class="btn btn-primary" ng-click="controller.onRedis()">Submit</button> </fieldset> </form> <div> <div ng-repeat="msg in messages track by $index"> {{msg}} </div> </div> </div> </body> </html>
vi Dockerfile
Docker can automatically build container images by reading instructions from a Dockerfile, which is a text file that contains all the commands needed to build an image.
Information to be added to the Dockerfile:
FROM php:5-apache RUN apt-get update RUN pear channel-discover pear.nrk.io RUN pear install nrk/Predis ADD guestbook.php /var/www/html/guestbook.php ADD controllers.js /var/www/html/controllers.js ADD index.html /var/www/html/index.html
docker build -t frontend .
Example image information:
Sending build context to Docker daemon 372.7 kB Step 1 : FROM php:5-apache 5-apache: Pulling from library/php 5c90d4a2d1a8: Pull complete 357b76a49838: Pull complete 0e87614c69f0: Pull complete a3a94d3df9be: Pull complete 8d889f91ade2: Pull complete 6aa1b9bbdc5d: Pull complete 777536a87ced: Pull complete c9ba89109223: Pull complete 2fb909a2ccf9: Pull complete b568c0efcb94: Pull complete c0887fadb409: Pull complete Digest: sha256:1985aed3a8242e35f598f0f2b08aea11ecdd623ba670cfbb1f078c689d98c42c Status: Downloaded newer image for php:5-apache ---> 7374b3b98172 Step 2 : RUN apt-get update ---> Running in 287defbad457 Get:1 http://security.debian.org jessie/updates InRelease [63.1 kB] Ign http://httpredir.debian.org jessie InRelease Get:2 http://httpredir.debian.org jessie-updates InRelease [142 kB] Get:3 http://httpredir.debian.org jessie Release.gpg [2373 B] Get:4 http://security.debian.org jessie/updates/main amd64 Packages [359 kB] Get:5 http://httpredir.debian.org jessie Release [148 kB] Get:6 http://httpredir.debian.org jessie-updates/main amd64 Packages [17.6 kB] Get:7 http://httpredir.debian.org jessie/main amd64 Packages [9032 kB] Fetched 9765 kB in 11s (875 kB/s) Reading package lists... ---> e34285bd2042 Removing intermediate container 287defbad457 Step 3 : RUN pear channel-discover pear.nrk.io ---> Running in d18922f9b0ad Adding Channel "pear.nrk.io" succeeded Discovery of channel "pear.nrk.io" succeeded ---> 63bd71456d26 Removing intermediate container d18922f9b0ad Step 4 : RUN pear install nrk/Predis ---> Running in 32f931c2af8a downloading Predis-1.1.1.tgz ... Starting to download Predis-1.1.1.tgz (228,512 bytes) .............................................done: 228,512 bytes install ok: channel://pear.nrk.io/Predis-1.1.1 ---> c4f931c29c25 Removing intermediate container 32f931c2af8a Step 5 : ADD guestbook.php /var/www/html/guestbook.php ---> 3d71494f0d16 Removing intermediate container 037173e5d15e Step 6 : ADD controllers.js /var/www/html/controllers.js ---> e55a52cca404 Removing intermediate container 6d7d4a32368f Step 7 : ADD index.html /var/www/html/index.html ---> 5f56d1feb421 Removing intermediate container 9a511c08d6cd Successfully built 5f56d1feb421
If "Successfully built" is displayed, the container image of the Frontend component is built successfully. To view the built image, run the docker images command.
Example command output:
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE frontend latest 5f56d1feb421 26 hours ago 480.3 M
You do not need to manually build a container image for the Redis_master component. The public redis image in the public container registry can be used as a container image of the Redis_master component.
To download the public redis image, perform the following steps:
docker pull redis:3.0
Example command output:
3.0: Pulling from library/redis d34921bc2709: Pulling fs layer 7062b3d97728: Pulling fs layer f5e079305b5b: Pulling fs layer f24ed385d97f: Pulling fs layer 07490d4a265d: Pulling fs layer 69a7e7de57fd: Pull complete 8b4e50bbe5d0: Pull complete 9233ecfa2fa2: Pull complete 279b06473b2b: Pull complete a6e81c8b1686: Pull complete a9f6f37bf5d4: Pull complete 9dfb98084b52: Pull complete 9a6f22fa2498: Pull complete f3c3d957fc95: Pull complete 9d8d146dd82c: Pull complete 7a423638612b: Pull complete f2603106ad09: Pull complete 77904efd4524: Pull complete Digest: sha256:7072fb5c25c253812b73f2890482c9b219108fc4a9fdff5d22a2425dba8cdd25 Status: Downloaded newer image for redis:3.0
If "Status: Downloaded newer image for redis:30" is displayed, the public redis image is downloaded successfully.
Before using the public redis image as the container image of the Redis_slave component, be sure that the master/slave setup has been configured between container images of Redis_master and Redis_slave components.
mkdir Redis_slave
cd Redis_slave
vi run.sh
Content in the run.sh file:
redis-server --slaveof redis-master 6379
In the file, redis-master is the service name of the Redis_master component, and 6379 is the default port number of the Redis components.
vi Dockerfile
Content in the Dockerfile:
FROM redis:3.0 ADD run.sh /run.sh RUN chmod a+x /run.sh CMD /run.sh
docker build -t redisslave .
Example command output:
Sending build context to Docker daemon 3.072 kB Step 1 : FROM redis:3.0 ---> 77904efd4524 Step 2 : ADD run.sh /run.sh ---> 9c7e739083b1 Removing intermediate container a843219d53b7 Step 3 : RUN chmod a+x /run.sh ---> Running in 908dcebd4d5a ---> 38a9b2fe49f6 Removing intermediate container 908dcebd4d5a Step 4 : CMD /run.sh ---> Running in dacb85ccf773 ---> 2922532794cf Removing intermediate container dacb85ccf773 Successfully built 2922532794cf
If "Successfully built" is displayed, the container image of the Redis_slave component is built successfully. To view the built image, run the docker images command.
Example image information:
REPOSITORY TAG IMAGE ID CREATED SIZE redisslave latest 2922532794cf About a minute ago 185.7 MB frontend latest 5f56d1feb421 3 minutes ago 530.1 MB redis 3.0 77904efd4524 2 minutes ago 185.7 MB