Another brick in the SIGHUP Cloud-Native Stack: Introducing the Certified Container Images (CCI)

SIGHUP is happy to introduce Certified Container Images (CCI): a secured and supported catalog of cloud native docker images to run your containerised workloads with confidence by SIGHUP

Another brick in the SIGHUP Cloud-Native Stack: Introducing the Certified Container Images (CCI)

We would like to introduce you Certified Container Images (CCI) as a containerised catalog of base docker images which are both supported and secured. We currently offer images for:

  • Popular runtimes - such as JVM-based distributions, nodejs, python, PHP, etc..
  • Application frameworks (Open Liberty, etc..)
  • Web servers (Apache, Nginx, HAProxy, Tomcat, etc..)
  • Build tools (Gradle, maven, composer, npm, etc..)

With CCI, we aim to provide ready to use, hassle-free, fully secured container images, with native Prometheus integration (thanks to the embedded cloud-native exporters), so that you and your team don't have to worry about maintaining container base images, exporting standard metrics, security vulnerabilities, and maintenance in general.

You can hand over CCI certified images to your developers, with confidence.

With CCI, we are adding another brick in our battle-tested and production-grade ecosystem to ease Kubernetes and Container-based workloads adoption. CCI will be available to all our community and customers, as an add-on to our existing SIGHUP Fury Subscription.

Start using them right away, simply apply using this form. We are opening the first 100 spots to get early access to the service. Some of the perks of applying today:

  • Stop worrying about base container images. Simply hand them over to your team.
  • Discounted Price when service will go GA.
  • Ask for new features relevant to you.

Starting Off - some background.

We should start off saying that Kubernetes is hard. It's a difficult technology, with plenty of challenges that you and your team will have to sort for a correct adoption.

One of the main challenges is the correct management of base application images used by developers. Community images are insecure by default, yet they are very often put into production with little-to-no security testing.

We have seen this happening almost every time because organizations failed at maintaining their own set of base images, hardened according to precise specs.

This is where Certified Container Images by SIGHUP comes into play.

Why CCI is important why you should care

CCI is a project which started as a product request from several of our enterprise partners.

What they wanted was pretty straight forward:

For their architecture and development teams, a catalog of container images that were both supported and secured.

Images they could hand over to their teams, with the confidence that security and automated compliance tests were in place when hardening the images. They also explicitly required these images to embed, as much as possible, native integration to our KFD Monitoring Module (which unsurprisingly is a pre-configured and secured Prometheus deployment), to expose out of the box, runtime and application metrics.

BTW, Certified What?

One fair question you might have is: what does "certified" means anyway in this context? Why "certified" and by whom?

Fair enough. Let us explain.

Certified = Supported + Secured + Continuously updated

  1. Supported: CCI is basically a Registry-as-a-service where you can trust the quality of the images you are pulling. In order to offer a viable service, we have to cover the engineering cost of maintaining our catalog, this is why CCI is going to be a paid service (apply to have more info about the cost, if you are curious). Being such, all images will come with SLA-driven support. Found a bug? No problem, open an issue and our engineering team will provide feedback and merge a fix. Need a new image, for something not currently supported? Let us know, we'll add it to our catalog. Having troubles with your application? Ask one of our engineers to debug the problem and have you back up&running in no time.
  2. Secured: Our entire catalog is tested against CVEs public lists on a daily bases. Critical fixes are implemented daily, and you can run our images with no-brain confidence that your applications are secured. Every image is shipped with both a security and a compatibility report so that you and your security teams can have a clear picture of the status for all your container dependencies.
  3. Continuously update: We haven't just worked hard to create our images out of the best of breed available from both the community and security research, we have also fully automated the update process of all our catalog so that you are sure, on a daily bases, to run the last and best version of your container images.

Building CCI - The Basics, what we cover and how it works

Photo by Alexas Fotos from Pexels

What we developed are all the mechanisms to build, certify, and sign container images. We didn't stop working there; we also automated day two operations to apply security patches and improvements to all supported container images.

As mentioned, another top-requested feature is the zero-touch Prometheus integration. We know how to set up these exporters on different runtimes (Java, PHP, nodejs, Python, etc.....). So you don't have to worry about learning how to set them up.

Build, certify, sign, repeat - here is how it works in detail

Photo by Startup Stock Photos from Pexels

We have a bunch of container image definitions (aka Dockerfiles). During the process, an image is built, scanned, linted, tested against specific tests for each image, and finally signed.

All artifacts generated are processed to generate a daily detailed report.

Here you can preview what a report looks like:

Report, first part

... and the vulnerabilities status:

Report, last part

Day two operations

Photo by Scott Webb from Pexels

Vulnerabilities appear every day along with software updates. So the journey of building and maintaining a set of production-grade container images becomes a painful task for developers. Furthermore, we know not all companies can dedicate such an amount of time.

As an example, in the report screenshot pasted before there are 2 important (high severity) vulnerabilities in the libpcre3 and perl-base SO packages.

In the perl-base specific case, it was fixed applying the latest release of perl-base=5.30.3-4 (CVE-2020-10878  only applies to perl-base versions under 5.30.3).

