Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
15 changes: 9 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,43 @@
# ---------------------------------------------------------------------------
# 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

# Cache dependency resolution layer separately from source code.
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

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.
18 changes: 18 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -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"]