# How to Run testssl.sh Within Docker Containers: Complete Guide

> Learn to run testssl.sh in Docker containers. Use the official image and pass scanner arguments directly with host directory bind mounts for output. Get started now.

- Repository: [Dirk Wetter/testssl.sh](https://github.com/drwetter/testssl.sh)
- Tags: how-to-guide
- Published: 2026-03-01

---

**You can run testssl.sh within Docker containers using the official scratch-based image from GitHub Container Registry or Docker Hub, passing scanner arguments directly to `docker run` while bind-mounting host directories to capture output files.**

The [`drwetter/testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/drwetter/testssl.sh) repository provides a containerized version of the SSL/TLS scanner that eliminates host-side dependencies. This guide explains how to execute scans using pre-built images and how to build custom variants from source.

## Understanding the testssl.sh Docker Image Architecture

The container image follows a **multi-stage build** pattern designed for minimal footprint and security.

### Multi-Stage Build Process

The `Dockerfile` defines two distinct stages. First, a **builder stage** uses an openSUSE Leap base to pull required binaries—bash, openssl, curl, and dependencies—into a custom root-fs at `/rootfs` (lines 6-20). 

Second, a **runtime stage** copies this stripped root-fs into a **scratch** image (lines 33-60). This approach ensures the final image contains only the essential runtime components, reducing attack surface and image size.

### Security-First Runtime Configuration

The runtime image creates a non-root user named `testssl` with **UID 1000** and sets this as the default execution context. The entrypoint is hardcoded to [`testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/testssl.sh), meaning any arguments passed to `docker run` are interpreted directly as scanner options.

## Running testssl.sh in Docker Containers

The official images are published to both Docker Hub and GitHub Container Registry under [`ghcr.io/testssl/testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/ghcr.io/testssl/testssl.sh).

### Quick Start with Pre-Built Images

To verify the installation or view available options, run the container without arguments to display the built-in help:

```bash
docker run --rm -it ghcr.io/testssl/testssl.sh:3.2

```

This executes the default entrypoint and shows the scanner's `--help` output.

### Handling Output Files and Permissions

When generating reports with flags like `--html`, `--json`, or `--log`, the scanner creates files with ownership `testssl:1000` and mode `644` inside the container. To retrieve these files on your host system, you must bind-mount a host directory and set the container's working directory accordingly.

Scan a target and write an HTML report to your host:

```bash
docker run --rm -it \
  -v /tmp:/data \
  --workdir /data \
  ghcr.io/testssl/testssl.sh:3.2 \
  --htmlfile ./ example.com

```

The HTML file appears as `/tmp/example.com_p443-<date>-<time>.html` on your host machine. According to [`Dockerfile.md`](https://github.com/drwetter/testssl.sh/blob/main/Dockerfile.md) (lines 13-18), this pattern ensures proper file permissions and accessibility.

## Building Custom testssl.sh Images

You can build container images locally from specific branches or tags when you need custom modifications or the Alpine-based variant.

### Building from Source

Clone the repository and build using the local `Dockerfile`:

```bash
git clone --branch 3.2 --depth 1 https://github.com/testssl/testssl.sh .
docker build -t localhost/testssl.sh:3.2 .

```

Alternatively, build directly from the remote repository without local checkout:

```bash
docker build -t localhost/testssl.sh:3.2 \
  https://github.com/testssl/testssl.sh.git#3.2

```

These methods reference the multi-stage build defined in `Dockerfile` (lines 35-43), which handles the builder and runtime stages automatically.

### Alpine-Based Variant

For a smaller image footprint, use the Alpine-based Dockerfile:

```bash
docker build -t localhost/testssl.sh:3.2-alpine \
  --file https://raw.githubusercontent.com/testssl/testssl.sh/3.2/Dockerfile.alpine \
  https://github.com/testssl/testssl.sh.git#3.2

```

As documented in [`Dockerfile.md`](https://github.com/drwetter/testssl.sh/blob/main/Dockerfile.md) (lines 66-73), this variant uses Alpine Linux instead of the scratch-based approach, trading minimalism for broader compatibility with certain network debugging tools.

## Summary

- The **official testssl.sh image** uses a multi-stage build (openSUSE builder → scratch runtime) to minimize size and dependencies.
- The container runs as **non-root user `testssl` (UID 1000)** with the entrypoint already set to the scanner script.
- Use **bind mounts and `--workdir`** to capture HTML, JSON, or log files to your host filesystem with correct permissions.
- Build custom images from any branch using the remote repository URL or locally cloned source.
- Choose between the **scratch-based** image (smallest, most secure) or the **Alpine-based** variant for broader tooling support.

## Frequently Asked Questions

### How do I save scan results when running testssl.sh in Docker?

Bind-mount a host directory to the container and set it as the working directory. The scanner writes files with mode `644` and ownership `testssl:1000`, so mounting a host path like `-v /tmp:/data` combined with `--workdir /data` allows the output files to persist on your host after the container exits.

### What is the difference between the standard and Alpine testssl.sh Docker images?

The **standard image** copies a stripped root-fs into a scratch container, resulting in a minimal runtime with no package manager or shell beyond the essentials. The **Alpine variant** uses `Dockerfile.alpine` and builds on Alpine Linux, offering a slightly larger image but including additional utilities that may help with network debugging or custom scripting.

### Can I run testssl.sh in Docker without installing anything on my host?

Yes. The image contains all runtime dependencies including bash, openssl, and curl. You only need Docker installed—no other host-side packages are required. Pull the image from [`ghcr.io/testssl/testssl.sh`](https://github.com/drwetter/testssl.sh/blob/main/ghcr.io/testssl/testssl.sh) or Docker Hub and run it immediately.

### Which user does the testssl.sh Docker container run as?

The container executes as the **non-root user `testssl` with UID 1000**, as defined in `Dockerfile` (lines 33-60). This security measure ensures the scanner operates with minimal privileges inside the container environment.