Skip to content

Instantly share code, notes, and snippets.

@williamzujkowski
Created November 17, 2025 04:44
Show Gist options
  • Select an option

  • Save williamzujkowski/a0028efcfc85ff65b88122df2a34b2c8 to your computer and use it in GitHub Desktop.

Select an option

Save williamzujkowski/a0028efcfc85ff65b88122df2a34b2c8 to your computer and use it in GitHub Desktop.
NodeShield Docker deployment configuration with CBOM enforcement
#!/bin/bash
# NodeShield Docker Deployment Stack
# Complete setup for homelab CBOM enforcement testing
# Tested on: Ubuntu 24.04, Docker 24.0.7, NodeShield 1.2.0
set -euo pipefail
# Configuration
API_DIR="./my-api"
NODESHIELD_VERSION="1.2.0"
NODE_VERSION="20-alpine"
echo "[1/5] Creating NodeShield-enabled Dockerfile..."
cat > "${API_DIR}/Dockerfile" <<'EOF'
FROM node:20-alpine
# Install NodeShield runtime
RUN apk add --no-cache curl && \
npm install -g @nodeshield/runtime@1.2.0 && \
apk del curl
WORKDIR /app
# Copy application files
COPY package*.json ./
RUN npm ci --only=production
COPY . .
# NodeShield configuration
ENV NODE_OPTIONS="--require @nodeshield/runtime/hook"
ENV CBOM_POLICY="/app/cbom.yaml"
ENV CBOM_ENFORCE="true"
ENV CBOM_LOG_LEVEL="warn"
# Non-root user for security
RUN addgroup -g 1001 nodeapp && \
adduser -D -u 1001 -G nodeapp nodeapp && \
chown -R nodeapp:nodeapp /app
USER nodeapp
EXPOSE 3000
CMD ["node", "server.js"]
EOF
echo "[2/5] Creating Docker Compose orchestration..."
cat > "${API_DIR}/docker-compose.yml" <<'EOF'
version: '3.8'
services:
api:
build:
context: .
dockerfile: Dockerfile
container_name: nodeshield-api
ports:
- "3000:3000"
environment:
NODE_ENV: production
CBOM_ENFORCE: "true"
CBOM_LOG_LEVEL: "warn"
CBOM_AUDIT_PATH: "/app/logs/violations.log"
volumes:
- ./logs:/app/logs
- ./cbom.yaml:/app/cbom.yaml:ro
restart: unless-stopped
networks:
- nodeshield-net
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
nodeshield-net:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
EOF
echo "[3/5] Generating network isolation rules..."
cat > "${API_DIR}/network-policy.yml" <<'EOF'
# Docker network policy for NodeShield isolation
# Prevents lateral movement and egress restrictions
services:
api:
networks:
nodeshield-net:
ipv4_address: 172.28.0.10
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE # Allow port 3000 binding
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp:noexec,nosuid,size=100m
EOF
echo "[4/5] Creating audit logging configuration..."
mkdir -p "${API_DIR}/logs"
cat > "${API_DIR}/logs/violations.log" <<'EOF'
# NodeShield Violation Audit Log
# Format: [TIMESTAMP] SEVERITY MODULE CAPABILITY ACTION
# Auto-rotated daily, retained 30 days
EOF
echo "[5/5] Creating startup script..."
cat > "${API_DIR}/start.sh" <<'EOF'
#!/bin/sh
# NodeShield service startup with validation
set -e
# Validate CBOM policy exists
if [ ! -f /app/cbom.yaml ]; then
echo "ERROR: CBOM policy not found at /app/cbom.yaml"
exit 1
fi
# Validate NodeShield runtime loaded
if ! node --require @nodeshield/runtime/hook --eval "console.log('NodeShield loaded')" > /dev/null 2>&1; then
echo "ERROR: NodeShield runtime failed to load"
exit 1
fi
# Start application with NodeShield enforcement
echo "Starting NodeShield-protected API..."
exec node server.js
EOF
chmod +x "${API_DIR}/start.sh"
echo ""
echo "✅ NodeShield Docker stack created successfully!"
echo ""
echo "Next steps:"
echo " 1. Generate SBOM: syft scan dir:${API_DIR} -o cyclonedx-json > sbom.json"
echo " 2. Create CBOM: nodeshield outline --sbom sbom.json --output cbom.yaml"
echo " 3. Review policies manually (focus on network/exec/filesystem)"
echo " 4. Build image: docker-compose build"
echo " 5. Start stack: docker-compose up -d"
echo " 6. Check logs: docker logs -f nodeshield-api"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment