Using ZFE with Docker

The Docker open platform has excellent documentation which you should read and understand.

Why Docker?

Docker is a container-based platform that enables you to develop, deploy, and run applications within a container. Your application, plus any dependencies your application requires, such as binaries and libraries, and configuration information are held within the container. You can deploy multiple containers, all of which run in Docker and on top of the operating system.

Using Docker you can scale your applications vertically, meaning multiple instances of the session server can exist on one server and each instance will perform exactly as it did when you created and tested it.

What are the benefits?

Containerization delivers multiple benefits:

  • Performance

    Virtual machines are an alternative to containers, however containers do not contain an operating system (unlike VMs). This means containers are faster to create, quicker to start, and have a much smaller footprint.

  • Agility

    Because containers are more portable and have better performance, you can take advantage of more agile and responsive development practices.

  • Isolation

    Docker containers are independent of one another. This is important because a Docker container containing one application, including the required versions of any supporting software, will not interfere with another container of the same application which requires different supporting software. You can have total confidence that at each stage of development and deployment the image you create will perform exactly as expected.

  • Scalability

    Creating new containers is simple and quick. The Docker documentation has information on how to manage multiple containers.

Terminology

There are basic terms you need to be familiar with when working with Docker. For more information see the Docker Documentation site.

  • Container
  • A run-time instance of an image. A container is usually completely isolated from the host environment, only able to access host files and ports if it has been configured to do so. To run an image in a container you use the docker run command.
  • Docker Hub
  • A cloud-based community resource for working with Docker. Docker Hub is typically used for hosting images, but can be used for user authentication and automating the building of images. Anyone can publish images to Docker Hub.
  • Docker Compose
  • Compose is a tool that uses YAML files to configure your application services and then define and run multi-container Docker applications. To learn more about Compose visit the Docker Compose documentation.
  • Dockerfile
  • A text document containing the commands to build a Docker image. You can specify complex commands (such as specifying an existing image to use as a base) or simple ones (such as copying files from one directory to another). To build an image from a Dockerfile you use the docker build command.
  • Image
  • A standalone, executable package that runs in a container. A Docker image is a binary that includes everything needed to run a single Docker container, including its metadata. You can build your own images (using a Dockerfile) or use images that have been built by others and then made available in a registry (such as Docker Hub). To build an image from a Dockerfile you use the docker build command. To run an image in a container you use the docker run command.

Getting Started with Docker and ZFE

The ZFE install package contains an initial Dockerfile and accompanying application jar file to get you started using the session server in containers.

There are examples located in the docker/samples folder. See Docker Compose Examples for instructions.

There are four steps involved in creating the base image:

  1. Install Docker and Docker Compose. Follow the instructions on the Docker web site.

  2. Extract the download package file and locate Dockerfile and zfe.jar in the Docker folder

  3. Build the Docker image

  4. Run the Docker image

Build the session server Docker image

Assuming you have followed steps one and two; installed Docker and Docker Compose and extracted and located Dockerfile and zfe.jar, the next step is to build the base Docker image of the session server.

  1. Run this command from the folder containing the Dockerfile:

    docker build -t zfe:<version> .

    Replace <version> with the version of the session server. If a version is not available, the default tag (-t) is latest.

  2. Verify that the image was successfully created. Run:

    docker images

    The output should contain information about the image you just built.

Run the image

Before you can run the session server image in a Docker container, you must set some environment variables.

Variable

Description

SERVER_SSL_KEYSTORE

The path to the keystore file

SERVER_SSL_TRUSTSTORE

The path to the trust store file. It is required to import the MSS certificate into the trust store to communicate securely with MSS.

MANAGEMENT_SERVER_URL

The address of the MSS server

You have two options that you can use:

  • Use a bind mount

  • Extend an existing Docker image

Using a bind mount

A bind mount mounts a file or directory on the host machine into a container. The file or directory is referenced by its full or relative path on the host machine.

This bind mounts the keystore and truststore files on the host to the Docker container.

docker run --env SERVER_SSL_KEYSTORE=./etc/servletcontainer.bcfks \
--env SERVER_SSL_TRUSTSTORE=./etc/trustcerts.bcfks \
--env MANAGEMENT_SERVER_URL=https://localhost/mss \
--volume ~/certs/demo_keystore.bcfks:/opt/zfe/etc/servletcontainer.bcfks \
--volume ~/certs/demo_truststore.bcfks:/opt/zfe/etc/trustcerts.bcfks \
--expose 7070 \
--expose 7443 \
--publish 7070:7070 \
--publish 7443:7443 \
zfe

Extending an existing Docker image

With this method you create a new Dockerfile to copy the files you need into the Docker image.

First, create a Dockerfile that will extend from the zfe Dockerfile FROM zfe:

COPY ./certs/demo_keystore.bcfks /opt/zfe/etc/servletcontainer.bcfks
COPY ./certs/demo_truststore.bcfks /opt/zfe/etc/trustcerts.bcfks

Next, build the extended Dockerfile, naming it demo.

docker build -t demo

Finally, run the demo image.