As we are running vulnerability scanners every day, if a new vulnerability appears on any SIGHUP container image, we receive an internal alert.

The example above was a notification triggered on the 19th June 2020 about a new vulnerability in the libpcre package.

Once we receive a notification like this, the team starts an internal process to fix it as soon as possible and keep it tracked.

Prometheus exporter

Some of the most used runtimes across enterprises can be configured to expose internal metrics using Prometheus exporters.

Java can expose JVM metrics if you configure it. We include and configure it out of the box on SIGHUP java-based images.

Getting started - A real world example

Java Spring Boot and Maven

Here you can find an example repository with a java application using the Spring Boot framework and Maven to build a fat jar using SIGHUP CCI.

# Clone the repo
$ git clone
# Move to the local copy
$ cd certified-images-java-getting-started
# Preload the images we are going to use. Not required as docker build will do it.
$ docker pull
$ docker pull

Now we are ready to build this java application. To build it you don't need to have any JDK or Maven version installed. Everything is managed in its Dockerfile. Let's build it:

# Build the application
$ docker build -t spring-boot-maven:local .
# It can take up to 10 minutes

As it can take up to 10 minutes, let's review the Dockerfile.

FROM as builder

# Prepare directories
RUN mkdir /app

# Copy the application
COPY pom.xml /app/pom.xml
COPY src /app/src

# Compile Java application
RUN mvn clean package


# Copy compiled app into /app directory
COPY --from=builder /app/target/demo-0.0.1-SNAPSHOT.jar /app/demo-0.0.1-SNAPSHOT.jar

# The app exposes 8080 port

As you can see, this definition used a nice feature from docker: multi-stage builds, which uses two different containers to build and run the application. This way you don't need to run your application with a heavy java container image along with Maven.

Once the container is built:

$ docker run --name demo -d -p 8080:8080 -p 30000:30000 spring-boot-maven:local
$ docker logs demo
exec java -javaagent:/opt/SIGHUP/java/14/entrypoint/jmx_prometheus_javaagent.jar=30000:/opt/SIGHUP/java/14/configuration/jmx_exporter.yaml -XX:+ExitOnOutOfMemoryError -cp . -jar /app/demo-0.0.1-SNAPSHOT.jar
 _____  _____  _____  _   _  _   _ ______ 
/  ___||_   _||  __ \| | | || | | || ___ \
\ `--.   | |  | |  \/| |_| || | | || |_/ /
 `--. \  | |  | | __ |  _  || | | ||  __/ 
/\__/ / _| |_ | |_\ \| | | || |_| || |    
\____/  \___/  \____/\_| |_/ \___/ \_|    
2020-06-03 15:03:34.376  INFO 7 --- [           main] io.sighup.demo.DemoApplication           : Starting DemoApplication v0.0.1-SNAPSHOT on d52b75b5d449 with PID 7 (/app/demo-0.0.1-SNAPSHOT.jar started by root in /app)
2020-06-03 15:03:34.379  INFO 7 --- [           main] io.sighup.demo.DemoApplication           : No active profile set, falling back to default profiles: default
2020-06-03 15:03:35.857  INFO 7 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-06-03 15:03:35.869  INFO 7 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-06-03 15:03:35.870  INFO 7 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.35]
2020-06-03 15:03:35.957  INFO 7 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-06-03 15:03:35.957  INFO 7 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1521 ms
2020-06-03 15:03:36.295  INFO 7 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-06-03 15:03:36.792  INFO 7 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-06-03 15:03:36.815  INFO 7 --- [           main] io.sighup.demo.DemoApplication           : Started DemoApplication in 3.121 seconds (JVM running for 3.9)

The application is ready:

$ curl localhost:8080
Greetings from SIGHUP!

And Prometheus JVM exporter is served using the 30000 port.

$ curl localhost:30000


# HELP jvm_threads_state Current count of threads by state
# TYPE jvm_threads_state gauge
jvm_threads_state{state="WAITING",} 12.0
jvm_threads_state{state="BLOCKED",} 0.0
jvm_threads_state{state="RUNNABLE",} 9.0
jvm_threads_state{state="TERMINATED",} 0.0
jvm_threads_state{state="TIMED_WAITING",} 4.0
jvm_threads_state{state="NEW",} 0.0
# HELP jvm_classes_loaded The number of classes that are currently loaded in the JVM
# TYPE jvm_classes_loaded gauge
jvm_classes_loaded 6616.0
# HELP jvm_classes_loaded_total The total number of classes that have been loaded since the JVM has started execution
# TYPE jvm_classes_loaded_total counter
jvm_classes_loaded_total 6616.0
# HELP jvm_classes_unloaded_total The total number of classes that have been unloaded since the JVM has started execution
# TYPE jvm_classes_unloaded_total counter
jvm_classes_unloaded_total 0.0

How to get started with CCI today

Photo by Lukas Mayer from Pexels

We've been working hard on it and, today, we're happy to invite you to the closed beta of SIGHUP Container Certified Images (CCI).
If you want to get started with CCI and consider them for your containerised workloads, you start here:

We welcome any suggestions and are excited about what is coming next.

Thank you!