• Cloud Container Engine

cce
  1. Help Center
  2. Cloud Container Engine
  3. User Guide
  4. Getting Started
  5. Building Container Images

Building Container Images

This section uses the Guestbook application as an example to explain how to build container images in the Linux environment.

NOTE:
  • The procedure for building container images is similar across all operating systems.
  • It is recommended that the same operating system be used to build and upload container images.

Background

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.

Prerequisites

  • Internet connectivity to Docker Hub of Docker, Inc. is available.
  • Docker 1.10.0 or a later version has been installed on the virtual or physical machine that you use to build container images.

    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/.

Building a Container Image of the Frontend Component

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          
  1. Log in to your Docker client as the root user or any other user who is authorized to perform Docker operations.
  2. Run the following commands to create the directories where the Frontend component files will be stored:

    mkdir guestbook

    cd guestbook

    mkdir frontend

    cd frontend

  3. Run the following command to create the Guestbook script guestbook.php:

    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.

  4. Run the following command to create the Guestbook script controllers.js:

    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(",");
                });
    });

  5. Run the following command to create the index.html file:

    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>

  6. Run the following command to edit the Dockerfile:

    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
    • The FROM instruction indicates that the container image of the Frontend component is based on the php:5-apache image.
    • The RUN instruction indicates that the apt-get command is used to update the software package list and install Predis.
    • The ADD instruction indicates that the local code file is added to the container image of the Frontend component.

  7. Run the following command to build a container image of the Frontend component in the frontend directory:

    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

Building a Container Image of the Redis_master Component

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:

  1. Run the following command to download the public redis image:

    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.

Building a Container Image of the Redis_slave Component

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.

  1. Run the following commands to create the Redis-slave directory in the guestbook directory created in "Building a Container Image of the Frontend Component":

    mkdir Redis_slave

    cd Redis_slave

  2. Run the following command to create the run.sh file:

    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.

  3. Run the following command to create the Dockerfile:

    vi Dockerfile

    Content in the Dockerfile:

    FROM redis:3.0
    ADD run.sh /run.sh
    RUN chmod a+x /run.sh
    CMD /run.sh
    • The FROM instruction indicates that the container image of the Redis_slave component is based on the public redis image.
    • The ADD instruction indicates that the local run.sh script is added to the container image of the Redis_slave component.
    • The RUN instruction indicates that all users are authorized to run the run.sh file.
    • The CMD instruction indicates that the run.sh file is automatically run when a container is up.

  4. Run the following command to build a container image of the Redis_slave component:

    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