SlideShare a Scribd company logo
1 of 12
Download to read offline
Docker Java App with MariaDB – Deployment in Less than
a Minute
Background
Java developers and DevOps professionals have long struggled to automate the deployment of
enterprise Java applications. The complex nature of these applications usually meant that
application dependencies and external integrations had to be re-configured each time an
application was deployed in DEV/TEST environments.
Many solutions advertised the “model once, deploy anywhere” message for application
deployments. In reality, however there were always intricacies that made it very difficult to re-
use an application template across both an on-premise vSphere virtual environment and an AWS
environment, for example.
More recently, however, Docker containers popularized the idea of packaging application
components into Linux Containers that can be deployed exactly the same on any Linux host as
long as Docker Engine is installed.
Unfortunately containerizing enterprise Java applications is still a challenge mostly because
existing application composition frameworks do not address complex dependencies, external
integrations or auto-scaling workflows post-provision. Moreover, the ephemeral design of
containers meant that developers had to spin up new containers and re-create the complex
dependencies & external integrations with every version update.
DCHQ, available in hosted and on-premise versions, addresses all of these challenges and
simplifies the containerization of enterprise Java applications through an advance application
composition framework that extends Docker Compose with cross-image environment variable
bindings, extensible BASH script plug-ins that can be invoked at request time or post-provision,
and application clustering for high availability across multiple hosts or regions with support for
auto scaling.
Once an application is provisioned, a user can monitor the CPU, Memory, & I/O of the running
containers, get notifications & alerts, and perform day-2 operations like Scheduled Backups,
Container Updates using BASH script plug-ins, and Scale In/Out. Moreover, out-of-box
workflows that facilitate Continuous Delivery with Jenkins allow developers to refresh the Java
WAR file of a running application without disrupting the existing dependencies & integrations.
In this blog, we will go over the end-to-end automation of a Java application called Pizza Shop
that is deployed on two different containerized application stacks:
 Nginx (for load balancing), clustered Tomcat and MariaDB (as the database)
 Nginx (for load balancing), clustered Jetty and MariaDB (as the database)
The same Java WAR file will be deployed on two different application servers. DCHQ not only
automates the application deployments – but it also integrates with 12 different clouds to
automate the provisioning and auto-scaling of clusters with software-defined networking. We
will cover:
 Building the application templates that can re-used on any Linux host running anywhere
 Provisioning & auto-scaling the underlying infrastructure on any cloud (with Rackspace
being the example in this blog)
 Deploying the multi-tier Java-based Pizza Shop applications on the Rackspace cluster
 Monitoring the CPU, Memory & I/O of the Running Containers
 Enabling the Continuous Delivery Workflow with Jenkins to update the WAR file of the
running applications when a build is triggered
 Scaling out the Application Server Cluster for Scalability Tests
Building the Application Templates for the Java-based Pizza
Shop Application on Tomcat and Jetty
Once logged in to DCHQ (either the hosted DCHQ.io or on-premise version), a user can
navigate to Manage > Templates and then click on the + button to create a new Docker
Compose template.
We have created four application templates using the official images from Docker Hub for the
same Pizza Shop application – but for four different application servers.
 3-Tier PizzaShop (Nginx - Tomcat - MariaDB)
 3-Tier PizzaShop (Nginx - Jetty - MariaDB)
Across both templates, you will notice that Nginx is invoking a BASH script plug-in to add the
container IP’s of the application servers in the default.conf file dynamically (or at request time).
The application servers (Tomcat and Jetty) are also invoking a BASH script plug-in to deploy the
Pizza Shop Java WAR files from an external URL Tomcat, JBoss and Jetty are invoking the
exact same plug-in – except the WAR file is getting deployed on different directories:
 Tomcat – dir=/usr/local/tomcat/webapps/ROOT.war
 Jetty – dir=/var/lib/jetty/webapps/ROOT.war
You will notice that the cluster_size parameter allows you to specify the number of containers to
launch (with the same application dependencies).
The host parameter allows you to specify the host you would like to use for container
deployments. That way you can ensure high-availability for your application server clusters
across different hosts (or regions) and you can comply with affinity rules to ensure that the
database runs on a separate host for example. Here are the values supported for the host
parameter:
 host1, host2, host3, etc. – selects a host randomly within a data-center (or cluster) for
container deployments
 <IP Address 1, IP Address 2, etc.> -- allows a user to specify the actual IP addresses to
use for container deployments
 <Hostname 1, Hostname 2, etc.> -- allows a user to specify the actual hostnames to use
for container deployments
 Wildcards (e.g. “db-*”, or “app-srv-*”) – to specify the wildcards to use within a
