/
Pack Hosting Panel

Docker application images

How can I build Docker images for my application as part of my CI/CD pipeline?


Introduction

Automatically building your application as Docker images provides some interesting benefits, like:

  • Application auto scaling with Hipex Hybrid Cloud
  • Dockerized acceptance environments
  • Dockerized development environments

In this article, we'll explain how to upgrade your CI/CD pipeline to build Docker application images.

After following those steps, you will get Dockerized versions of your application, based on PHP and Nginx base images, being built and pushed to a private Docker registry as part of your CI/CD pipeline.

Prerequisites

In order to start using Docker application images, you'll need the following:

  • Dedicated Hipex server or cluster
  • Application created on your server
  • Hipex provided Docker Registry
  • A CI-system that supports building Docker images (Gitlab, Github, Bitbucket etc.)
  • CI/CD configuration based on Hipex Deploy. See the quickstart
  • For code completion: minimum version 2.3 of the hipex/deploy-configuration composer dev dependency
composer.json
    ...
    "require-dev": {
        "hipex/deploy-configuration": "^2.3"
        ...
    }
    ...

Upgrade Hipex Deploy version

In order to build Docker images for your application with Hipex Deploy, the minimum required version is v2.9.0.

Upgrade your CI-configuration to use the new image tag.

  • GitLab: .gitlab-ci.yml
  • Bitbucket: bitbucket-pipelines.yml

Nginx and Redis configuration

Because a Dockerized version of your applications needs to know all platform service configurations up front, it's important to adopt both your Nginx and Redis configurations in the codebase of your application.

Please follow the steps in Nginx configuration to make sure that all necessary Nginx configuration is added to your project.

Do the same for Redis by following the step at Redis configuration.

Configure Docker Registry

Hipex Deploy assumes the existence of the following variables in order to configure the private Docker registry that will hold the application images being built as part of the CI/CD strategy:

VariableDescriptionExample
CI_REGISTRYThe url of the assigned private Docker registry servercore.harbor.hipex.cloud/daas-domain-xxxx
CI_REGISTRY_USERThe username of the user that is configured for the registryrobot$xXxXxXxXxXx
CI_REGISTRY_PASSWORDThe password of the user that is configured for the registry

note If Hipex provided you with a private Docker registry for your application, you can find the above information on your application dashboard in the Pack Hosting Panel.

Depending on your CI-system, find below the instructions to configure the CI variables for your pipeline.

Configure PHP and Nginx base images

To prevent a potential situation from happening where your PHP and Nginx application images change in behaviour due to underlying changes in the base images that Hipex Deploy is using to bake your Docker app images, it's important to pin the tags of those base images to a specific version.

Please visit our public Docker image registry on https://registry.hipex.cloud/ to explore the available images.

Here's an example on how those base images can be specified by using the setDockerBaseImagePhp() and setDockerBaseImageNginx() functions in deploy.php.

deploy.php
    public function __construct()
    {
        parent::__construct('git@bitbucket.org:mycompany/myproject.git');
        $this->setPhpVersion('php72');

        $this->setDockerBaseImagePhp('registry.hipex.cloud/hipex-services/docker-image-php/7.2-fpm:v1.4.3-beta.1');        $this->setDockerBaseImageNginx('registry.hipex.cloud/hipex-services/docker-image-nginx:v1.0.1');
        $this->configureEnvironments();
        $this->configureShared();
        $this->configureBuild();
        $this->configureDeploy();
        $this->configureExcluded();
    }

Configure files and folders shared across releases / servers

To enable your application to run in the Hipex Hybrid Cloud, it's important to indicate what files and folders of your project will be shared across releases and across servers in your cluster.

Hipex Hybrid Cloud is our scalable best of both worlds hosting solution that consists of a combination of your dedicated server or cluster together with auto-scaled compute instances that run your containerized workloads in the Hipex Cloud.

Here's an overview that shows what to use when:

WhatWhen
SharedFileFiles that must be shared on a server across all releases
SharedFolderFolders that must be shared on a server across all releases
ClusterSharedFileFiles that must be shared between all servers across all releases
ClusterSharedFolderFolders that must be shared between all servers across all releases

To give you and indication of what kind of configuration can be used for files and folders, here's an example with configured release/cluster shared files and folders for a Magento 2 project:

