diff --git a/Dockerfile b/Dockerfile index 432bff7..7360b18 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,16 +6,20 @@ RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certifi COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/ WORKDIR /app + COPY pyproject.toml ./ -COPY guarddog_nexus/ guarddog_nexus/ +RUN uv pip install --system fastapi uvicorn[standard] jinja2 httpx \ + "sqlalchemy[asyncio]" aiosqlite python-multipart RUN uv pip install --system guarddog -RUN uv pip install --system -e . + +COPY guarddog_nexus/ guarddog_nexus/ RUN mkdir -p /data /tmp/guarddog-nexus ENV DATABASE_PATH=/data/guarddog.db ENV TEMP_DIR=/tmp/guarddog-nexus +ENV PYTHONDONTWRITEBYTECODE=1 EXPOSE 8080 diff --git a/scripts/setup-nexus.sh b/scripts/setup-nexus.sh index 46abcbb..2f6f0a8 100644 --- a/scripts/setup-nexus.sh +++ b/scripts/setup-nexus.sh @@ -1,19 +1,18 @@ #!/bin/sh -# Setup script for test Nexus instance. -# Creates a PyPI proxy repo and a webhook pointing to guarddog-nexus. +set -e NEXUS_URL="${NEXUS_URL:-http://nexus:8081}" ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin123}" WEBHOOK_URL="${WEBHOOK_URL:-http://guarddog-nexus:8080/webhooks/nexus}" -echo "Waiting for Nexus to start..." +apk add --no-cache curl >/dev/null 2>&1 || true -# Wait until Nexus REST API is available (up to 5 minutes) +echo "Waiting for Nexus to start..." MAX_WAIT=300 ELAPSED=0 while [ $ELAPSED -lt $MAX_WAIT ]; do if curl -sf -o /dev/null "${NEXUS_URL}/service/rest/v1/status" 2>/dev/null; then - echo "Nexus is up!" + echo "Nexus is up." break fi sleep 5 @@ -21,53 +20,64 @@ while [ $ELAPSED -lt $MAX_WAIT ]; do done if [ $ELAPSED -ge $MAX_WAIT ]; then - echo "Timed out waiting for Nexus" + echo "Timed out waiting for Nexus" >&2 exit 1 fi -# Check if password needs changing (first run) -ADMIN_PASSWORD_FILE="/nexus-data/admin.password" -if [ -f "$ADMIN_PASSWORD_FILE" ]; then - RANDOM_PASS=$(cat "$ADMIN_PASSWORD_FILE") - echo "Using random admin password: $RANDOM_PASS" - AUTH_PASS="$RANDOM_PASS" -else - AUTH_PASS="$ADMIN_PASSWORD" +AUTH_PASS="$ADMIN_PASSWORD" +if [ -f /nexus-data/admin.password ]; then + AUTH_PASS=$(cat /nexus-data/admin.password) + echo "Using initial admin password from volume" fi echo "Creating PyPI proxy repository..." curl -sf -u "admin:${AUTH_PASS}" \ -H "Content-Type: application/json" \ - -d '{ - "name": "pypi-proxy", - "online": true, - "storage": {"blobStoreName": "default", "strictContentTypeValidation": true}, - "proxy": {"remoteUrl": "https://pypi.org", "contentMaxAge": 1440}, - "format": "pypi" - }' \ - "${NEXUS_URL}/service/rest/v1/repositories/pypi/proxy" || echo "Repo may already exist" - -echo "Creating webhook..." -curl -sf -u "admin:${AUTH_PASS}" \ - -H "Content-Type: application/json" \ + -X POST \ -d "{ - \"name\": \"guarddog-scan\", - \"eventTypes\": [\"repository.component\", \"repository.asset\"], - \"format\": \"pypi\", - \"url\": \"${WEBHOOK_URL}\", - \"secret\": \"\", - \"enabled\": true + \"name\": \"pypi-proxy\", + \"online\": true, + \"storage\": { + \"blobStoreName\": \"default\", + \"strictContentTypeValidation\": true + }, + \"proxy\": { + \"remoteUrl\": \"https://pypi.org\", + \"contentMaxAge\": 1440, + \"metadataMaxAge\": 1440 + }, + \"negativeCache\": { + \"enabled\": true, + \"timeToLive\": 1440 + }, + \"httpClient\": { + \"blocked\": false, + \"autoBlock\": true, + \"connection\": { + \"timeout\": 60, + \"retries\": 3 + } + } }" \ - "${NEXUS_URL}/service/rest/v1/webhooks" || echo "Webhook may already exist" + "${NEXUS_URL}/service/rest/v1/repositories/pypi/proxy" 2>/dev/null || \ + echo "Proxy repo may already exist, continuing..." -# Change admin password if this was first run -if [ -f "$ADMIN_PASSWORD_FILE" ]; then - echo "Changing admin password..." - curl -sf -u "admin:${RANDOM_PASS}" \ +echo "" +echo "NOTE: Webhook setup is not available in Nexus OSS/Community edition." +echo "In Nexus Pro, configure:" +echo " Capability: Webhook: Repository" +echo " URL: ${WEBHOOK_URL}" +echo " Event types: repository.component, repository.asset" +echo " Repository filter: pypi-proxy" +echo "" + +if [ -f /nexus-data/admin.password ]; then + echo "Changing default admin password..." + curl -sf -u "admin:${AUTH_PASS}" \ -H "Content-Type: text/plain" \ -X PUT \ -d "${ADMIN_PASSWORD}" \ - "${NEXUS_URL}/service/rest/v1/security/users/admin/change-password" + "${NEXUS_URL}/service/rest/v1/security/users/admin/change-password" 2>/dev/null || true fi echo "Nexus setup complete."