hostname
Additionally, a user can create cross-image environment variable bindings by making a reference
to another image’s environment variable. In this case, we have made several bindings – including
database.url=jdbc:mysql://{{MariaDB|container_ip}}:3306/{{MariaDB|MYSQL_DATABA
SE}} – in which the database container IP is resolved dynamically at request time and is used to
ensure that the application servers can establish a connection with the database.
Here is a list of supported environment variable values:
 {{alphanumeric | 8}} – creates a random 8-character alphanumeric string. This is most
useful for creating random passwords.
 {{<Image Name> | ip}} – allows you to enter the host IP address of a container as a
value for an environment variable. This is most useful for allowing the middleware tier to
establish a connection with the database.
 {{<Image Name> | container_ip}} – allows you to enter the internal IP of a container as
a value for an environment variable. This is most useful for allowing the middleware tier
to establish a secure connection with the database (without exposing the database port).
 {{<Image Name> | port _<Port Number>}} – allows you to enter the Port number of a
container as a value for an environment variable. This is most useful for allowing the
middleware tier to establish a connection with the database. In this case, the port number
specified needs to be the internal port number – i.e. not the external port that is allocated
to the container. For example, {{PostgreSQL | port_5432}} will be translated to the
actual external port that will allow the middleware tier to establish a connection with the
database.
 {{<Image Name> | <Environment Variable Name>}} – allows you to enter the value
an image’s environment variable into another image’s environment variable. The use
cases here are endless – as most multi-tier applications will have cross-image
dependencies.
Provisioning & Auto-Scaling the Underlying Infrastructure
on Any Cloud
Once an application is saved, a user can register a Cloud Provider to automate the provisioning
and auto-scaling of clusters on 12 different cloud end-points including OpenStack, CloudStack,
Amazon Web Services, Rackspace, Microsoft Azure, DigitalOcean, HP Public Cloud, IBM
SoftLayer, Google Compute Engine, and many others.
First, a user can register a Cloud Provider for Rackspace (for example) by navigating to Manage
> Repo & Cloud Provider and then clicking on the + button to select Rackspace. The
Rackspace API Key needs to be provided – which can be retrieved from the Account Settings
section of the Rackspace Cloud Control Panel.
A user can then create a cluster with an auto-scale policy to automatically spin up new Cloud
Servers. This can be done by navigating to Manage > Clusters page and then clicking on the +
button. You can select a capacity-based placement policy and then Weave as the networking
layer in order to facilitate secure, password-protected cross-container communication across
multiple hosts within a cluster. The Auto-Scale Policy in this example sets the maximum
number of VM’s (or Cloud Servers) to 10.
A user can now provision a number of Cloud Servers on the newly created cluster by navigating
to Manage > Bare-Metal Server & VM and then clicking on the + button to select Rackspace.
Once the Cloud Provider is selected, a user can select the region, size and image needed. Ports
can be opened on the new Cloud Servers (e.g. 32000-59000 for Docker, 6783 for Weave, and
5672 for RabbitMQ). A Data Center (or Cluster) is then selected and the number of Cloud
Servers can be specified.
Deploying the Multi-Tier Java-based Pizza Shop Application
on the Rackspace Cluster
Once the Cloud Servers are provisioned, a user can deploy a multi-tier, Docker-based Java
applications on the new Cloud Servers. This can be done by navigating to the Self-Service
Library and then clicking on Customize to request a multi-tier application.
A user can select an Environment Tag (like DEV or QE) and the Rackspace Cluster created
before clicking on Run
Monitoring the CPU, Memory & I/O Utilization of the
Running Containers
Once the application is up and running, our developers monitor the CPU, Memory, & I/O of the
running containers to get alerts when these metrics exceed a pre-defined threshold. This is
especially useful when our developers are performing functional & load testing.
A user can perform historical monitoring analysis and correlate issues to container updates or
build deployments. This can be done by clicking on the Actions menu of the running application
and then on Monitoring. A custom date range can be selected to view CPU, Memory and I/O
historically.
Enabling the Continuous Delivery Workflow with Jenkins to
Update the WAR File of the Running Application when a
Build is Triggered
For developers wishing to follow the “immutable” containers model by rebuilding Docker
images containing the application code and spinning up new containers with every application
update, DCHQ provides an automated build feature that allows developers to automatically
create Docker images from Dockerfiles or private GitHub projects containing Dockerfiles.
However, many developers may wish to update the running application server containers with
the latest Java WAR file instead. For that, DCHQ allows developers to enable a continuous
delivery workflow with Jenkins. This can be done by clicking on the Actions menu of the
running application and then selecting Continuous Delivery. A user can select a Jenkins
instance that has already been registered with DCHQ, the actual Job on Jenkins that will produce
the latest WAR file, and then a BASH script plug-in to grab this build and deploy it on a running
application server. Once this policy is saved, DCHQ will grab the latest WAR file from Jenkins
any time a build is triggered and deploy it on the running application server.
Developers, as a result will always have the latest Java WAR file deployed on their running
containers in DEV/TEST environments.
Scaling out the Tomcat Application Server Cluster
If the running application becomes resource constrained, a user can to scale out the application to
meet the increasing load. Moreover, a user can schedule the scale out during business hours and
the scale in during weekends for example.
To scale out the cluster of Tomcat servers from 2 to 4, a user can click on the Actions menu of
the running application and then select Scale Out. A user can then specify the new size for the
cluster and then click on Run Now.
We then used the BASH plug-in to update Nginx’s default.conf file so that it’s aware of the new
application server added. The BASH script plug-ins can also be scheduled to accommodate use
cases like cleaning up logs or updating configurations at defined frequencies. An application
time-line is available to track every change made to the application for auditing and diagnostics.
To execute a plug-in on a running container, a user can click on the Actions menu of the running
application and then select Plug-ins. A user can then select the load balancer (Nginx) container,
search for the plug-in that needs to be executed, enable container restart using the toggle button.
The
default argument for this plug-in will dynamically resolve all the container IP’s of the running
Tomcat servers and add them as part of the default.conf file.
An application time-line is available to track every change made to the application for auditing
and diagnostics. This can be accessed from the expandable menu at the bottom of the page of a
running application.
Alerts and notifications are available for when containers or hosts are down or when
the CPU & Memory Utilization of either hosts or containers exceed a defined
threshold.
Conclusion
Containerizing enterprise Java applications is still a challenge mostly because existing
application composition frameworks do not address complex dependencies, external integrations
or auto-scaling workflows post-provision. Moreover, the ephemeral design of containers meant
that developers had to spin up new containers and re-create the complex dependencies & external
integrations with every version update.
DCHQ, available in hosted and on-premise versions, addresses all of these challenges and
simplifies the containerization of enterprise Java applications through an advance application
composition framework that facilitates cross-image environment variable bindings, extensible
BASH script plug-ins that can be invoked at request time or post-provision, and application
clustering for high availability across multiple hosts or regions with support for auto scaling.
Sign Up for FREE on http://DCHQ.io
to get access to out-of-box multi-tier Java application templates (including the Movie Store app
on Tomcat, JBoss, GlassFish and Jetty) along with application lifecycle management
functionality like monitoring, container updates, scale in/out and continuous delivery.
Contact Us:
DCHQ Inc.,
845 Market St #450
San Francisco, CA 94103
650-307-4783

