# Getting Started with FIPS Containers

URL: https://edu.chainguard.dev/chainguard/fips/getting-started.md
Last Modified: October 16, 2025
Tags: FIPS, Tutorial, Getting Started

Deploy and verify your first Chainguard FIPS container

 Prerequisites Before starting, you&rsquo;ll need:
Chainguard account with FIPS access: FIPS containers are not included in the free tier. Contact Chainguard to request access. Docker or compatible container runtime: Install Docker Desktop or another OCI-compatible runtime. Basic container knowledge: Familiarity with pulling and running container images. FIPS containers work on any recent Linux kernel, including:
Linux workstations macOS (Docker Desktop) Windows (WSL2 with Docker Desktop) Choosing a FIPS Image Chainguard offers 400+ FIPS image variants. Choose based on your use case:
Language runtime images if you&rsquo;re building applications:
go-fips - For building Go applications python-fips - For Python applications node-fips - For Node.js applications jdk-fips or jre-fips - For Java applications dotnet-runtime-fips - For .NET applications Application images if you need a specific tool or service:
nginx-fips - Web server postgres-fips - Database prometheus-fips - Monitoring And many more Base images for minimal runtime environments:
glibc-openssl-fips - Minimal glibc-based runtime busybox-fips - Minimal BusyBox environment Browse the complete catalog at images.chainguard.dev/?category=fips.
Your First FIPS Container Let&rsquo;s start with a Python example to verify FIPS is working.
Pull the Image Replace ORGANIZATION with your organization name in the Chainguard Registry:
docker pull cgr.dev/$ORGANIZATION/python-fips:latest Run a Test Script Create a Python script that uses cryptography:
cat &gt; test_fips.py &lt;&lt; &#39;EOF&#39; import hashlib import ssl # Test that we can use cryptographic functions data = b&#34;Hello, FIPS!&#34; hash_result = hashlib.sha256(data).hexdigest() print(f&#34;SHA-256 hash: {hash_result}&#34;) # Check SSL/TLS configuration print(f&#34;OpenSSL version: {ssl.OPENSSL_VERSION}&#34;) print(&#34;FIPS cryptography is active&#34;) EOFRun the script in the FIPS container:
docker run --rm -v $(pwd):/work -w /work \ cgr.dev/$ORGANIZATION/python-fips:latest \ test_fips.pyYou should see output like:
SHA-256 hash: 4a1e3b5c7d9f2a8c6b0e4f3a9d8c7b6a5e4d3c2b1a0f9e8d7c6b5a4e3d2c1b0a OpenSSL version: OpenSSL 3.4.0 5 Aug 2025 FIPS cryptography is activeThis confirms the container is using OpenSSL for cryptographic operations.
Verifying FIPS Configuration Check the SBOM Every Chainguard image includes a Software Bill of Materials (SBOM). Verify FIPS-required packages:
cosign download attestation cgr.dev/$ORGANIZATION/python-fips:latest | jq -r .payload | base64 -d | jq &#39;.predicate.buildDefinition.externalParameters.&#34;image-configuration&#34;.contents.packages&#39; | grep -E &#34;libcrypto|openssl-config&#34;Look for:
libcrypto3 version 3.4.0-r2 or higher openssl-config-fipshardened version 3.4.0-r3 or higher These packages indicate kernel-independent FIPS configuration.
Inspect OpenSSL Configuration Run a container interactively to check OpenSSL configuration:
docker run --rm -it --entrypoint /usr/bin/bash cgr.dev/$ORGANIZATION/python-fips:latest-devInside the container, verify the FIPS module:
cat /etc/ssl/fipsmodule.cnfYou should see configuration for the FIPS provider. This file&rsquo;s presence and validity are essential for FIPS operation.
Building Applications with FIPS Multi-Stage Build Pattern The recommended pattern is to build with a FIPS SDK image and run with a minimal FIPS runtime image.
Example Dockerfile for a Go application:
# Build stage FROM cgr.dev/$ORGANIZATION/go-fips:latest AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN go build -o myapp # Runtime stage FROM cgr.dev/$ORGANIZATION/glibc-openssl-fips:latest COPY --from=builder /app/myapp /usr/bin/myapp ENTRYPOINT [&#34;/usr/bin/myapp&#34;]This pattern:
Builds your application with FIPS-enabled Go toolchain Produces a minimal runtime image with only the binary and FIPS runtime Maintains FIPS compliance throughout Build and Run docker build -t myapp-fips . docker run --rm myapp-fipsThe resulting container runs on any Linux kernel and maintains FIPS validation.
Common Patterns Python Application with Requirements FROM cgr.dev/$ORGANIZATION/python-fips:latest WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD [&#34;python&#34;, &#34;app.py&#34;] Node.js Application FROM cgr.dev/$ORGANIZATION/node-fips:latest AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --production COPY . . # Use multi-stage if you want a smaller runtime FROM cgr.dev/$ORGANIZATION/node-fips:latest WORKDIR /app COPY --from=builder /app . CMD [&#34;node&#34;, &#34;server.js&#34;] Java Application FROM cgr.dev/$ORGANIZATION/jdk-fips:latest AS builder WORKDIR /app COPY . . RUN javac MyApp.java FROM cgr.dev/$ORGANIZATION/jre-fips:latest WORKDIR /app COPY --from=builder /app/*.class . CMD [&#34;java&#34;, &#34;MyApp&#34;] Testing FIPS Enforcement To verify that FIPS mode is enforced, you can intentionally break the FIPS configuration and confirm the application fails.
Warning: This test should only be done in development environments.
Run a container with access to modify system files:
docker run --rm -it --user root --entrypoint /usr/bin/bash \ cgr.dev/$ORGANIZATION/python-fips:latest-devInside the container, break the FIPS configuration:
# Backup the config cp /etc/ssl/fipsmodule.cnf /tmp/fipsmodule.cnf.bak # Invalidate it ln -sf /dev/null /etc/ssl/fipsmodule.cnf # Try to use crypto python3 -c &#34;import hashlib; print(hashlib.sha256(b&#39;test&#39;).hexdigest())&#34;You should see an error indicating FIPS is required but not available. This proves the container enforces FIPS mode and won&rsquo;t fall back to non-validated cryptography.
Restore the config to fix:
cp /tmp/fipsmodule.cnf.bak /etc/ssl/fipsmodule.cnf Development Workflow Local Development FIPS containers work on any kernel, so you can develop and test locally:
Pull the FIPS image for your language/framework Mount your source code into the container Iterate on code with hot-reload if your framework supports it Test cryptographic operations work correctly Example for Python development:
docker run --rm -it \ -v $(pwd):/app \ -w /app \ -p 8000:8000 \ --entrypoint /usr/bin/bash cgr.dev/$ORGANIZATION/python-fips:latest-devInside, install development dependencies and run your app.
CI/CD Integration FIPS containers work in standard CI/CD pipelines without special infrastructure.
GitHub Actions example:
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Pull FIPS image run: docker pull cgr.dev/$ORGANIZATION/python-fips:latest - name: Run tests run: | docker run --rm -v $(pwd):/app -w /app \ cgr.dev/$ORGANIZATION/python-fips:latest \ python -m pytestNo special runners or kernel configurations required.
Troubleshooting Issue: &ldquo;FIPS mode requested but not available&rdquo; Cause: The FIPS provider configuration is missing or invalid.
Solution: Verify you&rsquo;re using a FIPS-tagged image (e.g., python-fips, not python). Check the SBOM contains required packages.
Issue: Application crashes on startup Cause: The application may be using a cryptographic library that doesn&rsquo;t support FIPS.
Solution: Ensure your application uses OpenSSL-backed cryptography.
Issue: Performance degradation Cause: Likely not FIPS-related. Profile your application first.
Solution: Use standard profiling tools to identify bottlenecks. FIPS cryptography typically adds minimal overhead.
Issue: Can&rsquo;t pull the image Cause: FIPS images require account access.
Solution: Verify your organization has FIPS access. Contact support if needed.
Next Steps Now that you&rsquo;ve deployed your first FIPS container:
Kernel-independent architecture: Understand how it works under the hood FAQs: Check common questions about FIPS implementation Chainguard support: Contact us for questions or custom requirements 