docker run --env SERVER_SSL_KEYSTORE=./etc/servletcontainer.bcfks \
--env SERVER_SSL_TRUSTSTORE=./etc/trustcerts.bcfks \
--env MANAGEMENT_SERVER_URL=https://localhost/mss \
--expose 7070 \
--expose 7443 \
--publish 7070:7070 \
--publish 7443:7443 \
demo

Examples

The examples, located in the docker/samples folder, walk you through four scenarios using Docker Compose. Compose is a tool that uses a YAML file to configure and run your applications with a single command.

Review the Docker documentation on Docker Compose before proceeding.

Prerequisites

To run the examples, you need:

The examples include:

  • A basic example providing a demo keystore and truststore files in which you can import a MSS server certificate.

  • An hybrid example which assumes a local ZFE installation and mounts existing, on disk, keystore and truststore files to the Docker container.

  • An extension example showing how to update, modify, and customize the ZFE web client

  • A load balancer example illustrating how to balance between linked containers.

Basic

This basic example illustrates how to run the session server Docker image in Docker Compose. In this example you will import the MSS server certificate to enable secure communications with MSS.

By default, the session server listens on port 7070 (HTTP) and 7443 (HTTPS). If it is necessary to modify the ports, for example to 8443 and 8080, update the ports in the docker-compose.yml file:

ports:
    - 8443:7443
    - 8080:7070
  • To start the session server service:

    docker-compose up
  • To run the service in a daemon:

    docker-compose up -d
  • To look at running containers:

    docker ps

Hybrid

In this example a local installation of ZFE, with existing keystore and truststore files on disk is present. These files will be mounted (copied) to the Docker container.

  • To update the ports, modify ZFE_PORT, ZFE_HTTP_PORT in the.env file.

  • To update the MSS server address, modify MSS_ADDRESS in the.env file.

  • To start the session server service, copy .env and docker-compose.yml to sessionserver/microservices/zfe/, and run: docker-compose up -d.

Extensions

Using extensions and your own HTML, CSS, or JavaScript, you can update, modify, and customize the presentation of the web client from within the browser. See Extending the ZFE Web Client for more information.

This example sets SPRING_PROFILES_ACTIVE to extensions-enabled and maps the location of the extensions in docker-compose.yml.

To start the session server service:

docker-compose up -d

You could also choose to extend the base zfe Docker image and copy the extension files into the Docker container:

  1. Create the Dockerfile that extends from the zfe Dockerfile.

    FROM zfe
    
    COPY ./certs/servletcontainer.bcfks /opt/zfe/etc/servletcontainer.bcfks
    COPY ./certs/trustcerts.bcfks /opt/zfe/etc/trustcerts.bcfks
    COPY ./extensions /opt/zfe/extensions/
  2. Build the extended Dockerfile and name it extensions.

    docker build -t extensions
  3. Update docker-compose.yml to use the new extensions image

    version: '3'
    services:
    
      zfe:
        image: extensions
        environment:
          - LOGGING_FILE=./logs/zfe.log
          - LOGGING_FILE_MAXSIZE=10MB
          - LOGGING_FILE_MAXHISTORY=10
          - SERVER_SSL_KEYSTORE=./etc/servletcontainer.bcfks
          - SERVER_SSL_TRUSTSTORE=./etc/trustcerts.bcfks
          - MANAGEMENT_SERVER_URL=https://${MSS_ADDRESS}/mss
          - METERING_ENABLED=false
          - METERING_HOST_REQUIRED=false
          - METERING_SERVER_URL=${MSS_ADDRESS}|https|meter
          - ID_MANAGER_SERVER_URL=https://${MSS_ADDRESS}/tidm
          - SPRING_PROFILES_ACTIVE=extensions-enabled
        ports:
          - ${ZFE_PORT}:7443
          - ${ZFE_HTTP_PORT}:7070
        expose:
          - 7443
          - 7070

Load Balance

HAProxy is a load balancer. Learn more about HAProxy on their web site.

This example, an haproxy service is included in the docker-compose.yml file. The example uses an HAProxy image to balance between linked containers. This example uses SSL Bridging to link the containers.

To provide secure communication between the clients and the load balancer, you must update the LOAD_BALANCER_CERT property in the.env file with the location of the load balancer certificate.

To help you test, you can generate a self-signed certificate:

  1. Generate a unique private key (KEY):

    sudo openssl genrsa -out mydomain.key 2048
  2. Generate a Certificate Signing Request (CSR):

    sudo openssl req -new -key mydomain.key -out mydomain.csr
  3. Create a Self-Signed Certificate (CRT):

    openssl x509 -req -days 365 -in mydomain.csr -signkey mydomain.key -out mydomain.crt
  4. Append KEY and CERT to loadbalancer.pem:

    sudo cat mydomain.key mydomain.crt > ./certs/loadbalancer.pem

To start the session server and haproxy services:

docker-compose up -d

-or-

docker-compose up --scale zfe=n -d

Where n is the number of session server instances.

You can change the number of session server instances after the services start:

docker-compose scale zfe=n