More Related Content

What's hot

CUBRID Developer's Course
CUBRID Developer's CourseCUBRID Developer's Course
CUBRID Developer's CourseCUBRID
 
Azure, Cloud Computing & Services
Azure, Cloud Computing & ServicesAzure, Cloud Computing & Services
Azure, Cloud Computing & ServicesAlan Dean
 
Oracle WebLogic Server 12c with Docker
Oracle WebLogic Server 12c with DockerOracle WebLogic Server 12c with Docker
Oracle WebLogic Server 12c with DockerGuatemala User Group
 
Scaling drupal horizontally and in cloud
Scaling drupal horizontally and in cloudScaling drupal horizontally and in cloud
Scaling drupal horizontally and in cloudVladimir Ilic
 
SQL Server Cluster Presentation
SQL Server Cluster PresentationSQL Server Cluster Presentation
SQL Server Cluster Presentationwebhostingguy
 
RACAttack 12c Advanced Lab: Server Pools and Policy-managed databases
RACAttack 12c Advanced Lab: Server Pools and Policy-managed databasesRACAttack 12c Advanced Lab: Server Pools and Policy-managed databases
RACAttack 12c Advanced Lab: Server Pools and Policy-managed databasesLudovico Caldara
 
Elastic beanstalk
Elastic beanstalkElastic beanstalk
Elastic beanstalkParag Patil
 
Windows clustering and quorum basics
Windows clustering and quorum basicsWindows clustering and quorum basics
Windows clustering and quorum basicsHarsh Chawla
 
Sql 2012 always on
Sql 2012 always onSql 2012 always on
Sql 2012 always ondilip nayak
 
Securing your Pulsar Cluster with Vault_Chris Kellogg
Securing your Pulsar Cluster with Vault_Chris KelloggSecuring your Pulsar Cluster with Vault_Chris Kellogg
Securing your Pulsar Cluster with Vault_Chris KelloggStreamNative
 
Session 1 - CloudStack Plugin Structure and Implementation (2013.Q3)
Session 1 - CloudStack Plugin Structure and Implementation (2013.Q3)Session 1 - CloudStack Plugin Structure and Implementation (2013.Q3)
Session 1 - CloudStack Plugin Structure and Implementation (2013.Q3)tcloudcomputing-tw
 
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and moreScaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and moreDropsolid
 

What's hot (17)

CUBRID Developer's Course
CUBRID Developer's CourseCUBRID Developer's Course
CUBRID Developer's Course
 
Azure, Cloud Computing & Services
Azure, Cloud Computing & ServicesAzure, Cloud Computing & Services
Azure, Cloud Computing & Services
 
