M0 / Lab setup and verification

Docker quickstart

FoundationsPractitionerAdvisor

After this lesson you can

  • Build and run this course's Dockerfile on your own machine, without cloning any repository
  • Explain what docker build and docker run do, with a one-line mental model
  • Confirm with openssl version that ML-KEM and ML-DSA work natively

Before thisEnvironment overview: container or native

Mental model

A Docker image is a pre-packaged, self-consistent snapshot of an operating system. docker build produces that snapshot from a recipe file (a Dockerfile); docker run runs it. You do not need to know anything beyond these two commands. You do not need to clone a repository for this lesson: the full Dockerfile is below, and copying it into a file on your machine is enough.

Why no source build is needed

Early materials reviewed during this course’s research recommended building OpenSSL 3.5 from source (see the native-install-deep-dive lesson, which carries an important warning about that material: three different days gave three different, contradictory build instructions). The Dockerfile in this lesson instead installs directly from a package manager (Debian trixie’s apt repository), because that is enough: Debian trixie’s own repository ships 3.5.7MEASURED, and from 3.5 onward OpenSSL’s ML-KEM, ML-DSA and SLH-DSA support is in the default provider with no special build flags.

FROM debian:trixie-slim

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

WORKDIR /lab
CMD ["bash"]

Line by line: FROM sets the base image (here the slimmed-down “slim” variant of Debian’s “trixie” release). RUN gives shell commands to execute while the image is built; here it refreshes the package list, installs openssl and the certificate package, then deletes the downloaded package cache to keep the image small. WORKDIR sets the default working directory inside the container. CMD says what to run when the container starts with docker run and no other command is given (here a bash shell).

This Dockerfile was actually tested with docker build and docker run on 2026-09-04; the outputs of the lab commands above are real results, not estimates. The public key file of the ML-DSA-65 key (PEM format, base64 encoded) holds 2726 BMEASURED. That differs from the raw 1952-byte public key FIPS 204 specifies (see M4), because the PEM format adds base64 encoding and an ASN.1 wrapper.

If you want a persistent shell

docker run --rm -it pqc-academy-lab bash

This opens an interactive bash session inside the container. Instead of typing docker run before every command, you can run the lab commands from other lessons one after another in this shell. The --rm flag you saw in every docker run above cleans up the container when the session ends (otherwise stopped containers pile up after each docker run, visible with docker ps -a). If you want to keep data, mount your own directory with -v $(pwd):/lab. The -it flag allocates an interactive terminal (i) and a pseudo-TTY (t), which you need to run an interactive program like bash.

Is this the course’s “only” OpenSSL version

No, and it matters to say so clearly: the container you build in this lesson has OpenSSL 3.5.7MEASURED, but the certificate chain measurements in M7 were made on a different machine with OpenSSL 3.6.2. Both are 3.5 or later, so they support ML-KEM, ML-DSA and SLH-DSA the same way. The exact patch version (3.5.7 or 3.6.2) does not matter; what matters is that major.minor is at least 3.5. When a number in this course is labelled “measured with OpenSSL X.Y”, that tells you which environment the measurement came from. If your container shows a different patch version, that is not an error, just a natural difference depending on when you ran apt-get update.

Numbers to know

  • docker/Dockerfile: Debian trixie-slim + apt-get install openssl gives native ML-KEM, ML-DSA and SLH-DSA, with no extra setup

Lab: Create the Dockerfile, build the image, verify

Requires: Docker (or a compatible OCI runtime). Check your setup

shell
mkdir -p pqc-lab && cd pqc-lab
Recorded output
(the directory is created and you move into it)
shell
cat > Dockerfile << 'EOF'
FROM debian:trixie-slim
RUN apt-get update -qq \
    && apt-get install -y -qq --no-install-recommends \
        openssl ca-certificates \
    && rm -rf /var/lib/apt/lists/*
WORKDIR /lab
CMD ["bash"]
EOF
Recorded output
(the Dockerfile is created; it has the same content as this course's docker/Dockerfile, so copy and paste works and you do not need to clone anything)
shell
docker build -t pqc-academy-lab .
Recorded output
Successfully tagged pqc-academy-lab:latest. On the first run it downloads the Debian base image (debian:trixie-slim), which can take a few seconds to a few minutes depending on network speed and cache; later builds finish in seconds because the layers are cached
shell
docker run --rm pqc-academy-lab openssl version
Recorded output
OpenSSL 3.5.7 9 Jun 2026 (Library: OpenSSL 3.5.7 9 Jun 2026)
shell
docker run --rm pqc-academy-lab openssl list -providers
Recorded output
Providers:
  default
    name: OpenSSL Default Provider
    version: 3.5.7
    status: active
shell
docker run --rm pqc-academy-lab sh -c "openssl genpkey -algorithm ML-DSA-65 -out /tmp/k.key && openssl pkey -in /tmp/k.key -pubout -out /tmp/k.pub && wc -c /tmp/k.pub"
Recorded output
2726 /tmp/k.pub

At the table

How to say this in a bank meeting.

To an executive
Every lab environment was tested by this course in advance. If you hit a learning barrier, that is a gap in the course, not your mistake.
To an architect
Container-first is a defensible pattern in production too: in a CI/CD pipeline, a mismatch where 'the test environment was built with version X but production runs version Y' can make PQC negotiation fail silently (see the build-time versus runtime divergence risk in M12). A container image is the standard way to keep the two environments identical.
Objection
“"Containers don't reflect real production. Isn't a native install more 'real'?"”
Answer
The opposite: by removing version uncertainty, a container lets you separate what really comes from the OpenSSL version from what is a quirk of your own system.

Sources

  • Docker Inc., 2026. The primary, current reference for what each Dockerfile line (FROM, RUN, WORKDIR, CMD) does

    FROM, RUN, WORKDIR, CMD sections / 8 min

  • Debian Project, 2026. Source showing that Debian trixie's apt repository ships OpenSSL 3.5.7 directly as a package, so no source build is needed

    package page, version number / 2 min

Checkpoint

Answer first, then compare with the model answer and score yourself against the rubric. Saved in this browser only.

  1. 01Recall

    What do docker build and docker run each do, in order?

  2. 02Recall

    What does the --rm flag add to docker run?

  3. 03Scenario

    If docker run ... openssl version shows an old version like 'OpenSSL 1.1.1', what could that indicate (the image, the host, or the command itself)?

  4. 04Hostile

    Your first docker build took 90 seconds, which seems longer than expected. Is something broken, and how would you tell?