From 693bfc740b331da69f62fefcdf7eddb3fb01e363 Mon Sep 17 00:00:00 2001 From: Marco Franzon <43796979+mfranzon@users.noreply.github.com> Date: Sat, 22 Nov 2025 00:52:13 +0300 Subject: [PATCH] Add DHI to the Python guide (#23749) ## Description Upgraded Python language guide to include DHI-based Dockerfile example. ## Reviews - [ ] Technical review - [ ] Editorial review - [ ] Product review --------- Co-authored-by: Craig Osterhout <103533812+craig-osterhout@users.noreply.github.com> Co-authored-by: Sarah Sanders --- content/guides/python/containerize.md | 200 +++++++++++++++++++++++++- 1 file changed, 197 insertions(+), 3 deletions(-) diff --git a/content/guides/python/containerize.md b/content/guides/python/containerize.md index f53be97a2d..fedc4b7523 100644 --- a/content/guides/python/containerize.md +++ b/content/guides/python/containerize.md @@ -45,6 +45,12 @@ questions about your application. For example, this application uses FastAPI to run. Refer to the following example to answer the prompts from `docker init` and use the same answers for your prompts. +Before editing your Dockerfile, you need to choose a base image. You can use the [Python Docker Official Image](https://hub.docker.com/_/python), +or a [Docker Hardened Image (DHI)](https://hub.docker.com/hardened-images/catalog/dhi/python). + +Docker Hardened Images (DHIs) are minimal, secure, and production-ready base images maintained by Docker. +They help reduce vulnerabilities and simplify compliance. For more details, see [Docker Hardened Images](/dhi/). + ```console $ docker init Welcome to the Docker Init CLI! @@ -63,6 +69,189 @@ Let's get started! ? What is the command to run your app? python3 -m uvicorn app:app --host=0.0.0.0 --port=8000 ``` + +Create a file named `.gitignore` with the following contents. + +```text {collapse=true,title=".gitignore"} +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +``` + +{{< /tab >}} +{{< tab name="Using the official Docker image" >}} + +If you don't have Docker Desktop installed or prefer creating the assets +manually, you can create the following files in your project directory. + +Create a file named `Dockerfile` with the following contents. + +```dockerfile {collapse=true,title=Dockerfile} +# syntax=docker/dockerfile:1 + +# Comments are provided throughout this file to help you get started. +# If you need more help, visit the Dockerfile reference guide at +# https://docs.docker.com/go/dockerfile-reference/ + +# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7 + +# This Dockerfile uses Docker Hardened Images (DHI) for enhanced security. +# For more information, see https://docs.docker.com/dhi/ +ARG PYTHON_VERSION=3.12 +FROM python:${PYTHON_VERSION}-slim + +# Prevents Python from writing pyc files. +ENV PYTHONDONTWRITEBYTECODE=1 + +# Keeps Python from buffering stdout and stderr to avoid situations where +# the application crashes without emitting any logs due to buffering. +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app + +# Create a non-privileged user that the app will run under. +# See https://docs.docker.com/go/dockerfile-user-best-practices/ +ARG UID=10001 +RUN adduser \ + --disabled-password \ + --gecos "" \ + --home "/nonexistent" \ + --shell "/sbin/nologin" \ + --no-create-home \ + --uid "${UID}" \ + appuser + +# Download dependencies as a separate step to take advantage of Docker's caching. +# Leverage a cache mount to /root/.cache/pip to speed up subsequent builds. +# Leverage a bind mount to requirements.txt to avoid having to copy them into +# into this layer. +RUN --mount=type=cache,target=/root/.cache/pip \ + --mount=type=bind,source=requirements.txt,target=requirements.txt \ + python -m pip install -r requirements.txt + +# Switch to the non-privileged user to run the application. +USER appuser + +# Copy the source code into the container. +COPY . . + +# Expose the port that the application listens on. +EXPOSE 8000 + +# Run the application. +CMD ["python3", "-m", "uvicorn", "app:app", "--host=0.0.0.0", "--port=8000"] +``` + +Create a file named `compose.yaml` with the following contents. + +```yaml {collapse=true,title=compose.yaml} +# Comments are provided throughout this file to help you get started. +# If you need more help, visit the Docker Compose reference guide at +# https://docs.docker.com/go/compose-spec-reference/ + +# Here the instructions define your application as a service called "server". +# This service is built from the Dockerfile in the current directory. +# You can add other services your application may depend on here, such as a +# database or a cache. For examples, see the Awesome Compose repository: +# https://github.com/docker/awesome-compose +services: + server: + build: + context: . + ports: + - 8000:8000 +``` + +Create a file named `.dockerignore` with the following contents. + +```text {collapse=true,title=".dockerignore"} +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/go/build-context-dockerignore/ + +**/.DS_Store +**/__pycache__ +**/.venv +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose.y*ml +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md +``` + Create a file named `.gitignore` with the following contents. ```text {collapse=true,title=".gitignore"} @@ -123,7 +312,7 @@ venv.bak/ ``` {{< /tab >}} -{{< tab name="Manually create assets" >}} +{{< tab name="Using Docker Hardened Image" >}} If you don't have Docker Desktop installed or prefer creating the assets manually, you can create the following files in your project directory. @@ -139,8 +328,10 @@ Create a file named `Dockerfile` with the following contents. # Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7 -ARG PYTHON_VERSION=3.12 -FROM python:${PYTHON_VERSION}-slim +# This Dockerfile uses Docker Hardened Images (DHI) for enhanced security. +# For more information, see https://docs.docker.com/dhi/ +ARG PYTHON_VERSION=3.12.12-debian13-fips-dev +FROM /dhi-python:${PYTHON_VERSION} # Prevents Python from writing pyc files. ENV PYTHONDONTWRITEBYTECODE=1 @@ -149,6 +340,9 @@ ENV PYTHONDONTWRITEBYTECODE=1 # the application crashes without emitting any logs due to buffering. ENV PYTHONUNBUFFERED=1 +#Add dependencies for adduser +RUN apt update -y && apt install adduser -y + WORKDIR /app # Create a non-privileged user that the app will run under.