diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml new file mode 100644 index 0000000000..54afebe676 --- /dev/null +++ b/.github/workflows/scan.yml @@ -0,0 +1,42 @@ +name: Voting App Build & Scan + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +jobs: + build-and-scan: + runs-on: ubuntu-latest + + env: + SYS_DIG_SECURE_URL: https://app.au1.sysdig.com + + steps: + - name: Checkout source + uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Log in to DockerHub (optional) + if: ${{ secrets.DOCKERHUB_USERNAME && secrets.DOCKERHUB_TOKEN }} + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build Voting App images + run: | + docker build -t voting-app ./vote + docker build -t worker ./worker + docker build -t result ./result + + - name: Scan image with Sysdig CLI Scanner + env: + SECURE_API_TOKEN: ${{ secrets.SECURE_API_TOKEN }} + run: | + docker run --rm --platform linux/amd64 --user 0 -v "$(pwd)/scan-logs:/home/nonroot/scan-logs" -v /var/run/docker.sock:/var/run/docker.sock -e SECURE_API_TOKEN="${{ secrets.SECURE_API_TOKEN }}" quay.io/sysdig/sysdig-cli-scanner:1.22.4 --apiurl "$SYS_DIG_SECURE_URL" --loglevel info --skiptlsverify docker://voting-app + diff --git a/k8s-specifications/db-deployment.yaml b/k8s-specifications/db-deployment.yaml index bc94ca7368..dde2f3f658 100644 --- a/k8s-specifications/db-deployment.yaml +++ b/k8s-specifications/db-deployment.yaml @@ -1,8 +1,6 @@ apiVersion: apps/v1 kind: Deployment metadata: - labels: - app: db name: db spec: replicas: 1 @@ -14,20 +12,33 @@ spec: labels: app: db spec: + serviceAccountName: default containers: - - image: postgres:15-alpine - name: postgres - env: - - name: POSTGRES_USER - value: postgres - - name: POSTGRES_PASSWORD - value: postgres - ports: - - containerPort: 5432 - name: postgres - volumeMounts: - - mountPath: /var/lib/postgresql/data - name: db-data - volumes: - - name: db-data - emptyDir: {} + - name: postgres + image: postgres:15 + securityContext: + runAsUser: 1000 + runAsNonRoot: true + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "500m" + memory: "256Mi" + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 diff --git a/k8s-specifications/redis-deployment.yaml b/k8s-specifications/redis-deployment.yaml index 24aa52135f..a985c681a2 100644 --- a/k8s-specifications/redis-deployment.yaml +++ b/k8s-specifications/redis-deployment.yaml @@ -1,8 +1,6 @@ apiVersion: apps/v1 kind: Deployment metadata: - labels: - app: redis name: redis spec: replicas: 1 @@ -14,15 +12,33 @@ spec: labels: app: redis spec: + serviceAccountName: default containers: - - image: redis:alpine - name: redis - ports: - - containerPort: 6379 - name: redis - volumeMounts: - - mountPath: /data - name: redis-data - volumes: - - name: redis-data - emptyDir: {} + - name: redis + image: redis:7 + securityContext: + runAsUser: 1000 + runAsNonRoot: true + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "500m" + memory: "256Mi" + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 diff --git a/k8s-specifications/result-deployment.yaml b/k8s-specifications/result-deployment.yaml index b85488a667..6428795f83 100644 --- a/k8s-specifications/result-deployment.yaml +++ b/k8s-specifications/result-deployment.yaml @@ -1,8 +1,6 @@ apiVersion: apps/v1 kind: Deployment metadata: - labels: - app: result name: result spec: replicas: 1 @@ -14,9 +12,33 @@ spec: labels: app: result spec: + serviceAccountName: default containers: - - image: dockersamples/examplevotingapp_result - name: result - ports: - - containerPort: 80 - name: result + - name: result + image: dockersamples/examplevotingapp_result + securityContext: + runAsUser: 1000 + runAsNonRoot: true + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "500m" + memory: "256Mi" + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 diff --git a/k8s-specifications/vote-deployment.yaml b/k8s-specifications/vote-deployment.yaml index 165a9478f8..018a458d75 100644 --- a/k8s-specifications/vote-deployment.yaml +++ b/k8s-specifications/vote-deployment.yaml @@ -1,8 +1,6 @@ apiVersion: apps/v1 kind: Deployment metadata: - labels: - app: vote name: vote spec: replicas: 1 @@ -14,9 +12,33 @@ spec: labels: app: vote spec: + serviceAccountName: default containers: - - image: dockersamples/examplevotingapp_vote - name: vote - ports: - - containerPort: 80 - name: vote + - name: vote + image: dockersamples/examplevotingapp_vote + securityContext: + runAsUser: 1000 + runAsNonRoot: true + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "500m" + memory: "256Mi" + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 diff --git a/k8s-specifications/worker-deployment.yaml b/k8s-specifications/worker-deployment.yaml index 9e35450aec..bc2aa4498d 100644 --- a/k8s-specifications/worker-deployment.yaml +++ b/k8s-specifications/worker-deployment.yaml @@ -1,8 +1,6 @@ apiVersion: apps/v1 kind: Deployment metadata: - labels: - app: worker name: worker spec: replicas: 1 @@ -14,6 +12,33 @@ spec: labels: app: worker spec: + serviceAccountName: default containers: - - image: dockersamples/examplevotingapp_worker - name: worker + - name: worker + image: worker + securityContext: + runAsUser: 1000 + runAsNonRoot: true + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "500m" + memory: "256Mi" + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5