Oracle WebLogic Server 12c with Docker
Oracle WebLogic Server 12c with DockerOracle WebLogic Server 12c with Docker
Oracle WebLogic Server 12c with Docker
 
Lovely
LovelyLovely
Lovely
 
Apache ActiveMQ
Apache ActiveMQ Apache ActiveMQ
Apache ActiveMQ
 
Failover cluster
Failover clusterFailover cluster
Failover cluster
 
Scaling drupal horizontally and in cloud
Scaling drupal horizontally and in cloudScaling drupal horizontally and in cloud
Scaling drupal horizontally and in cloud
 
SQL Server Cluster Presentation
SQL Server Cluster PresentationSQL Server Cluster Presentation
SQL Server Cluster Presentation
 
RACAttack 12c Advanced Lab: Server Pools and Policy-managed databases
RACAttack 12c Advanced Lab: Server Pools and Policy-managed databasesRACAttack 12c Advanced Lab: Server Pools and Policy-managed databases
RACAttack 12c Advanced Lab: Server Pools and Policy-managed databases
 
Elastic beanstalk
Elastic beanstalkElastic beanstalk
Elastic beanstalk
 
Windows clustering and quorum basics
Windows clustering and quorum basicsWindows clustering and quorum basics
Windows clustering and quorum basics
 
Sql 2012 always on
Sql 2012 always onSql 2012 always on
Sql 2012 always on
 
Liberty management
Liberty managementLiberty management
Liberty management
 
Securing your Pulsar Cluster with Vault_Chris Kellogg
Securing your Pulsar Cluster with Vault_Chris KelloggSecuring your Pulsar Cluster with Vault_Chris Kellogg
Securing your Pulsar Cluster with Vault_Chris Kellogg
 
Session 1 - CloudStack Plugin Structure and Implementation (2013.Q3)
Session 1 - CloudStack Plugin Structure and Implementation (2013.Q3)Session 1 - CloudStack Plugin Structure and Implementation (2013.Q3)
Session 1 - CloudStack Plugin Structure and Implementation (2013.Q3)
 
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and moreScaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
 
AlwaysON Basics
AlwaysON BasicsAlwaysON Basics
AlwaysON Basics
 

Viewers also liked

Big Data and PA
Big Data and PABig Data and PA
Big Data and PATim Tate
 
Entrepreneurship & Storytelling - for Women En Mass 2015
Entrepreneurship & Storytelling -  for Women En Mass 2015Entrepreneurship & Storytelling -  for Women En Mass 2015
Entrepreneurship & Storytelling - for Women En Mass 2015Peggy Yu
 
BunnyCareConfessions3 - Copy
BunnyCareConfessions3 - CopyBunnyCareConfessions3 - Copy
BunnyCareConfessions3 - CopyClay Jackson
 
Living Globally
Living GloballyLiving Globally
Living Globallydevinkeefe
 
CV - July 2015 with nationwide
CV - July 2015 with nationwideCV - July 2015 with nationwide
CV - July 2015 with nationwidedeborah Wells
 
percentage and its applications
percentage and its applications percentage and its applications
percentage and its applications Yukta Mahajan
 
Rebirth and Understanding India - Sabari
Rebirth and Understanding India - SabariRebirth and Understanding India - Sabari
Rebirth and Understanding India - SabariSabarinath Venugopalan
 

Viewers also liked (10)

Big Data and PA
Big Data and PABig Data and PA
Big Data and PA
 
Entrepreneurship & Storytelling - for Women En Mass 2015
Entrepreneurship & Storytelling -  for Women En Mass 2015Entrepreneurship & Storytelling -  for Women En Mass 2015
Entrepreneurship & Storytelling - for Women En Mass 2015
 
Beesearch
BeesearchBeesearch
Beesearch
 
Linked lists
Linked listsLinked lists
Linked lists
 
BunnyCareConfessions3 - Copy
BunnyCareConfessions3 - CopyBunnyCareConfessions3 - Copy
BunnyCareConfessions3 - Copy
 
Living Globally
Living GloballyLiving Globally
Living Globally
 
CV - July 2015 with nationwide
CV - July 2015 with nationwideCV - July 2015 with nationwide
CV - July 2015 with nationwide
 
percentage and its applications
percentage and its applications percentage and its applications
percentage and its applications
 
Newslynx Media Impact Project
Newslynx Media Impact ProjectNewslynx Media Impact Project
Newslynx Media Impact Project
 
Rebirth and Understanding India - Sabari
Rebirth and Understanding India - SabariRebirth and Understanding India - Sabari
Rebirth and Understanding India - Sabari
 

Similar to Docker Java App with MariaDB – Deployment in Less than a Minute

Dockerization of Azure Platform
Dockerization of Azure PlatformDockerization of Azure Platform
Dockerization of Azure Platformnirajrules
 
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdfSchema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdfseo18
 
HPC Cloud Burst Using Docker
HPC Cloud Burst Using DockerHPC Cloud Burst Using Docker
HPC Cloud Burst Using DockerIRJET Journal
 
Getting Started with MariaDB with Docker
Getting Started with MariaDB with DockerGetting Started with MariaDB with Docker
Getting Started with MariaDB with DockerMariaDB plc
 
Java Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App EngineJava Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App EngineIMC Institute
 
Deploying your web application with AWS ElasticBeanstalk
Deploying your web application with AWS ElasticBeanstalkDeploying your web application with AWS ElasticBeanstalk
Deploying your web application with AWS ElasticBeanstalkJulien SIMON
 
Web Component Development Using Servlet & JSP Technologies (EE6) - Chapter 1...
 Web Component Development Using Servlet & JSP Technologies (EE6) - Chapter 1... Web Component Development Using Servlet & JSP Technologies (EE6) - Chapter 1...
Web Component Development Using Servlet & JSP Technologies (EE6) - Chapter 1...WebStackAcademy
 
Meetup 2022 - APIs with Quarkus.pdf
Meetup 2022 - APIs with Quarkus.pdfMeetup 2022 - APIs with Quarkus.pdf
Meetup 2022 - APIs with Quarkus.pdfRed Hat
 
Kubernetes for the PHP developer
Kubernetes for the PHP developerKubernetes for the PHP developer
Kubernetes for the PHP developerPaul Czarkowski
 
Docker dev ops for cd meetup 12-14
Docker dev ops for cd meetup 12-14Docker dev ops for cd meetup 12-14
Docker dev ops for cd meetup 12-14Simon Storm
 
Cloud Foundry for PHP developers
Cloud Foundry for PHP developersCloud Foundry for PHP developers
Cloud Foundry for PHP developersDaniel Krook
 
PHP Buildpacks in the Cloud on Bluemix
PHP Buildpacks in the Cloud on BluemixPHP Buildpacks in the Cloud on Bluemix
PHP Buildpacks in the Cloud on BluemixIBM
 
Docker Application to Scientific Computing
Docker Application to Scientific ComputingDocker Application to Scientific Computing
Docker Application to Scientific ComputingPeter Bryzgalov
 
Deploying windows containers with kubernetes
Deploying windows containers with kubernetesDeploying windows containers with kubernetes
Deploying windows containers with kubernetesBen Hall
 
Cloudjiffy vs Amazon Elastic Beanstalk
Cloudjiffy vs Amazon Elastic BeanstalkCloudjiffy vs Amazon Elastic Beanstalk
Cloudjiffy vs Amazon Elastic BeanstalkSharma Aashish
 
OpenStack with-docker-team-17
OpenStack with-docker-team-17OpenStack with-docker-team-17
OpenStack with-docker-team-17Jaspreet Singh
 
3 Easy Steps to Install Docker PostgreSQL Environment.pdf
3 Easy Steps to Install Docker PostgreSQL Environment.pdf3 Easy Steps to Install Docker PostgreSQL Environment.pdf
3 Easy Steps to Install Docker PostgreSQL Environment.pdfcalfonzodaly
 
OpenNebula Conf 2014 | Cloud Automation for OpenNebula by Kishorekumar Neelam...
OpenNebula Conf 2014 | Cloud Automation for OpenNebula by Kishorekumar Neelam...OpenNebula Conf 2014 | Cloud Automation for OpenNebula by Kishorekumar Neelam...
OpenNebula Conf 2014 | Cloud Automation for OpenNebula by Kishorekumar Neelam...NETWAYS
 

Similar to Docker Java App with MariaDB – Deployment in Less than a Minute (20)

Dockerization of Azure Platform
Dockerization of Azure PlatformDockerization of Azure Platform
Dockerization of Azure Platform
 
Axigen on docker
Axigen on dockerAxigen on docker
Axigen on docker
 
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdfSchema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
Schema-based multi-tenant architecture using Quarkus &amp; Hibernate-ORM.pdf
 
HPC Cloud Burst Using Docker
HPC Cloud Burst Using DockerHPC Cloud Burst Using Docker
HPC Cloud Burst Using Docker
 
Getting Started with MariaDB with Docker
Getting Started with MariaDB with DockerGetting Started with MariaDB with Docker
Getting Started with MariaDB with Docker
 
Java Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App EngineJava Web Programming on Google Cloud Platform [1/3] : Google App Engine
Java Web Programming on Google Cloud Platform [1/3] : Google App Engine
 
Deploying your web application with AWS ElasticBeanstalk
Deploying your web application with AWS ElasticBeanstalkDeploying your web application with AWS ElasticBeanstalk
Deploying your web application with AWS ElasticBeanstalk
 
Web Component Development Using Servlet & JSP Technologies (EE6) - Chapter 1...
 Web Component Development Using Servlet & JSP Technologies (EE6) - Chapter 1... Web Component Development Using Servlet & JSP Technologies (EE6) - Chapter 1...
