8 Commits
0.2.1 ... main

Author SHA1 Message Date
a220e5de99 Add Docker Hub authentication for Scout scans
Some checks failed
Migration Safety / Alembic upgrade/downgrade safety (push) Successful in 22s
PostgreSQL Compatibility Matrix / PG14 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG15 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG16 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG17 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG18 smoke (push) Successful in 8s
Container CVE Scan (development) / Scan backend/frontend images for CVEs (push) Failing after 1m53s
This update ensures Docker Scout scans use Docker Hub authentication. If the required credentials are absent, the scans are skipped with a corresponding message. This improves security and prevents unnecessary scan failures.
2026-02-14 18:31:10 +01:00
a5ffafaf9e Update CVE scanning workflow to use JSON format and new tools
All checks were successful
Container CVE Scan (development) / Scan backend/frontend images for CVEs (push) Successful in 2m9s
PostgreSQL Compatibility Matrix / PG14 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG15 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG16 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG17 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG18 smoke (push) Successful in 7s
Replaced Trivy output format from table to JSON for better processing. Added a summary step to parse and count severities using a Python script. Integrated Docker Scout scans for both backend and frontend, and updated uploaded artifacts to include the new JSON and Scout scan outputs.
2026-02-14 18:24:08 +01:00
d17752b611 Add CVE scan workflow for development branch
Some checks failed
Container CVE Scan (development) / Scan backend/frontend images for CVEs (push) Failing after 2m20s
PostgreSQL Compatibility Matrix / PG14 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG15 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG16 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG17 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG18 smoke (push) Successful in 7s
This commit introduces a GitHub Actions workflow to scan for CVEs in backend and frontend container images. It uses Trivy for scanning and uploads the reports as artifacts, providing better visibility into vulnerabilities in development builds.
2026-02-14 18:16:54 +01:00
fe05c40426 Merge branch 'main' of https://git.nesterovic.cc/nessi/NexaPG into development
All checks were successful
PostgreSQL Compatibility Matrix / PG14 smoke (push) Successful in 10s
PostgreSQL Compatibility Matrix / PG15 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG16 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG17 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG18 smoke (push) Successful in 8s
2026-02-14 17:47:34 +01:00
5a0478f47d harden(frontend): switch to nginx:alpine-slim with non-root runtime and nginx dir permission fixes 2026-02-14 17:47:26 +01:00
1cea82f5d9 Merge pull request 'Update frontend to use unprivileged Nginx on port 8080' (#34) from development into main
All checks were successful
Migration Safety / Alembic upgrade/downgrade safety (push) Successful in 21s
PostgreSQL Compatibility Matrix / PG14 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG15 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG16 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG17 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG18 smoke (push) Successful in 8s
Docker Publish (Release) / Build and Push Docker Images (release) Successful in 1m33s
Reviewed-on: #34
2026-02-14 16:18:34 +00:00
418034f639 Update NEXAPG_VERSION to 0.2.2
All checks were successful
PostgreSQL Compatibility Matrix / PG14 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG15 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG16 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG17 smoke (push) Successful in 7s
PostgreSQL Compatibility Matrix / PG18 smoke (push) Successful in 7s
Migration Safety / Alembic upgrade/downgrade safety (pull_request) Successful in 23s
PostgreSQL Compatibility Matrix / PG14 smoke (pull_request) Successful in 8s
PostgreSQL Compatibility Matrix / PG15 smoke (pull_request) Successful in 7s
PostgreSQL Compatibility Matrix / PG16 smoke (pull_request) Successful in 7s
PostgreSQL Compatibility Matrix / PG17 smoke (pull_request) Successful in 8s
PostgreSQL Compatibility Matrix / PG18 smoke (pull_request) Successful in 8s
Bumped the version from 0.2.1 to 0.2.2 in the configuration file. This likely reflects a new release or minor update to the application.
2026-02-14 17:17:57 +01:00
489dde812f Update frontend to use unprivileged Nginx on port 8080
All checks were successful
PostgreSQL Compatibility Matrix / PG14 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG15 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG16 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG17 smoke (push) Successful in 8s
PostgreSQL Compatibility Matrix / PG18 smoke (push) Successful in 8s
Switch from `nginx:1.29-alpine-slim` to `nginxinc/nginx-unprivileged:stable-alpine` for improved security by running as a non-root user. Changed the exposed port from 80 to 8080 in the configurations to reflect the unprivileged setup. Adjusted the `docker-compose.yml` and `nginx.conf` accordingly.
2026-02-14 17:13:18 +01:00
5 changed files with 146 additions and 6 deletions

View File

@@ -0,0 +1,137 @@
name: Container CVE Scan (development)
on:
push:
branches: ["development"]
workflow_dispatch:
jobs:
cve-scan:
name: Scan backend/frontend images for CVEs
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker Hub login (for Scout)
if: ${{ secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build backend image (local)
uses: docker/build-push-action@v6
with:
context: ./backend
file: ./backend/Dockerfile
push: false
load: true
tags: nexapg-backend:dev-scan
provenance: false
sbom: false
- name: Build frontend image (local)
uses: docker/build-push-action@v6
with:
context: ./frontend
file: ./frontend/Dockerfile
push: false
load: true
tags: nexapg-frontend:dev-scan
build-args: |
VITE_API_URL=/api/v1
provenance: false
sbom: false
- name: Trivy scan (backend)
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: nexapg-backend:dev-scan
format: json
output: trivy-backend.json
severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
ignore-unfixed: false
exit-code: 0
- name: Trivy scan (frontend)
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: nexapg-frontend:dev-scan
format: json
output: trivy-frontend.json
severity: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
ignore-unfixed: false
exit-code: 0
- name: Summarize Trivy severities
run: |
python - <<'PY'
import json
from collections import Counter
def summarize(path):
c = Counter()
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
for result in data.get("Results", []):
for v in result.get("Vulnerabilities", []) or []:
c[v.get("Severity", "UNKNOWN")] += 1
for sev in ["CRITICAL", "HIGH", "MEDIUM", "LOW", "UNKNOWN"]:
c.setdefault(sev, 0)
return c
for label, path in [("backend", "trivy-backend.json"), ("frontend", "trivy-frontend.json")]:
s = summarize(path)
print(f"===== Trivy {label} =====")
print(f"CRITICAL={s['CRITICAL']} HIGH={s['HIGH']} MEDIUM={s['MEDIUM']} LOW={s['LOW']} UNKNOWN={s['UNKNOWN']}")
print()
PY
- name: Docker Scout scan (backend)
run: |
if [ -z "${{ secrets.DOCKERHUB_USERNAME }}" ] || [ -z "${{ secrets.DOCKERHUB_TOKEN }}" ]; then
echo "Docker Hub Scout scan skipped: DOCKERHUB_USERNAME/DOCKERHUB_TOKEN not set." > scout-backend.txt
exit 0
fi
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DOCKER_SCOUT_HUB_USER="${{ secrets.DOCKERHUB_USERNAME }}" \
-e DOCKER_SCOUT_HUB_PAT="${{ secrets.DOCKERHUB_TOKEN }}" \
docker/scout-cli:latest cves nexapg-backend:dev-scan \
--only-severity critical,high,medium,low > scout-backend.txt
- name: Docker Scout scan (frontend)
run: |
if [ -z "${{ secrets.DOCKERHUB_USERNAME }}" ] || [ -z "${{ secrets.DOCKERHUB_TOKEN }}" ]; then
echo "Docker Hub Scout scan skipped: DOCKERHUB_USERNAME/DOCKERHUB_TOKEN not set." > scout-frontend.txt
exit 0
fi
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DOCKER_SCOUT_HUB_USER="${{ secrets.DOCKERHUB_USERNAME }}" \
-e DOCKER_SCOUT_HUB_PAT="${{ secrets.DOCKERHUB_TOKEN }}" \
docker/scout-cli:latest cves nexapg-frontend:dev-scan \
--only-severity critical,high,medium,low > scout-frontend.txt
- name: Print scan summary
run: |
echo "===== Docker Scout backend ====="
test -f scout-backend.txt && cat scout-backend.txt || echo "scout-backend.txt not available"
echo
echo "===== Docker Scout frontend ====="
test -f scout-frontend.txt && cat scout-frontend.txt || echo "scout-frontend.txt not available"
- name: Upload scan reports
uses: actions/upload-artifact@v3
with:
name: container-cve-scan-reports
path: |
trivy-backend.json
trivy-frontend.json
scout-backend.txt
scout-frontend.txt

View File

@@ -2,7 +2,7 @@ from functools import lru_cache
from pydantic import field_validator from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
NEXAPG_VERSION = "0.2.1" NEXAPG_VERSION = "0.2.2"
class Settings(BaseSettings): class Settings(BaseSettings):

View File

@@ -54,7 +54,7 @@ services:
depends_on: depends_on:
- backend - backend
ports: ports:
- "${FRONTEND_PORT}:80" - "${FRONTEND_PORT}:8080"
volumes: volumes:
pg_data: pg_data:

View File

@@ -7,9 +7,12 @@ ARG VITE_API_URL=/api/v1
ENV VITE_API_URL=${VITE_API_URL} ENV VITE_API_URL=${VITE_API_URL}
RUN npm run build RUN npm run build
FROM nginx:1.29-alpine-slim FROM nginx:1-alpine-slim
RUN apk upgrade --no-cache RUN apk upgrade --no-cache \
&& mkdir -p /var/cache/nginx /var/run /var/log/nginx /tmp/nginx \
&& chown -R nginx:nginx /var/cache/nginx /var/run /var/log/nginx /tmp/nginx
COPY nginx.conf /etc/nginx/conf.d/default.conf COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80 USER 101
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --retries=5 CMD nginx -t || exit 1 HEALTHCHECK --interval=30s --timeout=3s --retries=5 CMD nginx -t || exit 1

View File

@@ -1,5 +1,5 @@
server { server {
listen 80; listen 8080;
server_name _; server_name _;
root /usr/share/nginx/html; root /usr/share/nginx/html;