391043 Stack
📖 Tutorial

ClickHouse Hardened: A Step-by-Step Guide to Passing Security Scans with Docker Hardened Images

Last updated: 2026-05-10 00:02:14 Intermediate
Complete guide
Follow along with this comprehensive guide

Overview

In November 2025, a team self-hosting Langfuse, an open-source LLM observability platform on Kubernetes, uploaded their ClickHouse image to AWS ECR as part of production preparation. The pipeline scanner returned three critical vulnerabilities—not in ClickHouse, but in the base image. Their security team blocked deployment before it ever reached production. As one frustrated user noted in GitHub Issue #286: Our security team is not allowing us to take it to production. Please suggest alternatives.

ClickHouse Hardened: A Step-by-Step Guide to Passing Security Scans with Docker Hardened Images
Source: www.docker.com

If you’ve shipped containers into an enterprise environment recently, this situation will sound familiar. A perfectly functional deployment gets blocked not because something is broken, but because a scanner found CVEs in packages the application never even touches. Days are spent investigating findings, risk exceptions are written, and the security team rejects them anyway—because the vulnerabilities are technically real even if practically irrelevant to your workload.

This guide is about Docker Hardened Images (DHI) and how to get unstuck when a security team blocks a container with CVEs. We’ll focus specifically on the ClickHouse image—one of the most pulled database images on Docker Hub—and walk you through hardening it so it passes enterprise security scans without breaking functionality.

Prerequisites

Before you begin, ensure you have:

  • A working Docker installation (version 20.10 or later).
  • Access to a Linux environment (or macOS/Linux WSL2 on Windows).
  • Basic familiarity with the command line and Docker commands.
  • A Docker Hub account (or alternative registry access) to pull base images.
  • curl or a similar tool to test ClickHouse endpoints.
  • Optional but recommended: an image scanner like Trivy or Snyk to verify results.

Step-by-Step Instructions

1. Understand the Problem: ClickHouse’s Default Security Posture

ClickHouse, an open-source columnar database built for analytical workloads at scale, is capable of querying billions of rows in milliseconds. Companies like Cloudflare, Uber, and Spotify run it in production. With over 100 million pulls from Docker Hub, it’s the default for teams needing serious analytics throughput. But the image’s security posture was designed with developer ease-of-use in mind—not the hardening that enterprise production environments demand. That gap is where the trouble starts.

To see the issue, pull the latest ClickHouse image and scan it with Trivy:

docker pull clickhouse/clickhouse-server:latest
trivy image clickhouse/clickhouse-server:latest

You’ll likely see several CRITICAL or HIGH vulnerabilities—typically in the base OS packages (e.g., glibc, OpenSSL) that ClickHouse itself never loads.

2. Choose a Hardened Base Image

Docker Hardened Images (DHI) provides minimal, patched base images that strip out unnecessary packages and include only security fixes. For ClickHouse, we’ll use docker-hardened/clickhouse if available, or manually build on top of docker-hardened/ubuntu or docker-hardened/alpine. The DHI images are rebuilt daily with the latest patches.

Example: Pull a DHI Ubuntu image:

docker pull docker-hardened/ubuntu:22.04

3. Build a Custom ClickHouse Image from DHI

Instead of using the official ClickHouse Dockerfile (which starts from ubuntu:22.04 and adds many developer tools), we’ll create a minimal Dockerfile:

# Dockerfile.hardened
FROM docker-hardened/ubuntu:22.04 AS base

RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates \
    wget \
    gpg \
    && rm -rf /var/lib/apt/lists/*

# Download and verify ClickHouse binary (example for arm64, adjust for amd64)
RUN set -ex; \
    wget -q https://packages.clickhouse.com/deb/pool/clickhouse-server_24.3.5.95_amd64.deb; \
    dpkg -i clickhouse-server_24.3.5.95_amd64.deb; \
    rm clickhouse-server_24.3.5.95_amd64.deb; \
    rm -rf /var/lib/apt/lists/*

# Remove unnecessary files
RUN rm -rf /usr/share/doc /usr/share/man /var/log/clickhouse-server/*

EXPOSE 8123 9000

CMD ["clickhouse-server", "--config-file=/etc/clickhouse-server/config.xml"]

Build and tag it:

ClickHouse Hardened: A Step-by-Step Guide to Passing Security Scans with Docker Hardened Images
Source: www.docker.com
docker build -t clickhouse-hardened:latest -f Dockerfile.hardened .

4. Verify the Hardened Image

Run the image and test basic connectivity:

docker run -d --name clickhouse-test -p 8123:8123 -p 9000:9000 clickhouse-hardened:latest
curl http://localhost:8123/?query=SELECT+1

You should see a response like 1. Then stop and remove the container: docker rm -f clickhouse-test.

5. Scan the Hardened Image for CVEs

trivy image clickhouse-hardened:latest

Compare with the original scan. The number of CRITICAL vulnerabilities should drop to zero, and only a few LOW or UNKNOWN may remain (often related to kernel-level issues that can’t be fixed at container level).

6. Integrate with CI/CD and Security Scanners

To maintain compliance, automate scanning in your pipeline. Example GitHub Actions step:

jobs:
  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build hardened image
        run: docker build -t clickhouse-hardened:ci -f Dockerfile.hardened .
      - name: Scan with Trivy
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: clickhouse-hardened:ci
          format: sarif
          output: trivy-results.sarif

7. Deploy to Production

After your security team approves the scan results, push the image to your private registry and update your Kubernetes manifests:

kubectl set image deployment/clickhouse-deployment clickhouse=myregistry/clickhouse-hardened:latest

Common Mistakes

Mistake 1: Using the official image as-is without scanning. Always scan before deployment to avoid surprise blocks.

Mistake 2: Patching base images manually. This is time-consuming and error-prone. Use DHI which is rebuilt daily.

Mistake 3: Removing essential packages. ClickHouse requires some dependencies like ca-certificates. Check the official Dockerfile for required packages.

Mistake 4: Not pinning versions. Always use specific version tags (e.g., docker-hardened/ubuntu:22.04-2025-11-29) to ensure reproducibility.

Summary

Security scanners often flag ClickHouse images due to CVEs in the base OS layer, blocking production deployment. By switching to Docker Hardened Images (DHI)—minimal, daily-patched base images—you can eliminate those vulnerabilities without losing ClickHouse functionality. Build a custom Dockerfile that installs only the ClickHouse binary, scan it with tools like Trivy, and integrate into your CI/CD. The result: a compliant, production-ready ClickHouse container that satisfies even strict enterprise security teams.

Reference: GitHub Issue #286