Web Component Development Using Servlet & JSP Technologies (EE6) - Chapter 1...
 
Meetup 2022 - APIs with Quarkus.pdf
Meetup 2022 - APIs with Quarkus.pdfMeetup 2022 - APIs with Quarkus.pdf
Meetup 2022 - APIs with Quarkus.pdf
 
Kubernetes for the PHP developer
Kubernetes for the PHP developerKubernetes for the PHP developer
Kubernetes for the PHP developer
 
Docker dev ops for cd meetup 12-14
Docker dev ops for cd meetup 12-14Docker dev ops for cd meetup 12-14
Docker dev ops for cd meetup 12-14
 
Google App Engine
Google App EngineGoogle App Engine
Google App Engine
 
Cloud Foundry for PHP developers
Cloud Foundry for PHP developersCloud Foundry for PHP developers
Cloud Foundry for PHP developers
 
PHP Buildpacks in the Cloud on Bluemix
PHP Buildpacks in the Cloud on BluemixPHP Buildpacks in the Cloud on Bluemix
PHP Buildpacks in the Cloud on Bluemix
 
Docker Application to Scientific Computing
Docker Application to Scientific ComputingDocker Application to Scientific Computing
Docker Application to Scientific Computing
 
Deploying windows containers with kubernetes
Deploying windows containers with kubernetesDeploying windows containers with kubernetes
Deploying windows containers with kubernetes
 
Cloudjiffy vs Amazon Elastic Beanstalk
Cloudjiffy vs Amazon Elastic BeanstalkCloudjiffy vs Amazon Elastic Beanstalk
Cloudjiffy vs Amazon Elastic Beanstalk
 
OpenStack with-docker-team-17
OpenStack with-docker-team-17OpenStack with-docker-team-17
OpenStack with-docker-team-17
 
3 Easy Steps to Install Docker PostgreSQL Environment.pdf
3 Easy Steps to Install Docker PostgreSQL Environment.pdf3 Easy Steps to Install Docker PostgreSQL Environment.pdf
3 Easy Steps to Install Docker PostgreSQL Environment.pdf
 
OpenNebula Conf 2014 | Cloud Automation for OpenNebula by Kishorekumar Neelam...
OpenNebula Conf 2014 | Cloud Automation for OpenNebula by Kishorekumar Neelam...OpenNebula Conf 2014 | Cloud Automation for OpenNebula by Kishorekumar Neelam...
OpenNebula Conf 2014 | Cloud Automation for OpenNebula by Kishorekumar Neelam...
 

Recently uploaded

How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfdanishmna97
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governanceWSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightSafe Software
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringWSO2
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data SciencePaolo Missier
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAnitaRaj43
 
Quantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingQuantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingWSO2
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformWSO2
 

Recently uploaded (20)

How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governance
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software Engineering
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
Quantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingQuantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation Computing
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
 

