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
...
"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:
Variable | Description | Example |
---|---|---|
CI_REGISTRY | The url of the assigned private Docker registry server | core.harbor.hipex.cloud/daas-domain-xxxx |
CI_REGISTRY_USER | The username of the user that is configured for the registry | robot$xXxXxXxXxXx |
CI_REGISTRY_PASSWORD | The 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
.
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:
What | When |
---|---|
SharedFile | Files that must be shared on a server across all releases |
SharedFolder | Folders that must be shared on a server across all releases |
ClusterSharedFile | Files that must be shared between all servers across all releases |
ClusterSharedFolder | Folders 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:
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
<?php
return [
...
'queue' => [
'amqp' => [
'host' => '${RABBITMQ_SERVER}', 'port' => '5672', 'user' => '${RABBITMQ_USER}', 'password' => '${RABBITMQ_PASSWORD}', 'virtualhost' => '/',
'ssl' => ''
]
]
...
]
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
.
Variable | Context | Description | Example |
---|---|---|---|
REDIS_<identifier>_HOST | Single Redis instance | Redis host | If $redisCache = new RedisTcpService('cache', 7000); is configured in deploy.php , env var will be REDIS_CACHE_HOST |
REDIS_<identifier>_PORT | Single Redis instance | Redis port | If $redisCache = new RedisTcpService('cache', 7000); is configured in deploy.php , env var will be REDIS_CACHE_PORT |
REDIS_<identifier>_SLAVE_HOST | Redis cluster | Redis slave host | If $redisCache = new RedisTcpService('cache', 7000); is configured in deploy.php , env var will be REDIS_CACHE_SLAVE_HOST |
REDIS_<identifier>_SLAVE_PORT | Redis cluster | Redis slave port | If $redisCache = new RedisTcpService('cache', 7000); is configured in deploy.php , env var will be REDIS_CACHE_SLAVE_PORT |
REDIS_<identifier>_MASTER_HOST | Redis cluster | Redis master host | If $redisCache->setMasterServer('production1234.hipex.io'); is configured in deploy.php , env var will be REDIS_CACHE_MASTER_HOST |
REDIS_<identifier>_MASTER_PORT | Redis cluster | Redis master port | If $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!