deploy.php
class Deploy extends Configuration
{
    private function configureEnvironments() {..}
    private function configureBuild() {..}
    private function configureDeploy() {..}
    private function configureExcluded() {..}
    private function configureRedis() {..}
    private function configureNginx() {..}

    private function configureShared()    {        $this->setSharedFiles([            // Files shared over all releases            new SharedFile('app/etc/env.php'),            new SharedFile('pub/errors/local.xml'),        ]);        $this->setSharedFolders([            // Folders shared over all releases            new SharedFolder('var/log'),            new SharedFolder('var/session'),            // Folders shared over all releases and all servers within cluster            new ClusterSharedFolder('pub/media'),            new ClusterSharedFolder('pub/feeds'),            new ClusterSharedFolder('var/report'),        ]);    }    return new Deploy();
}

Create .hipextemplate files

In order to bake all necessary configuration files into your application images, we need a way to "generate" those files with the appropiate values as part of your CI-pipeline. All PHP based configuration files can be populated by utilizing .hipextemplate files, our solution to this problem.

As part of the hipex-deploy docker:build command, we'll parse every .hipextemplate file for you by replacing all tokens with environment variable values.

After processing the template, we'll remove the .hipextemplate extension. As an example, env.php.hipextemplate would be parsed as .env.php.

The following example shows a fragment of env.php.hipextemplate that contains tokens for configuring a RabbitMQ instance.

The values in this .hipextemplate will be replaced by environment variables declared in application/shared/.hipex-daas.env

app/etc/env.php.hipextemplate
<?php
return [
    ...
    'queue' => [
        'amqp' => [
            'host' => '${RABBITMQ_SERVER}',            'port' => '5672',            'user' => '${RABBITMQ_USER}',            'password' => '${RABBITMQ_PASSWORD}',            'virtualhost' => '/',
            'ssl' => ''
        ]
    ]
    ...
]
application/shared/.hipex-daas.env
RABBITMQ_SERVER=localhost
RABBITMQ_USER=user
RABBITMQ_PASSWORD=password

Convention based environment variables

The following convention based environment variables can be used in .hipextemplate files, and are derived from your configuration in deploy.php.

VariableContextDescriptionExample
REDIS_<identifier>_HOSTSingle Redis instanceRedis hostIf $redisCache = new RedisTcpService('cache', 7000); is configured in deploy.php, env var will be REDIS_CACHE_HOST
REDIS_<identifier>_PORTSingle Redis instanceRedis portIf $redisCache = new RedisTcpService('cache', 7000); is configured in deploy.php, env var will be REDIS_CACHE_PORT
REDIS_<identifier>_SLAVE_HOSTRedis clusterRedis slave hostIf $redisCache = new RedisTcpService('cache', 7000); is configured in deploy.php, env var will be REDIS_CACHE_SLAVE_HOST
REDIS_<identifier>_SLAVE_PORTRedis clusterRedis slave portIf $redisCache = new RedisTcpService('cache', 7000); is configured in deploy.php, env var will be REDIS_CACHE_SLAVE_PORT
REDIS_<identifier>_MASTER_HOSTRedis clusterRedis master hostIf $redisCache->setMasterServer('production1234.hipex.io'); is configured in deploy.php, env var will be REDIS_CACHE_MASTER_HOST
REDIS_<identifier>_MASTER_PORTRedis clusterRedis master portIf $redisCache->setMasterServer('production1234.hipex.io'); is configured in deploy.php env var will be REDIS_CACHE_MASTER_PORT

Add Docker Build step to CI configuration

When deploy.php contains all necessary configuration in order to build both PHP and Nginx Docker images for your application, we can add the hipex-deploy docker:build command to the pipeline in order to automatically build Docker application images as part of your build pipeline, and immediately push them to your projects private Docker registry.

note We'll bake both your PHP and Nginx application images based on a combination of conventions, base images, your own deploy.php configuration and the contents of your project. In the Hipex Cloud, they'll work in harmony and live together in Kubernetes Pods.

Depending on your projects CI-system, here's and example of how you could fit in the hipex-deploy docker:build step as part of your pipeline configuration:

If all steps have been followed correctly, given the above examples every push to master will result in both a new deployment to the main production environment and new Docker application images being built and pushed to the projects private registry.

Now your project is ready to be used and activated for Hipex Hybrid Cloud, as well as all other benefits that come with Dockerized applications!