Docker Java App with MariaDB – Deployment in Less than a Minute

  • 1. Docker Java App with MariaDB – Deployment in Less than a Minute Background Java developers and DevOps professionals have long struggled to automate the deployment of enterprise Java applications. The complex nature of these applications usually meant that application dependencies and external integrations had to be re-configured each time an application was deployed in DEV/TEST environments. Many solutions advertised the “model once, deploy anywhere” message for application deployments. In reality, however there were always intricacies that made it very difficult to re- use an application template across both an on-premise vSphere virtual environment and an AWS environment, for example. More recently, however, Docker containers popularized the idea of packaging application components into Linux Containers that can be deployed exactly the same on any Linux host as long as Docker Engine is installed. Unfortunately containerizing enterprise Java applications is still a challenge mostly because existing application composition frameworks do not address complex dependencies, external
  • 2. integrations or auto-scaling workflows post-provision. Moreover, the ephemeral design of containers meant that developers had to spin up new containers and re-create the complex dependencies & external integrations with every version update. DCHQ, available in hosted and on-premise versions, addresses all of these challenges and simplifies the containerization of enterprise Java applications through an advance application composition framework that extends Docker Compose with cross-image environment variable bindings, extensible BASH script plug-ins that can be invoked at request time or post-provision, and application clustering for high availability across multiple hosts or regions with support for auto scaling. Once an application is provisioned, a user can monitor the CPU, Memory, & I/O of the running containers, get notifications & alerts, and perform day-2 operations like Scheduled Backups, Container Updates using BASH script plug-ins, and Scale In/Out. Moreover, out-of-box workflows that facilitate Continuous Delivery with Jenkins allow developers to refresh the Java WAR file of a running application without disrupting the existing dependencies & integrations. In this blog, we will go over the end-to-end automation of a Java application called Pizza Shop that is deployed on two different containerized application stacks:  Nginx (for load balancing), clustered Tomcat and MariaDB (as the database)  Nginx (for load balancing), clustered Jetty and MariaDB (as the database) The same Java WAR file will be deployed on two different application servers. DCHQ not only automates the application deployments – but it also integrates with 12 different clouds to automate the provisioning and auto-scaling of clusters with software-defined networking. We will cover:  Building the application templates that can re-used on any Linux host running anywhere  Provisioning & auto-scaling the underlying infrastructure on any cloud (with Rackspace being the example in this blog)  Deploying the multi-tier Java-based Pizza Shop applications on the Rackspace cluster  Monitoring the CPU, Memory & I/O of the Running Containers  Enabling the Continuous Delivery Workflow with Jenkins to update the WAR file of the running applications when a build is triggered  Scaling out the Application Server Cluster for Scalability Tests Building the Application Templates for the Java-based Pizza Shop Application on Tomcat and Jetty Once logged in to DCHQ (either the hosted DCHQ.io or on-premise version), a user can navigate to Manage > Templates and then click on the + button to create a new Docker Compose template.
  • 3. We have created four application templates using the official images from Docker Hub for the same Pizza Shop application – but for four different application servers.  3-Tier PizzaShop (Nginx - Tomcat - MariaDB)  3-Tier PizzaShop (Nginx - Jetty - MariaDB) Across both templates, you will notice that Nginx is invoking a BASH script plug-in to add the container IP’s of the application servers in the default.conf file dynamically (or at request time). The application servers (Tomcat and Jetty) are also invoking a BASH script plug-in to deploy the Pizza Shop Java WAR files from an external URL Tomcat, JBoss and Jetty are invoking the exact same plug-in – except the WAR file is getting deployed on different directories:  Tomcat – dir=/usr/local/tomcat/webapps/ROOT.war  Jetty – dir=/var/lib/jetty/webapps/ROOT.war You will notice that the cluster_size parameter allows you to specify the number of containers to launch (with the same application dependencies). The host parameter allows you to specify the host you would like to use for container deployments. That way you can ensure high-availability for your application server clusters across different hosts (or regions) and you can comply with affinity rules to ensure that the database runs on a separate host for example. Here are the values supported for the host parameter:  host1, host2, host3, etc. – selects a host randomly within a data-center (or cluster) for container deployments  <IP Address 1, IP Address 2, etc.> -- allows a user to specify the actual IP addresses to use for container deployments  <Hostname 1, Hostname 2, etc.> -- allows a user to specify the actual hostnames to use for container deployments  Wildcards (e.g. “db-*”, or “app-srv-*”) – to specify the wildcards to use within a hostname Additionally, a user can create cross-image environment variable bindings by making a reference to another image’s environment variable. In this case, we have made several bindings – including database.url=jdbc:mysql://{{MariaDB|container_ip}}:3306/{{MariaDB|MYSQL_DATABA SE}} – in which the database container IP is resolved dynamically at request time and is used to ensure that the application servers can establish a connection with the database. Here is a list of supported environment variable values:
  • 4.  {{alphanumeric | 8}} – creates a random 8-character alphanumeric string. This is most useful for creating random passwords.  {{<Image Name> | ip}} – allows you to enter the host IP address of a container as a value for an environment variable. This is most useful for allowing the middleware tier to establish a connection with the database.  {{<Image Name> | container_ip}} – allows you to enter the internal IP of a container as a value for an environment variable. This is most useful for allowing the middleware tier to establish a secure connection with the database (without exposing the database port).  {{<Image Name> | port _<Port Number>}} – allows you to enter the Port number of a container as a value for an environment variable. This is most useful for allowing the middleware tier to establish a connection with the database. In this case, the port number specified needs to be the internal port number – i.e. not the external port that is allocated to the container. For example, {{PostgreSQL | port_5432}} will be translated to the actual external port that will allow the middleware tier to establish a connection with the database.  {{<Image Name> | <Environment Variable Name>}} – allows you to enter the value an image’s environment variable into another image’s environment variable. The use cases here are endless – as most multi-tier applications will have cross-image dependencies.
  • 5.
  • 6. Provisioning & Auto-Scaling the Underlying Infrastructure on Any Cloud Once an application is saved, a user can register a Cloud Provider to automate the provisioning and auto-scaling of clusters on 12 different cloud end-points including OpenStack, CloudStack, Amazon Web Services, Rackspace, Microsoft Azure, DigitalOcean, HP Public Cloud, IBM SoftLayer, Google Compute Engine, and many others. First, a user can register a Cloud Provider for Rackspace (for example) by navigating to Manage > Repo & Cloud Provider and then clicking on the + button to select Rackspace. The
  • 7. Rackspace API Key needs to be provided – which can be retrieved from the Account Settings section of the Rackspace Cloud Control Panel. A user can then create a cluster with an auto-scale policy to automatically spin up new Cloud Servers. This can be done by navigating to Manage > Clusters page and then clicking on the + button. You can select a capacity-based placement policy and then Weave as the networking layer in order to facilitate secure, password-protected cross-container communication across multiple hosts within a cluster. The Auto-Scale Policy in this example sets the maximum number of VM’s (or Cloud Servers) to 10.
  • 8. A user can now provision a number of Cloud Servers on the newly created cluster by navigating to Manage > Bare-Metal Server & VM and then clicking on the + button to select Rackspace. Once the Cloud Provider is selected, a user can select the region, size and image needed. Ports can be opened on the new Cloud Servers (e.g. 32000-59000 for Docker, 6783 for Weave, and 5672 for RabbitMQ). A Data Center (or Cluster) is then selected and the number of Cloud Servers can be specified. Deploying the Multi-Tier Java-based Pizza Shop Application on the Rackspace Cluster Once the Cloud Servers are provisioned, a user can deploy a multi-tier, Docker-based Java applications on the new Cloud Servers. This can be done by navigating to the Self-Service Library and then clicking on Customize to request a multi-tier application. A user can select an Environment Tag (like DEV or QE) and the Rackspace Cluster created before clicking on Run
  • 9. Monitoring the CPU, Memory & I/O Utilization of the Running Containers Once the application is up and running, our developers monitor the CPU, Memory, & I/O of the running containers to get alerts when these metrics exceed a pre-defined threshold. This is especially useful when our developers are performing functional & load testing. A user can perform historical monitoring analysis and correlate issues to container updates or build deployments. This can be done by clicking on the Actions menu of the running application and then on Monitoring. A custom date range can be selected to view CPU, Memory and I/O historically. Enabling the Continuous Delivery Workflow with Jenkins to Update the WAR File of the Running Application when a Build is Triggered For developers wishing to follow the “immutable” containers model by rebuilding Docker images containing the application code and spinning up new containers with every application update, DCHQ provides an automated build feature that allows developers to automatically create Docker images from Dockerfiles or private GitHub projects containing Dockerfiles.
  • 10. However, many developers may wish to update the running application server containers with the latest Java WAR file instead. For that, DCHQ allows developers to enable a continuous delivery workflow with Jenkins. This can be done by clicking on the Actions menu of the running application and then selecting Continuous Delivery. A user can select a Jenkins instance that has already been registered with DCHQ, the actual Job on Jenkins that will produce the latest WAR file, and then a BASH script plug-in to grab this build and deploy it on a running application server. Once this policy is saved, DCHQ will grab the latest WAR file from Jenkins any time a build is triggered and deploy it on the running application server. Developers, as a result will always have the latest Java WAR file deployed on their running containers in DEV/TEST environments. Scaling out the Tomcat Application Server Cluster If the running application becomes resource constrained, a user can to scale out the application to meet the increasing load. Moreover, a user can schedule the scale out during business hours and the scale in during weekends for example. To scale out the cluster of Tomcat servers from 2 to 4, a user can click on the Actions menu of the running application and then select Scale Out. A user can then specify the new size for the cluster and then click on Run Now.
  • 11. We then used the BASH plug-in to update Nginx’s default.conf file so that it’s aware of the new application server added. The BASH script plug-ins can also be scheduled to accommodate use cases like cleaning up logs or updating configurations at defined frequencies. An application time-line is available to track every change made to the application for auditing and diagnostics. To execute a plug-in on a running container, a user can click on the Actions menu of the running application and then select Plug-ins. A user can then select the load balancer (Nginx) container, search for the plug-in that needs to be executed, enable container restart using the toggle button. The default argument for this plug-in will dynamically resolve all the container IP’s of the running Tomcat servers and add them as part of the default.conf file. An application time-line is available to track every change made to the application for auditing and diagnostics. This can be accessed from the expandable menu at the bottom of the page of a running application.
  • 12. Alerts and notifications are available for when containers or hosts are down or when the CPU & Memory Utilization of either hosts or containers exceed a defined threshold. Conclusion Containerizing enterprise Java applications is still a challenge mostly because existing application composition frameworks do not address complex dependencies, external integrations or auto-scaling workflows post-provision. Moreover, the ephemeral design of containers meant that developers had to spin up new containers and re-create the complex dependencies & external integrations with every version update. DCHQ, available in hosted and on-premise versions, addresses all of these challenges and simplifies the containerization of enterprise Java applications through an advance application composition framework that facilitates cross-image environment variable bindings, extensible BASH script plug-ins that can be invoked at request time or post-provision, and application clustering for high availability across multiple hosts or regions with support for auto scaling. Sign Up for FREE on http://DCHQ.io to get access to out-of-box multi-tier Java application templates (including the Movie Store app on Tomcat, JBoss, GlassFish and Jetty) along with application lifecycle management functionality like monitoring, container updates, scale in/out and continuous delivery. Contact Us: DCHQ Inc., 845 Market St #450 San Francisco, CA 94103 650-307-4783