dockerls 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dockerls/__init__.py +31 -0
- dockerls/application/__init__.py +0 -0
- dockerls/application/dto/__init__.py +3 -0
- dockerls/application/dto/analysis.py +257 -0
- dockerls/application/services/__init__.py +0 -0
- dockerls/application/services/alternatives_lookup.py +167 -0
- dockerls/application/services/composite_repository.py +106 -0
- dockerls/application/services/cross_validation.py +233 -0
- dockerls/application/services/ecosystems.py +350 -0
- dockerls/application/services/fallback_scanner.py +97 -0
- dockerls/application/services/hardening_analysis.py +174 -0
- dockerls/application/services/migration.py +297 -0
- dockerls/application/services/progress.py +56 -0
- dockerls/application/services/remediation.py +321 -0
- dockerls/application/services/scan_history_store.py +88 -0
- dockerls/application/services/scanner_factory.py +88 -0
- dockerls/application/services/source_registry.py +151 -0
- dockerls/application/services/tag_history_store.py +76 -0
- dockerls/application/services/teardown.py +50 -0
- dockerls/application/services/verdict.py +298 -0
- dockerls/application/services/version_discovery.py +108 -0
- dockerls/application/use_cases/__init__.py +0 -0
- dockerls/application/use_cases/analyze_dockerfile.py +103 -0
- dockerls/application/use_cases/analyze_image.py +173 -0
- dockerls/application/use_cases/build_image.py +1795 -0
- dockerls/application/use_cases/compare_images.py +91 -0
- dockerls/application/use_cases/fleet_scan.py +240 -0
- dockerls/application/use_cases/recommend_images.py +1078 -0
- dockerls/application/use_cases/registry_audit.py +133 -0
- dockerls/application/use_cases/search_images.py +23 -0
- dockerls/application/use_cases/upgrade_base.py +167 -0
- dockerls/cache/__init__.py +0 -0
- dockerls/cache/sqlite_cache.py +184 -0
- dockerls/cli/__init__.py +0 -0
- dockerls/cli/analysis_baseline.py +98 -0
- dockerls/cli/app.py +294 -0
- dockerls/cli/commands/__init__.py +0 -0
- dockerls/cli/commands/advisor.py +262 -0
- dockerls/cli/commands/alternatives.py +291 -0
- dockerls/cli/commands/analyze.py +429 -0
- dockerls/cli/commands/analyze_dockerfile.py +104 -0
- dockerls/cli/commands/base_cmd.py +244 -0
- dockerls/cli/commands/base_image.py +551 -0
- dockerls/cli/commands/build.py +1300 -0
- dockerls/cli/commands/cache_cmd.py +104 -0
- dockerls/cli/commands/compare.py +177 -0
- dockerls/cli/commands/controls.py +110 -0
- dockerls/cli/commands/doctor.py +566 -0
- dockerls/cli/commands/export.py +81 -0
- dockerls/cli/commands/fleet.py +159 -0
- dockerls/cli/commands/health.py +84 -0
- dockerls/cli/commands/login.py +53 -0
- dockerls/cli/commands/policy_cmd.py +111 -0
- dockerls/cli/commands/provenance_cmd.py +162 -0
- dockerls/cli/commands/recommend.py +761 -0
- dockerls/cli/commands/registry_audit_cmd.py +103 -0
- dockerls/cli/commands/sbom.py +144 -0
- dockerls/cli/commands/search.py +86 -0
- dockerls/cli/commands/verify.py +115 -0
- dockerls/cli/commands/version.py +12 -0
- dockerls/cli/commands/vex_cmd.py +117 -0
- dockerls/cli/dependencies.py +530 -0
- dockerls/cli/image_names.py +79 -0
- dockerls/cli/options.py +42 -0
- dockerls/cli/progress.py +145 -0
- dockerls/cli/publish_prompt.py +123 -0
- dockerls/cli/rendering.py +214 -0
- dockerls/cli/runtime.py +65 -0
- dockerls/cli/scan_failure.py +71 -0
- dockerls/cli/text.py +39 -0
- dockerls/cli/validators.py +35 -0
- dockerls/cli/vulnerability_view.py +154 -0
- dockerls/domain/__init__.py +0 -0
- dockerls/domain/entities/__init__.py +75 -0
- dockerls/domain/entities/declared_metadata.py +147 -0
- dockerls/domain/entities/dockerfile_analysis.py +318 -0
- dockerls/domain/entities/image.py +109 -0
- dockerls/domain/entities/image_facts.py +137 -0
- dockerls/domain/entities/recommendation.py +33 -0
- dockerls/domain/entities/scan_result.py +129 -0
- dockerls/domain/entities/vulnerability.py +232 -0
- dockerls/domain/interfaces/__init__.py +17 -0
- dockerls/domain/interfaces/cache_store.py +18 -0
- dockerls/domain/interfaces/dockerfile_validator.py +99 -0
- dockerls/domain/interfaces/eol_checker.py +11 -0
- dockerls/domain/interfaces/image_repository.py +15 -0
- dockerls/domain/interfaces/scanner.py +15 -0
- dockerls/domain/security_controls.py +362 -0
- dockerls/domain/value_objects/__init__.py +49 -0
- dockerls/domain/value_objects/attack_surface.py +198 -0
- dockerls/domain/value_objects/base_recipe.py +600 -0
- dockerls/domain/value_objects/base_upgrade.py +292 -0
- dockerls/domain/value_objects/build_labels.py +99 -0
- dockerls/domain/value_objects/build_policy.py +412 -0
- dockerls/domain/value_objects/confidence.py +156 -0
- dockerls/domain/value_objects/fleet.py +174 -0
- dockerls/domain/value_objects/gate.py +327 -0
- dockerls/domain/value_objects/hardening.py +303 -0
- dockerls/domain/value_objects/image_reference.py +90 -0
- dockerls/domain/value_objects/inheritance.py +352 -0
- dockerls/domain/value_objects/network_policy.py +280 -0
- dockerls/domain/value_objects/production_readiness.py +145 -0
- dockerls/domain/value_objects/provenance.py +211 -0
- dockerls/domain/value_objects/recipe_diff.py +188 -0
- dockerls/domain/value_objects/registry_audit.py +195 -0
- dockerls/domain/value_objects/registry_target.py +225 -0
- dockerls/domain/value_objects/remediation_score.py +62 -0
- dockerls/domain/value_objects/scan_history.py +183 -0
- dockerls/domain/value_objects/scan_plan.py +193 -0
- dockerls/domain/value_objects/scanner_db.py +143 -0
- dockerls/domain/value_objects/security_score.py +160 -0
- dockerls/domain/value_objects/security_tier.py +122 -0
- dockerls/domain/value_objects/tag_history.py +180 -0
- dockerls/domain/value_objects/tool_release.py +253 -0
- dockerls/domain/value_objects/tristate.py +47 -0
- dockerls/domain/value_objects/vex.py +249 -0
- dockerls/exit_codes.py +23 -0
- dockerls/exporters/__init__.py +0 -0
- dockerls/exporters/base.py +17 -0
- dockerls/exporters/csv_exporter.py +85 -0
- dockerls/exporters/factory.py +31 -0
- dockerls/exporters/html_exporter.py +105 -0
- dockerls/exporters/json_exporter.py +19 -0
- dockerls/exporters/markdown_exporter.py +84 -0
- dockerls/exporters/sarif_exporter.py +245 -0
- dockerls/infrastructure/__init__.py +0 -0
- dockerls/infrastructure/config/__init__.py +0 -0
- dockerls/infrastructure/config/policy_file.py +165 -0
- dockerls/infrastructure/config/settings.py +197 -0
- dockerls/infrastructure/database/__init__.py +0 -0
- dockerls/infrastructure/database/models.py +78 -0
- dockerls/infrastructure/dockerfile_validator.py +1899 -0
- dockerls/infrastructure/evidence.py +99 -0
- dockerls/infrastructure/hashing.py +165 -0
- dockerls/infrastructure/logging/__init__.py +0 -0
- dockerls/infrastructure/logging/setup.py +98 -0
- dockerls/infrastructure/network/__init__.py +0 -0
- dockerls/infrastructure/network/guarded_client.py +107 -0
- dockerls/infrastructure/network/host_guard.py +117 -0
- dockerls/infrastructure/redaction.py +135 -0
- dockerls/infrastructure/templates/hardening/alpine.dockerfile +44 -0
- dockerls/infrastructure/templates/hardening/debian.dockerfile +45 -0
- dockerls/infrastructure/templates/hardening/distroless.dockerfile +34 -0
- dockerls/infrastructure/templates/hardening/go-alpine.dockerfile +52 -0
- dockerls/infrastructure/templates/hardening/go-debian.dockerfile +54 -0
- dockerls/infrastructure/templates/hardening/go-distroless.dockerfile +43 -0
- dockerls/infrastructure/templates/hardening/go-scratch.dockerfile +48 -0
- dockerls/infrastructure/templates/hardening/go.dockerfile +50 -0
- dockerls/infrastructure/templates/hardening/gradle-alpine.dockerfile +51 -0
- dockerls/infrastructure/templates/hardening/gradle.dockerfile +52 -0
- dockerls/infrastructure/templates/hardening/java-alpine.dockerfile +50 -0
- dockerls/infrastructure/templates/hardening/java-debian.dockerfile +50 -0
- dockerls/infrastructure/templates/hardening/java-distroless.dockerfile +39 -0
- dockerls/infrastructure/templates/hardening/java-ubuntu.dockerfile +54 -0
- dockerls/infrastructure/templates/hardening/java.dockerfile +60 -0
- dockerls/infrastructure/templates/hardening/maven-alpine.dockerfile +56 -0
- dockerls/infrastructure/templates/hardening/maven.dockerfile +57 -0
- dockerls/infrastructure/templates/hardening/node-alpine.dockerfile +47 -0
- dockerls/infrastructure/templates/hardening/node-debian.dockerfile +54 -0
- dockerls/infrastructure/templates/hardening/node-distroless.dockerfile +46 -0
- dockerls/infrastructure/templates/hardening/node-ubuntu.dockerfile +63 -0
- dockerls/infrastructure/templates/hardening/node.dockerfile +61 -0
- dockerls/infrastructure/templates/hardening/php-alpine.dockerfile +45 -0
- dockerls/infrastructure/templates/hardening/php-debian.dockerfile +45 -0
- dockerls/infrastructure/templates/hardening/php-ubuntu.dockerfile +49 -0
- dockerls/infrastructure/templates/hardening/php.dockerfile +44 -0
- dockerls/infrastructure/templates/hardening/python-alpine.dockerfile +51 -0
- dockerls/infrastructure/templates/hardening/python-debian.dockerfile +54 -0
- dockerls/infrastructure/templates/hardening/python-distroless.dockerfile +51 -0
- dockerls/infrastructure/templates/hardening/python-ubuntu.dockerfile +60 -0
- dockerls/infrastructure/templates/hardening/python.dockerfile +58 -0
- dockerls/infrastructure/templates/hardening/ruby-alpine.dockerfile +48 -0
- dockerls/infrastructure/templates/hardening/ruby-debian.dockerfile +50 -0
- dockerls/infrastructure/templates/hardening/rust-alpine.dockerfile +50 -0
- dockerls/infrastructure/templates/hardening/rust-debian.dockerfile +48 -0
- dockerls/infrastructure/templates/hardening/rust-scratch.dockerfile +44 -0
- dockerls/infrastructure/templates/hardening/rust.dockerfile +54 -0
- dockerls/infrastructure/templates/hardening/ubuntu.dockerfile +49 -0
- dockerls/infrastructure/toolchain/__init__.py +0 -0
- dockerls/infrastructure/toolchain/db_metadata.py +115 -0
- dockerls/infrastructure/toolchain/installer.py +435 -0
- dockerls/integrations/__init__.py +0 -0
- dockerls/integrations/dhi/__init__.py +0 -0
- dockerls/integrations/dhi/catalog.py +457 -0
- dockerls/integrations/dhi/definition.py +151 -0
- dockerls/integrations/dhi/repository.py +238 -0
- dockerls/integrations/dockerhub/__init__.py +0 -0
- dockerls/integrations/dockerhub/client.py +318 -0
- dockerls/integrations/dockerhub/urls.py +75 -0
- dockerls/integrations/endoflife/__init__.py +0 -0
- dockerls/integrations/endoflife/checker.py +216 -0
- dockerls/integrations/engine/__init__.py +0 -0
- dockerls/integrations/engine/batch.py +197 -0
- dockerls/integrations/engine/client.py +330 -0
- dockerls/integrations/engine/locator.py +96 -0
- dockerls/integrations/exploitdb/__init__.py +0 -0
- dockerls/integrations/exploitdb/client.py +271 -0
- dockerls/integrations/grype/__init__.py +0 -0
- dockerls/integrations/grype/scanner.py +336 -0
- dockerls/integrations/registry/__init__.py +0 -0
- dockerls/integrations/registry/hardened.py +284 -0
- dockerls/integrations/registry/inspector.py +420 -0
- dockerls/integrations/registry/oci.py +259 -0
- dockerls/integrations/registry/private.py +79 -0
- dockerls/integrations/registry/urls.py +36 -0
- dockerls/integrations/scan_errors.py +67 -0
- dockerls/integrations/scan_target.py +57 -0
- dockerls/integrations/signing/__init__.py +0 -0
- dockerls/integrations/signing/cosign.py +484 -0
- dockerls/integrations/threat_intel/__init__.py +0 -0
- dockerls/integrations/threat_intel/client.py +290 -0
- dockerls/integrations/trivy/__init__.py +0 -0
- dockerls/integrations/trivy/cache_pool.py +176 -0
- dockerls/integrations/trivy/scanner.py +447 -0
- dockerls/utils/__init__.py +0 -0
- dockerls/utils/auth.py +108 -0
- dockerls/utils/executables.py +39 -0
- dockerls/utils/ignore_file.py +130 -0
- dockerls/utils/rate_limit.py +130 -0
- dockerls/utils/resources.py +183 -0
- dockerls/utils/retry.py +31 -0
- dockerls/utils/safe_yaml.py +166 -0
- dockerls/utils/subprocess_runner.py +216 -0
- dockerls/utils/validation.py +72 -0
- dockerls-1.0.0.dist-info/METADATA +563 -0
- dockerls-1.0.0.dist-info/RECORD +230 -0
- dockerls-1.0.0.dist-info/WHEEL +5 -0
- dockerls-1.0.0.dist-info/entry_points.txt +2 -0
- dockerls-1.0.0.dist-info/licenses/LICENSE +21 -0
- dockerls-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Dockerfile.hardened.java-debian
|
|
2
|
+
# Hardened template for Java 21 (Eclipse Temurin JRE Debian Bookworm)
|
|
3
|
+
|
|
4
|
+
ARG JDK_VERSION=21-jdk
|
|
5
|
+
ARG JRE_VERSION=21-jre
|
|
6
|
+
|
|
7
|
+
# Stage 1: Build
|
|
8
|
+
FROM eclipse-temurin:${JDK_VERSION} AS builder
|
|
9
|
+
|
|
10
|
+
WORKDIR /app
|
|
11
|
+
|
|
12
|
+
RUN apt-get update && apt-get install -y --no-install-recommends maven \
|
|
13
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
14
|
+
|
|
15
|
+
COPY pom.xml ./
|
|
16
|
+
COPY src ./src
|
|
17
|
+
RUN mvn clean package -DskipTests || true
|
|
18
|
+
|
|
19
|
+
# Stage 2: Runtime
|
|
20
|
+
FROM eclipse-temurin:${JRE_VERSION}
|
|
21
|
+
|
|
22
|
+
LABEL security.scanner="dockerls"
|
|
23
|
+
LABEL security.hardened="true"
|
|
24
|
+
LABEL maintainer="security@company.com"
|
|
25
|
+
LABEL security.cve-contact="security@company.com"
|
|
26
|
+
|
|
27
|
+
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/./urandom"
|
|
28
|
+
|
|
29
|
+
RUN apt-get update && apt-get upgrade -y \
|
|
30
|
+
&& groupadd -g 10001 appgroup \
|
|
31
|
+
&& useradd -u 10001 -g appgroup -s /usr/sbin/nologin -m appuser \
|
|
32
|
+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
|
33
|
+
|
|
34
|
+
WORKDIR /app
|
|
35
|
+
|
|
36
|
+
COPY --from=builder --chown=appuser:appgroup /app/target/*.jar /app/app.jar
|
|
37
|
+
|
|
38
|
+
ARG GIT_SHA=unknown
|
|
39
|
+
ARG BUILD_TIME=unknown
|
|
40
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
41
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
42
|
+
|
|
43
|
+
USER appuser
|
|
44
|
+
|
|
45
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
|
46
|
+
CMD [ -f /app/app.jar ] || exit 1
|
|
47
|
+
|
|
48
|
+
EXPOSE 8080
|
|
49
|
+
|
|
50
|
+
ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /app/app.jar"]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Dockerfile.hardened.java-distroless
|
|
2
|
+
# Hardened template for Java 21 (Google Distroless - No Shell)
|
|
3
|
+
|
|
4
|
+
ARG JDK_VERSION=21-jdk-alpine
|
|
5
|
+
|
|
6
|
+
# Stage 1: Build
|
|
7
|
+
FROM eclipse-temurin:${JDK_VERSION} AS builder
|
|
8
|
+
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
|
|
11
|
+
RUN apk add --no-cache maven
|
|
12
|
+
|
|
13
|
+
COPY pom.xml ./
|
|
14
|
+
COPY src ./src
|
|
15
|
+
RUN mvn clean package -DskipTests || true
|
|
16
|
+
|
|
17
|
+
# Stage 2: Distroless Java 21 Runtime (No Shell)
|
|
18
|
+
FROM gcr.io/distroless/java21-debian12:nonroot
|
|
19
|
+
|
|
20
|
+
LABEL security.scanner="dockerls"
|
|
21
|
+
LABEL security.hardened="true"
|
|
22
|
+
LABEL maintainer="security@company.com"
|
|
23
|
+
LABEL security.cve-contact="security@company.com"
|
|
24
|
+
|
|
25
|
+
WORKDIR /app
|
|
26
|
+
|
|
27
|
+
COPY --from=builder /app/target/*.jar /app/app.jar
|
|
28
|
+
|
|
29
|
+
ARG GIT_SHA=unknown
|
|
30
|
+
ARG BUILD_TIME=unknown
|
|
31
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
32
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
33
|
+
|
|
34
|
+
# nonroot user in Distroless
|
|
35
|
+
USER 65532:65532
|
|
36
|
+
|
|
37
|
+
EXPOSE 8080
|
|
38
|
+
|
|
39
|
+
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar", "/app/app.jar"]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Dockerfile.hardened.java-ubuntu
|
|
2
|
+
# Hardened template for Java 21 (Eclipse Temurin JRE Ubuntu 24.04)
|
|
3
|
+
|
|
4
|
+
ARG UBUNTU_VERSION=24.04
|
|
5
|
+
|
|
6
|
+
# Stage 1: Build
|
|
7
|
+
FROM ubuntu:${UBUNTU_VERSION} AS builder
|
|
8
|
+
|
|
9
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
10
|
+
|
|
11
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
12
|
+
openjdk-21-jdk maven ca-certificates \
|
|
13
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
14
|
+
|
|
15
|
+
WORKDIR /app
|
|
16
|
+
|
|
17
|
+
COPY pom.xml ./
|
|
18
|
+
COPY src ./src
|
|
19
|
+
RUN mvn clean package -DskipTests || true
|
|
20
|
+
|
|
21
|
+
# Stage 2: Runtime
|
|
22
|
+
FROM ubuntu:${UBUNTU_VERSION}
|
|
23
|
+
|
|
24
|
+
LABEL security.scanner="dockerls"
|
|
25
|
+
LABEL security.hardened="true"
|
|
26
|
+
LABEL maintainer="security@company.com"
|
|
27
|
+
LABEL security.cve-contact="security@company.com"
|
|
28
|
+
|
|
29
|
+
ENV DEBIAN_FRONTEND=noninteractive \
|
|
30
|
+
JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/./urandom"
|
|
31
|
+
|
|
32
|
+
RUN apt-get update && apt-get upgrade -y \
|
|
33
|
+
&& apt-get install -y --no-install-recommends openjdk-21-jre-headless ca-certificates \
|
|
34
|
+
&& groupadd -g 10001 appgroup \
|
|
35
|
+
&& useradd -u 10001 -g appgroup -s /usr/sbin/nologin -m appuser \
|
|
36
|
+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
|
37
|
+
|
|
38
|
+
WORKDIR /app
|
|
39
|
+
|
|
40
|
+
COPY --from=builder --chown=appuser:appgroup /app/target/*.jar /app/app.jar
|
|
41
|
+
|
|
42
|
+
ARG GIT_SHA=unknown
|
|
43
|
+
ARG BUILD_TIME=unknown
|
|
44
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
45
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
46
|
+
|
|
47
|
+
USER appuser
|
|
48
|
+
|
|
49
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
|
50
|
+
CMD [ -f /app/app.jar ] || exit 1
|
|
51
|
+
|
|
52
|
+
EXPOSE 8080
|
|
53
|
+
|
|
54
|
+
ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /app/app.jar"]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Dockerfile.hardened.java
|
|
2
|
+
# Hardened template for Java / JVM - Production Ready (Eclipse Temurin 21)
|
|
3
|
+
|
|
4
|
+
# Stage 1: Builder
|
|
5
|
+
FROM eclipse-temurin:21-jdk-alpine AS builder
|
|
6
|
+
|
|
7
|
+
WORKDIR /app
|
|
8
|
+
|
|
9
|
+
# Copy build output from Maven or Gradle
|
|
10
|
+
COPY pom.xml* mvnw* ./
|
|
11
|
+
COPY .mvn ./.mvn
|
|
12
|
+
COPY build.gradle* settings.gradle* gradlew* ./
|
|
13
|
+
COPY gradle ./gradle
|
|
14
|
+
|
|
15
|
+
# Download dependencies
|
|
16
|
+
RUN if [ -f "./mvnw" ]; then ./mvnw dependency:go-offline; \
|
|
17
|
+
elif [ -f "./gradlew" ]; then ./gradlew --no-daemon dependencies; fi || true
|
|
18
|
+
|
|
19
|
+
COPY src ./src
|
|
20
|
+
|
|
21
|
+
# Compile the jar package
|
|
22
|
+
RUN if [ -f "./mvnw" ]; then ./mvnw clean package -DskipTests; \
|
|
23
|
+
elif [ -f "./gradlew" ]; then ./gradlew --no-daemon bootJar || ./gradlew --no-daemon build -x test; \
|
|
24
|
+
fi || true
|
|
25
|
+
|
|
26
|
+
RUN find target build/libs -name "*.jar" ! -name "*sources*" ! -name "*javadoc*" -exec cp {} /app/app.jar \; || touch /app/app.jar
|
|
27
|
+
|
|
28
|
+
# Stage 2: Runtime Minimal
|
|
29
|
+
FROM eclipse-temurin:21-jre-alpine
|
|
30
|
+
|
|
31
|
+
LABEL security.scanner="dockerls"
|
|
32
|
+
LABEL security.hardened="true"
|
|
33
|
+
LABEL maintainer="your-team@company.com"
|
|
34
|
+
LABEL security.cve-contact="security@company.com"
|
|
35
|
+
|
|
36
|
+
# JVM flags tuned for containers and security
|
|
37
|
+
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/./urandom"
|
|
38
|
+
|
|
39
|
+
RUN addgroup -g 10001 appgroup && \
|
|
40
|
+
adduser -D -u 10001 -G appgroup -h /home/appuser appuser
|
|
41
|
+
|
|
42
|
+
WORKDIR /app
|
|
43
|
+
|
|
44
|
+
COPY --from=builder --chown=appuser:appgroup /app/app.jar /app/app.jar
|
|
45
|
+
|
|
46
|
+
# Build metadata
|
|
47
|
+
ARG GIT_SHA=unknown
|
|
48
|
+
ARG BUILD_TIME=unknown
|
|
49
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
50
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
51
|
+
|
|
52
|
+
USER appuser
|
|
53
|
+
|
|
54
|
+
# Health check
|
|
55
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
|
|
56
|
+
CMD nc -z localhost 8080 || exit 1
|
|
57
|
+
|
|
58
|
+
EXPOSE 8080
|
|
59
|
+
|
|
60
|
+
ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /app/app.jar"]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Dockerfile.hardened.maven-alpine
|
|
2
|
+
# Hardened template for a Java application built with Maven (Alpine).
|
|
3
|
+
#
|
|
4
|
+
# The build uses the official Maven image, which carries the JDK and the
|
|
5
|
+
# tool; the runtime uses only the JRE. This separation keeps the compiler,
|
|
6
|
+
# the Maven cache, and the build dependency tree out of the image that ships
|
|
7
|
+
# to production -- none of it is needed to *run* the application, and each
|
|
8
|
+
# one is attack surface and CVEs to triage later.
|
|
9
|
+
|
|
10
|
+
ARG MAVEN_VERSION=3.9-eclipse-temurin-21-alpine
|
|
11
|
+
ARG JRE_VERSION=21-jre-alpine
|
|
12
|
+
|
|
13
|
+
# Stage 1: Build
|
|
14
|
+
FROM maven:${MAVEN_VERSION} AS builder
|
|
15
|
+
|
|
16
|
+
WORKDIR /app
|
|
17
|
+
|
|
18
|
+
# The POM goes in alone first: that way the dependency layer is only
|
|
19
|
+
# rebuilt when the POM changes, not on every code change.
|
|
20
|
+
COPY pom.xml ./
|
|
21
|
+
RUN mvn -B dependency:go-offline
|
|
22
|
+
|
|
23
|
+
COPY src ./src
|
|
24
|
+
RUN mvn -B clean package -DskipTests
|
|
25
|
+
|
|
26
|
+
# Stage 2: Runtime
|
|
27
|
+
FROM eclipse-temurin:${JRE_VERSION}
|
|
28
|
+
|
|
29
|
+
LABEL security.scanner="dockerls"
|
|
30
|
+
LABEL security.hardened="true"
|
|
31
|
+
LABEL maintainer="security@company.com"
|
|
32
|
+
LABEL security.cve-contact="security@company.com"
|
|
33
|
+
|
|
34
|
+
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/./urandom"
|
|
35
|
+
|
|
36
|
+
RUN apk upgrade --no-cache \
|
|
37
|
+
&& addgroup -g 10001 appgroup \
|
|
38
|
+
&& adduser -u 10001 -G appgroup -s /sbin/nologin -D appuser
|
|
39
|
+
|
|
40
|
+
WORKDIR /app
|
|
41
|
+
|
|
42
|
+
COPY --from=builder --chown=appuser:appgroup /app/target/*.jar /app/app.jar
|
|
43
|
+
|
|
44
|
+
ARG GIT_SHA=unknown
|
|
45
|
+
ARG BUILD_TIME=unknown
|
|
46
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
47
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
48
|
+
|
|
49
|
+
USER appuser
|
|
50
|
+
|
|
51
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
|
52
|
+
CMD [ -f /app/app.jar ] || exit 1
|
|
53
|
+
|
|
54
|
+
EXPOSE 8080
|
|
55
|
+
|
|
56
|
+
ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /app/app.jar"]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Dockerfile.hardened.maven
|
|
2
|
+
# Hardened template for a Java application built with Maven (Debian slim).
|
|
3
|
+
#
|
|
4
|
+
# The build uses the official Maven image, which carries the JDK and the
|
|
5
|
+
# tool; the runtime uses only the JRE. This separation keeps the compiler,
|
|
6
|
+
# the Maven cache, and the build dependency tree out of the image that ships
|
|
7
|
+
# to production -- none of it is needed to *run* the application, and each
|
|
8
|
+
# one is attack surface and CVEs to triage later.
|
|
9
|
+
|
|
10
|
+
ARG MAVEN_VERSION=3.9-eclipse-temurin-21
|
|
11
|
+
ARG JRE_VERSION=21-jre
|
|
12
|
+
|
|
13
|
+
# Stage 1: Build
|
|
14
|
+
FROM maven:${MAVEN_VERSION} AS builder
|
|
15
|
+
|
|
16
|
+
WORKDIR /app
|
|
17
|
+
|
|
18
|
+
# The POM goes in alone first: that way the dependency layer is only
|
|
19
|
+
# rebuilt when the POM changes, not on every code change.
|
|
20
|
+
COPY pom.xml ./
|
|
21
|
+
RUN mvn -B dependency:go-offline
|
|
22
|
+
|
|
23
|
+
COPY src ./src
|
|
24
|
+
RUN mvn -B clean package -DskipTests
|
|
25
|
+
|
|
26
|
+
# Stage 2: Runtime
|
|
27
|
+
FROM eclipse-temurin:${JRE_VERSION}
|
|
28
|
+
|
|
29
|
+
LABEL security.scanner="dockerls"
|
|
30
|
+
LABEL security.hardened="true"
|
|
31
|
+
LABEL maintainer="security@company.com"
|
|
32
|
+
LABEL security.cve-contact="security@company.com"
|
|
33
|
+
|
|
34
|
+
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/./urandom"
|
|
35
|
+
|
|
36
|
+
RUN apt-get update && apt-get upgrade -y --no-install-recommends \
|
|
37
|
+
&& rm -rf /var/lib/apt/lists/* \
|
|
38
|
+
&& groupadd -g 10001 appgroup \
|
|
39
|
+
&& useradd -u 10001 -g appgroup -s /usr/sbin/nologin -m appuser
|
|
40
|
+
|
|
41
|
+
WORKDIR /app
|
|
42
|
+
|
|
43
|
+
COPY --from=builder --chown=appuser:appgroup /app/target/*.jar /app/app.jar
|
|
44
|
+
|
|
45
|
+
ARG GIT_SHA=unknown
|
|
46
|
+
ARG BUILD_TIME=unknown
|
|
47
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
48
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
49
|
+
|
|
50
|
+
USER appuser
|
|
51
|
+
|
|
52
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
|
53
|
+
CMD [ -f /app/app.jar ] || exit 1
|
|
54
|
+
|
|
55
|
+
EXPOSE 8080
|
|
56
|
+
|
|
57
|
+
ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar /app/app.jar"]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Dockerfile.hardened.node-alpine
|
|
2
|
+
# Hardened template for Node.js 22 (Alpine Linux musl)
|
|
3
|
+
|
|
4
|
+
ARG NODE_VERSION=22-alpine
|
|
5
|
+
|
|
6
|
+
# Stage 1: Builder
|
|
7
|
+
FROM node:${NODE_VERSION} AS builder
|
|
8
|
+
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
|
|
11
|
+
RUN apk add --no-cache python3 make g++ && rm -rf /var/cache/apk/*
|
|
12
|
+
|
|
13
|
+
COPY package*.json ./
|
|
14
|
+
RUN npm ci --only=production && npm cache clean --force
|
|
15
|
+
|
|
16
|
+
COPY . .
|
|
17
|
+
RUN npm run build || true
|
|
18
|
+
|
|
19
|
+
# Stage 2: Runtime
|
|
20
|
+
FROM node:${NODE_VERSION}
|
|
21
|
+
|
|
22
|
+
LABEL security.scanner="dockerls"
|
|
23
|
+
LABEL security.hardened="true"
|
|
24
|
+
LABEL maintainer="security@company.com"
|
|
25
|
+
LABEL security.cve-contact="security@company.com"
|
|
26
|
+
|
|
27
|
+
ENV NODE_ENV=production
|
|
28
|
+
|
|
29
|
+
WORKDIR /app
|
|
30
|
+
|
|
31
|
+
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
|
|
32
|
+
COPY --chown=node:node . .
|
|
33
|
+
|
|
34
|
+
ARG GIT_SHA=unknown
|
|
35
|
+
ARG BUILD_TIME=unknown
|
|
36
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
37
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
38
|
+
|
|
39
|
+
USER node
|
|
40
|
+
|
|
41
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
42
|
+
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {if (r.statusCode !== 200) process.exit(1)}).on('error', () => process.exit(1))"
|
|
43
|
+
|
|
44
|
+
EXPOSE 3000
|
|
45
|
+
|
|
46
|
+
ENTRYPOINT ["node"]
|
|
47
|
+
CMD ["--enable-source-maps", "dist/index.js"]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Dockerfile.hardened.node-debian
|
|
2
|
+
# Hardened template for Node.js 22 (Debian Bookworm Slim - glibc)
|
|
3
|
+
|
|
4
|
+
ARG NODE_VERSION=22-bookworm-slim
|
|
5
|
+
|
|
6
|
+
# Stage 1: Builder
|
|
7
|
+
FROM node:${NODE_VERSION} AS builder
|
|
8
|
+
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
|
|
11
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
12
|
+
build-essential python3 ca-certificates \
|
|
13
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
14
|
+
|
|
15
|
+
COPY package*.json ./
|
|
16
|
+
RUN npm ci --only=production && npm cache clean --force
|
|
17
|
+
|
|
18
|
+
COPY . .
|
|
19
|
+
RUN npm run build || true
|
|
20
|
+
|
|
21
|
+
# Stage 2: Runtime
|
|
22
|
+
FROM node:${NODE_VERSION}
|
|
23
|
+
|
|
24
|
+
LABEL security.scanner="dockerls"
|
|
25
|
+
LABEL security.hardened="true"
|
|
26
|
+
LABEL maintainer="security@company.com"
|
|
27
|
+
LABEL security.cve-contact="security@company.com"
|
|
28
|
+
|
|
29
|
+
ENV NODE_ENV=production
|
|
30
|
+
|
|
31
|
+
# Update OS security packages
|
|
32
|
+
RUN apt-get update && apt-get upgrade -y \
|
|
33
|
+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
|
34
|
+
|
|
35
|
+
WORKDIR /app
|
|
36
|
+
|
|
37
|
+
# The 'node' user (UID 1000) already exists in the official Debian Node image
|
|
38
|
+
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
|
|
39
|
+
COPY --chown=node:node . .
|
|
40
|
+
|
|
41
|
+
ARG GIT_SHA=unknown
|
|
42
|
+
ARG BUILD_TIME=unknown
|
|
43
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
44
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
45
|
+
|
|
46
|
+
USER node
|
|
47
|
+
|
|
48
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
49
|
+
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {if (r.statusCode !== 200) process.exit(1)}).on('error', () => process.exit(1))"
|
|
50
|
+
|
|
51
|
+
EXPOSE 3000
|
|
52
|
+
|
|
53
|
+
ENTRYPOINT ["node"]
|
|
54
|
+
CMD ["--enable-source-maps", "dist/index.js"]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Dockerfile.hardened.node-distroless
|
|
2
|
+
# Hardened template for Node.js 22 (Google Distroless - No Shell)
|
|
3
|
+
|
|
4
|
+
ARG NODE_VERSION=22-alpine
|
|
5
|
+
|
|
6
|
+
# Stage 1: Builder
|
|
7
|
+
FROM node:${NODE_VERSION} AS builder
|
|
8
|
+
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
|
|
11
|
+
RUN apk add --no-cache python3 make g++ && rm -rf /var/cache/apk/*
|
|
12
|
+
|
|
13
|
+
COPY package*.json ./
|
|
14
|
+
RUN npm ci --only=production && npm cache clean --force
|
|
15
|
+
|
|
16
|
+
COPY . .
|
|
17
|
+
RUN npm run build || true
|
|
18
|
+
|
|
19
|
+
# Stage 2: Distroless Runtime (Zero Shell)
|
|
20
|
+
FROM gcr.io/distroless/nodejs22-debian12:nonroot
|
|
21
|
+
|
|
22
|
+
LABEL security.scanner="dockerls"
|
|
23
|
+
LABEL security.hardened="true"
|
|
24
|
+
LABEL maintainer="security@company.com"
|
|
25
|
+
LABEL security.cve-contact="security@company.com"
|
|
26
|
+
|
|
27
|
+
ENV NODE_ENV=production
|
|
28
|
+
|
|
29
|
+
WORKDIR /app
|
|
30
|
+
|
|
31
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
32
|
+
COPY --from=builder /app/dist ./dist
|
|
33
|
+
COPY --from=builder /app/package.json ./package.json
|
|
34
|
+
|
|
35
|
+
ARG GIT_SHA=unknown
|
|
36
|
+
ARG BUILD_TIME=unknown
|
|
37
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
38
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
39
|
+
|
|
40
|
+
# nonroot user in Distroless is 65532:65532
|
|
41
|
+
USER 65532:65532
|
|
42
|
+
|
|
43
|
+
EXPOSE 3000
|
|
44
|
+
|
|
45
|
+
ENTRYPOINT ["/nodejs/bin/node"]
|
|
46
|
+
CMD ["--enable-source-maps", "dist/index.js"]
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Dockerfile.hardened.node-ubuntu
|
|
2
|
+
# Hardened template for Node.js 22 (Ubuntu 24.04 LTS)
|
|
3
|
+
|
|
4
|
+
ARG UBUNTU_VERSION=24.04
|
|
5
|
+
|
|
6
|
+
# Stage 1: Builder
|
|
7
|
+
FROM ubuntu:${UBUNTU_VERSION} AS builder
|
|
8
|
+
|
|
9
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
10
|
+
|
|
11
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
12
|
+
curl ca-certificates build-essential \
|
|
13
|
+
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
|
14
|
+
&& apt-get install -y --no-install-recommends nodejs \
|
|
15
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
16
|
+
|
|
17
|
+
WORKDIR /app
|
|
18
|
+
COPY package*.json ./
|
|
19
|
+
RUN npm ci --only=production && npm cache clean --force
|
|
20
|
+
|
|
21
|
+
COPY . .
|
|
22
|
+
RUN npm run build || true
|
|
23
|
+
|
|
24
|
+
# Stage 2: Runtime
|
|
25
|
+
FROM ubuntu:${UBUNTU_VERSION}
|
|
26
|
+
|
|
27
|
+
LABEL security.scanner="dockerls"
|
|
28
|
+
LABEL security.hardened="true"
|
|
29
|
+
LABEL maintainer="security@company.com"
|
|
30
|
+
LABEL security.cve-contact="security@company.com"
|
|
31
|
+
|
|
32
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
33
|
+
ENV NODE_ENV=production
|
|
34
|
+
|
|
35
|
+
RUN apt-get update && apt-get upgrade -y \
|
|
36
|
+
&& apt-get install -y --no-install-recommends curl ca-certificates \
|
|
37
|
+
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
|
38
|
+
&& apt-get install -y --no-install-recommends nodejs \
|
|
39
|
+
&& groupadd -g 10001 nodeuser \
|
|
40
|
+
&& useradd -u 10001 -g nodeuser -s /usr/sbin/nologin -m nodeuser \
|
|
41
|
+
&& apt-get purge -y curl \
|
|
42
|
+
&& apt-get autoremove -y \
|
|
43
|
+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
|
44
|
+
|
|
45
|
+
WORKDIR /app
|
|
46
|
+
|
|
47
|
+
COPY --from=builder --chown=nodeuser:nodeuser /app/node_modules ./node_modules
|
|
48
|
+
COPY --chown=nodeuser:nodeuser . .
|
|
49
|
+
|
|
50
|
+
ARG GIT_SHA=unknown
|
|
51
|
+
ARG BUILD_TIME=unknown
|
|
52
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
53
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
54
|
+
|
|
55
|
+
USER nodeuser
|
|
56
|
+
|
|
57
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
58
|
+
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {if (r.statusCode !== 200) process.exit(1)}).on('error', () => process.exit(1))"
|
|
59
|
+
|
|
60
|
+
EXPOSE 3000
|
|
61
|
+
|
|
62
|
+
ENTRYPOINT ["node"]
|
|
63
|
+
CMD ["--enable-source-maps", "dist/index.js"]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Dockerfile.hardened.node
|
|
2
|
+
# Hardened template for Node.js - Production Ready
|
|
3
|
+
|
|
4
|
+
ARG NODE_VERSION=22-alpine
|
|
5
|
+
|
|
6
|
+
# Stage 1: Builder
|
|
7
|
+
FROM node:${NODE_VERSION} AS builder
|
|
8
|
+
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
|
|
11
|
+
# Install build dependencies if needed (stay only in the builder)
|
|
12
|
+
RUN apk add --no-cache \
|
|
13
|
+
python3 \
|
|
14
|
+
make \
|
|
15
|
+
g++ \
|
|
16
|
+
&& rm -rf /var/cache/apk/*
|
|
17
|
+
|
|
18
|
+
# Copy package manifests and install clean dependencies
|
|
19
|
+
COPY package*.json ./
|
|
20
|
+
RUN npm ci --only=production \
|
|
21
|
+
&& npm cache clean --force
|
|
22
|
+
|
|
23
|
+
# Copy source and build
|
|
24
|
+
COPY . .
|
|
25
|
+
RUN npm run build || true
|
|
26
|
+
|
|
27
|
+
# Stage 2: Runtime
|
|
28
|
+
FROM node:${NODE_VERSION}
|
|
29
|
+
|
|
30
|
+
# Security labels
|
|
31
|
+
LABEL security.scanner="dockerls"
|
|
32
|
+
LABEL security.hardened="true"
|
|
33
|
+
LABEL maintainer="your-team@company.com"
|
|
34
|
+
LABEL security.cve-contact="security@company.com"
|
|
35
|
+
|
|
36
|
+
# Production environment variables
|
|
37
|
+
ENV NODE_ENV=production
|
|
38
|
+
|
|
39
|
+
WORKDIR /app
|
|
40
|
+
|
|
41
|
+
# Copy only the necessary artifacts with ownership for the 'node' user
|
|
42
|
+
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
|
|
43
|
+
COPY --chown=node:node . .
|
|
44
|
+
|
|
45
|
+
# Build metadata
|
|
46
|
+
ARG GIT_SHA=unknown
|
|
47
|
+
ARG BUILD_TIME=unknown
|
|
48
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
49
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
50
|
+
|
|
51
|
+
USER node
|
|
52
|
+
|
|
53
|
+
# Secure native health check
|
|
54
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
55
|
+
CMD node -e "require('http').get('http://localhost:3000/health', (r) => {if (r.statusCode !== 200) process.exit(1)}).on('error', () => process.exit(1))"
|
|
56
|
+
|
|
57
|
+
EXPOSE 3000
|
|
58
|
+
|
|
59
|
+
# No shell - exec form
|
|
60
|
+
ENTRYPOINT ["node"]
|
|
61
|
+
CMD ["--enable-source-maps", "dist/index.js"]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Dockerfile.hardened.php-alpine
|
|
2
|
+
# Hardened template for PHP 8.3 (Alpine Linux)
|
|
3
|
+
|
|
4
|
+
ARG PHP_VERSION=8.3-cli-alpine
|
|
5
|
+
ARG COMPOSER_VERSION=2
|
|
6
|
+
|
|
7
|
+
# Stage 1: Composer dependencies
|
|
8
|
+
FROM composer:${COMPOSER_VERSION} AS vendor
|
|
9
|
+
|
|
10
|
+
WORKDIR /app
|
|
11
|
+
COPY composer.json composer.lock ./
|
|
12
|
+
RUN composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader || true
|
|
13
|
+
|
|
14
|
+
# Stage 2: PHP Runtime
|
|
15
|
+
FROM php:${PHP_VERSION}
|
|
16
|
+
|
|
17
|
+
LABEL security.scanner="dockerls"
|
|
18
|
+
LABEL security.hardened="true"
|
|
19
|
+
LABEL maintainer="security@company.com"
|
|
20
|
+
LABEL security.cve-contact="security@company.com"
|
|
21
|
+
|
|
22
|
+
RUN apk update && apk upgrade --no-cache \
|
|
23
|
+
&& addgroup -g 10001 appgroup \
|
|
24
|
+
&& adduser -u 10001 -G appgroup -s /sbin/nologin -D appuser \
|
|
25
|
+
&& rm -rf /var/cache/apk/*
|
|
26
|
+
|
|
27
|
+
WORKDIR /app
|
|
28
|
+
|
|
29
|
+
COPY --from=vendor --chown=appuser:appgroup /app/vendor ./vendor
|
|
30
|
+
COPY --chown=appuser:appgroup . .
|
|
31
|
+
|
|
32
|
+
ARG GIT_SHA=unknown
|
|
33
|
+
ARG BUILD_TIME=unknown
|
|
34
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
35
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
36
|
+
|
|
37
|
+
USER appuser
|
|
38
|
+
|
|
39
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
|
40
|
+
CMD php -v || exit 1
|
|
41
|
+
|
|
42
|
+
EXPOSE 8000
|
|
43
|
+
|
|
44
|
+
ENTRYPOINT ["php"]
|
|
45
|
+
CMD ["-S", "0.0.0.0:8000", "-t", "public"]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Dockerfile.hardened.php-debian
|
|
2
|
+
# Hardened template for PHP 8.3 (Debian Bookworm Slim)
|
|
3
|
+
|
|
4
|
+
ARG PHP_VERSION=8.3-cli-bookworm
|
|
5
|
+
ARG COMPOSER_VERSION=2
|
|
6
|
+
|
|
7
|
+
# Stage 1: Composer dependencies
|
|
8
|
+
FROM composer:${COMPOSER_VERSION} AS vendor
|
|
9
|
+
|
|
10
|
+
WORKDIR /app
|
|
11
|
+
COPY composer.json composer.lock ./
|
|
12
|
+
RUN composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader || true
|
|
13
|
+
|
|
14
|
+
# Stage 2: PHP Runtime
|
|
15
|
+
FROM php:${PHP_VERSION}
|
|
16
|
+
|
|
17
|
+
LABEL security.scanner="dockerls"
|
|
18
|
+
LABEL security.hardened="true"
|
|
19
|
+
LABEL maintainer="security@company.com"
|
|
20
|
+
LABEL security.cve-contact="security@company.com"
|
|
21
|
+
|
|
22
|
+
RUN apt-get update && apt-get upgrade -y \
|
|
23
|
+
&& groupadd -g 10001 appgroup \
|
|
24
|
+
&& useradd -u 10001 -g appgroup -s /usr/sbin/nologin -m appuser \
|
|
25
|
+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
|
26
|
+
|
|
27
|
+
WORKDIR /app
|
|
28
|
+
|
|
29
|
+
COPY --from=vendor --chown=appuser:appgroup /app/vendor ./vendor
|
|
30
|
+
COPY --chown=appuser:appgroup . .
|
|
31
|
+
|
|
32
|
+
ARG GIT_SHA=unknown
|
|
33
|
+
ARG BUILD_TIME=unknown
|
|
34
|
+
LABEL org.opencontainers.image.revision="${GIT_SHA}"
|
|
35
|
+
LABEL org.opencontainers.image.created="${BUILD_TIME}"
|
|
36
|
+
|
|
37
|
+
USER appuser
|
|
38
|
+
|
|
39
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
|
|
40
|
+
CMD php -v || exit 1
|
|
41
|
+
|
|
42
|
+
EXPOSE 8000
|
|
43
|
+
|
|
44
|
+
ENTRYPOINT ["php"]
|
|
45
|
+
CMD ["-S", "0.0.0.0:8000", "-t", "public"]
|