diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 288c0ba..b5af664 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -29,9 +29,20 @@ jobs: run: | go install github.com/securego/gosec/v2/cmd/gosec@v2.22.2 gosec -exclude=G115 ./... - - name: Run Trivy vulnerability scanner + - name: Run Trivy vulnerability scanner (filesystem) uses: aquasecurity/trivy-action@bfa4b33a029b9aa80ddb784b45574c30e072c59e # 0.24.0 with: scan-type: 'fs' severity: 'CRITICAL,HIGH' exit-code: '1' + + - name: Build Docker image + run: | + docker build -t flowgre:scan --build-arg VERSION=scan . + + - name: Run Trivy vulnerability scanner (Docker image) + uses: aquasecurity/trivy-action@bfa4b33a029b9aa80ddb784b45574c30e072c59e # 0.24.0 + with: + image-ref: 'flowgre:scan' + severity: 'CRITICAL,HIGH' + exit-code: '1' diff --git a/Dockerfile b/Dockerfile index 5574661..4140e20 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ # --------------------------------------------------------------------------- # Build stage — compile a fully static binary (CGO_ENABLED=0) # --------------------------------------------------------------------------- -FROM golang:1.26-alpine AS build-stage +FROM golang:1.26-alpine3.24 AS build-stage WORKDIR /src @@ -12,21 +12,23 @@ WORKDIR /src COPY go.mod go.sum ./ RUN go mod download +ARG VERSION=dev + # Copy source and build a static binary. # TARGETARCH is auto-injected by BuildKit (arm64 on this host, amd64 on CI). COPY . . -RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -ldflags "-s -w" -o /flowgre . +RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -ldflags "-s -w -X main.version=${VERSION}" -o /flowgre . # --------------------------------------------------------------------------- # Runtime stage — minimal Alpine image, non-root user # --------------------------------------------------------------------------- -FROM alpine:3.21 +FROM alpine:3.24 RUN addgroup -S flowgre && \ adduser -S -g flowgre flowgre WORKDIR /opt/app -COPY --from=build-stage /flowgre ./flowgre +COPY --chown=flowgre:flowgre --from=build-stage /flowgre ./flowgre USER flowgre @@ -34,10 +36,11 @@ ENTRYPOINT ["/opt/app/flowgre"] # OCI labels — version is injected at build time via --build-arg ARG VERSION=dev -LABEL org.opencontainers.image.source="https://github.com/dmabry/flowgre" \ +LABEL org.opencontainers.image.version="${VERSION}" \ + org.opencontainers.image.source="https://github.com/dmabry/flowgre" \ org.opencontainers.image.description="NetFlow v9 / IPFIX packet generator for collector stress testing" \ org.opencontainers.image.licenses="Apache-2.0" \ - org.opencontainers.image.version="${VERSION}" + org.opencontainers.image.vendor="Flowgre Team" # No HEALTHCHECK — flowgre is a CLI tool, not a daemon. # The /health endpoint only exists in barrage mode with -web flag. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..fe57eb0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +services: + flowgre: + build: + context: . + dockerfile: Dockerfile + args: + VERSION: dev + image: flowgre:dev + container_name: flowgre + network_mode: "host" + # Override command - examples: + # single mode: + # command: ["single", "-server", "127.0.0.1", "-port", "9995", "-count", "10"] + # barrage mode: + # command: ["barrage", "-server", "127.0.0.1", "-port", "9995", "-workers", "2", "-delay", "100"] + # ipfix mode: + # command: ["ipfix", "-server", "127.0.0.1", "-port", "9995", "-count", "10"] + command: ["--help"] \ No newline at end of file