diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e3e01a4..8a4bb09f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,13 +16,16 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Set up Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: ${{ env.PYTHON_VERSION }} + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libldap2-dev libsasl2-dev + - name: Install dependencies for coverage run: | cd dns-server && pip install -r requirements.txt pytest pytest-cov @@ -35,7 +38,7 @@ jobs: --cov-fail-under=98 -v --tb=short || true - name: Upload coverage to Codecov - uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4 + uses: codecov/codecov-action@3f20e214133d0983f9a10f3d63b0faf9241a3daa # v6 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.xml @@ -55,7 +58,7 @@ jobs: needs: build-and-test steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Build unified Docker image - DNS Server run: | @@ -84,10 +87,10 @@ jobs: contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Set up Python for bandit - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index a3b3f3b2..76cfb420 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -9,49 +9,113 @@ env: REPO: squawk jobs: - push_to_registries: - name: Push Docker image to multiple registries + build-platform: + name: Build Docker image for ${{ matrix.platform }} runs-on: ubuntu-latest + strategy: + matrix: + platform: [linux/amd64, linux/arm64] permissions: packages: write contents: read steps: - name: Check out the repo - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + + - name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9b11de45568b7b44d28e85c0b8e7 # v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@b5ca514318bd6ebba01cdb9b2d9a7ac3b0c11b09 # v3 - name: Log in to Docker Hub - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf5ca # v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Log in to the Container registry - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf5ca # v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 - with: - images: | - penguintechinc/${{ env.REPO }} - ghcr.io/${{ github.repository }} + - name: Extract platform tag + id: platform_tag + run: | + PLATFORM_TAG=$(echo ${{ matrix.platform }} | sed 's/linux\///') + echo "tag=$PLATFORM_TAG" >> $GITHUB_OUTPUT - - name: Build and push Docker images - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + - name: Build Docker image for ${{ matrix.platform }} + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . + platforms: ${{ matrix.platform }} push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + tags: | + penguintechinc/${{ env.REPO }}:cron-${{ steps.platform_tag.outputs.tag }} + ghcr.io/${{ github.repository }}:cron-${{ steps.platform_tag.outputs.tag }} + cache-from: type=gha,scope=${{ matrix.platform }} + cache-to: type=gha,mode=max,scope=${{ matrix.platform }} - - name: Build and push Docker images to static tags - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + - name: Build Docker image with static tags for ${{ matrix.platform }} + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . + platforms: ${{ matrix.platform }} push: true - tags: ghcr.io/penguintechinc/${{ env.REPO }}:latest, ghcr.io/penguintechinc/${{ env.REPO }}:nightly, penguintechinc/${{ env.REPO }}:latest - labels: ${{ steps.meta.outputs.labels }} + tags: | + ghcr.io/penguintechinc/${{ env.REPO }}:latest-${{ steps.platform_tag.outputs.tag }} + ghcr.io/penguintechinc/${{ env.REPO }}:nightly-${{ steps.platform_tag.outputs.tag }} + penguintechinc/${{ env.REPO }}:latest-${{ steps.platform_tag.outputs.tag }} + cache-from: type=gha,scope=${{ matrix.platform }} + cache-to: type=gha,mode=max,scope=${{ matrix.platform }} + + merge-manifests: + name: Merge Docker manifests + runs-on: ubuntu-latest + needs: build-platform + permissions: + packages: write + contents: read + steps: + - name: Check out the repo + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + + - name: Log in to Docker Hub + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf5ca # v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Log in to the Container registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf5ca # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@b5ca514318bd6ebba01cdb9b2d9a7ac3b0c11b09 # v3 + + - name: Merge manifests for cron tags + run: | + docker buildx imagetools create -t penguintechinc/${{ env.REPO }}:cron \ + penguintechinc/${{ env.REPO }}:cron-amd64 \ + penguintechinc/${{ env.REPO }}:cron-arm64 + docker buildx imagetools create -t ghcr.io/${{ github.repository }}:cron \ + ghcr.io/${{ github.repository }}:cron-amd64 \ + ghcr.io/${{ github.repository }}:cron-arm64 + + - name: Merge manifests for latest/nightly tags + run: | + docker buildx imagetools create -t ghcr.io/penguintechinc/${{ env.REPO }}:latest \ + ghcr.io/penguintechinc/${{ env.REPO }}:latest-amd64 \ + ghcr.io/penguintechinc/${{ env.REPO }}:latest-arm64 + docker buildx imagetools create -t ghcr.io/penguintechinc/${{ env.REPO }}:nightly \ + ghcr.io/penguintechinc/${{ env.REPO }}:nightly-amd64 \ + ghcr.io/penguintechinc/${{ env.REPO }}:nightly-arm64 + docker buildx imagetools create -t penguintechinc/${{ env.REPO }}:latest \ + penguintechinc/${{ env.REPO }}:latest-amd64 \ + penguintechinc/${{ env.REPO }}:latest-arm64 diff --git a/.github/workflows/go-client-release.yml b/.github/workflows/go-client-release.yml index 40320b40..77bafb0a 100644 --- a/.github/workflows/go-client-release.yml +++ b/.github/workflows/go-client-release.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Set up Go uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 @@ -61,17 +61,21 @@ jobs: make security # Build and release job - triggered by version tags - build-and-release: - name: Build and Release Go Client + build-platform: + name: Build Go Client (${{ matrix.platform }}) runs-on: ubuntu-latest needs: test if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') permissions: contents: write packages: write + strategy: + matrix: + platform: [linux/amd64, linux/arm64] + steps: - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 @@ -84,132 +88,241 @@ jobs: echo "VERSION=$VERSION" >> $GITHUB_OUTPUT echo "BINARY_NAME=squawk" >> $GITHUB_OUTPUT - - name: Set up Go - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 - with: - go-version: ${{ env.GO_VERSION }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@b5ca514318bd6ebba01cdb9b2d9a7ac3b0c11b09 # v3 - # Build for all platforms using containerized approach (Debian) - - name: Build All Platforms (Containerized) + - name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9b11de45568b7b44d28e85c0b8e7 # v3 + + - name: Build Go binary for platform working-directory: dns-client-go + env: + PLATFORM: ${{ matrix.platform }} + BINARY_NAME: squawk + APP_NAME: squawk-dns-client + GO_VERSION: '1.24.2' run: | docker run --rm -v $(pwd):/workspace -w /workspace \ + --platform ${{ matrix.platform }} \ golang:${{ env.GO_VERSION }}-bookworm \ sh -c ' apt-get update && apt-get install -y --no-install-recommends git - - echo "Building ${{ steps.version.outputs.BINARY_NAME }} for all platforms..." - - VERSION="${{ steps.version.outputs.VERSION }}" - BINARY_NAME="${{ steps.version.outputs.BINARY_NAME }}" - - # Linux AMD64 - mkdir -p build/linux-amd64 - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ - -ldflags "-X main.version=$VERSION -X main.buildTime=$(date -u +%Y-%m-%d_%H:%M:%S) -X main.gitCommit=${{ github.sha }}" \ - -o build/linux-amd64/$BINARY_NAME \ - ./cmd/${{ env.APP_NAME }} - - # Linux ARM64 - mkdir -p build/linux-arm64 - CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build \ - -ldflags "-X main.version=$VERSION -X main.buildTime=$(date -u +%Y-%m-%d_%H:%M:%S) -X main.gitCommit=${{ github.sha }}" \ - -o build/linux-arm64/$BINARY_NAME \ - ./cmd/${{ env.APP_NAME }} - - # macOS AMD64 - mkdir -p build/darwin-amd64 - CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build \ - -ldflags "-X main.version=$VERSION -X main.buildTime=$(date -u +%Y-%m-%d_%H:%M:%S) -X main.gitCommit=${{ github.sha }}" \ - -o build/darwin-amd64/$BINARY_NAME \ - ./cmd/${{ env.APP_NAME }} - - # macOS ARM64 (Apple Silicon) - mkdir -p build/darwin-arm64 - CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build \ - -ldflags "-X main.version=$VERSION -X main.buildTime=$(date -u +%Y-%m-%d_%H:%M:%S) -X main.gitCommit=${{ github.sha }}" \ - -o build/darwin-arm64/$BINARY_NAME \ - ./cmd/${{ env.APP_NAME }} - - # Windows AMD64 - mkdir -p build/windows-amd64 - CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build \ - -ldflags "-X main.version=$VERSION -X main.buildTime=$(date -u +%Y-%m-%d_%H:%M:%S) -X main.gitCommit=${{ github.sha }}" \ - -o build/windows-amd64/$BINARY_NAME.exe \ - ./cmd/${{ env.APP_NAME }} - # Windows ARM64 - mkdir -p build/windows-arm64 - CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build \ - -ldflags "-X main.version=$VERSION -X main.buildTime=$(date -u +%Y-%m-%d_%H:%M:%S) -X main.gitCommit=${{ github.sha }}" \ - -o build/windows-arm64/$BINARY_NAME.exe \ + ARCH=$(echo "${{ matrix.platform }}" | cut -d/ -f2) + mkdir -p build/$ARCH + CGO_ENABLED=0 GOOS=linux GOARCH=$ARCH go build \ + -ldflags "-X main.version=${{ steps.version.outputs.VERSION }} -X main.buildTime=$(date -u +%Y-%m-%d_%H:%M:%S) -X main.gitCommit=${{ github.sha }}" \ + -o build/$ARCH/${{ steps.version.outputs.BINARY_NAME }} \ ./cmd/${{ env.APP_NAME }} - echo "Build completed for all platforms" - find build -name "*$BINARY_NAME*" -type f -exec ls -la {} \; + ls -la build/$ARCH/${{ steps.version.outputs.BINARY_NAME }} ' - # Create release packages - - name: Create Release Packages - working-directory: dns-client-go + - name: Upload binary artifacts + uses: actions/upload-artifact@v4 + with: + name: binaries-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }} + path: dns-client-go/build/ + + build-docker-platform: + name: Build Docker Image (${{ matrix.platform }}) + runs-on: ubuntu-latest + needs: test + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + packages: write + strategy: + matrix: + platform: [linux/amd64, linux/arm64] + + steps: + - name: Checkout code + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + with: + fetch-depth: 0 + + - name: Extract version from tag + id: version + env: + TAG: ${{ github.ref }} run: | - mkdir -p build/packages - BINARY_NAME="${{ steps.version.outputs.BINARY_NAME }}" - VERSION="${{ steps.version.outputs.VERSION }}" - - # Create release archives - cd build/linux-amd64 && tar -czf ../packages/squawk-$VERSION-linux-amd64.tar.gz $BINARY_NAME - cd ../linux-arm64 && tar -czf ../packages/squawk-$VERSION-linux-arm64.tar.gz $BINARY_NAME - cd ../darwin-amd64 && tar -czf ../packages/squawk-$VERSION-darwin-amd64.tar.gz $BINARY_NAME - cd ../darwin-arm64 && tar -czf ../packages/squawk-$VERSION-darwin-arm64.tar.gz $BINARY_NAME - cd ../windows-amd64 && zip -q ../packages/squawk-$VERSION-windows-amd64.zip $BINARY_NAME.exe - cd ../windows-arm64 && zip -q ../packages/squawk-$VERSION-windows-arm64.zip $BINARY_NAME.exe - - # Generate checksums - cd ../packages - sha256sum * > SHA256SUMS + VERSION=${TAG#refs/tags/v} + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + echo "BINARY_NAME=squawk" >> $GITHUB_OUTPUT - # Docker build and push for releases - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + uses: docker/setup-buildx-action@b5ca514318bd6ebba01cdb9b2d9a7ac3b0c11b09 # v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9b11de45568b7b44d28e85c0b8e7 # v3 - name: Log in to GitHub Container Registry - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf5ca # v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - # Build and push Docker image - - name: Build and push Docker image - uses: docker/build-push-action@v5 + - name: Build and push Docker image (per platform) + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 + env: + VERSION: ${{ steps.version.outputs.VERSION }} + BINARY_NAME: ${{ steps.version.outputs.BINARY_NAME }} + APP_NAME: squawk-dns-client with: context: dns-client-go - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platform }} push: true build-args: | - VERSION=${{ steps.version.outputs.VERSION }} + VERSION=${{ env.VERSION }} BUILD_TIME=$(date -u +%Y-%m-%d_%H:%M:%S) GIT_COMMIT=${{ github.sha }} - BINARY_NAME=${{ steps.version.outputs.BINARY_NAME }} + BINARY_NAME=${{ env.BINARY_NAME }} tags: | - ghcr.io/penguintechinc/${{ env.APP_NAME }}:${{ steps.version.outputs.VERSION }} - ghcr.io/penguintechinc/${{ env.APP_NAME }}:latest + ghcr.io/penguintechinc/${{ env.APP_NAME }}:${{ env.VERSION }}-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }} + ghcr.io/penguintechinc/${{ env.APP_NAME }}:latest-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }} labels: | org.opencontainers.image.title=Squawk DNS Client (Go) org.opencontainers.image.description=High-performance DNS-over-HTTPS client - org.opencontainers.image.version=${{ steps.version.outputs.VERSION }} + org.opencontainers.image.version=${{ env.VERSION }} org.opencontainers.image.source=https://github.com/${{ github.repository }} org.opencontainers.image.revision=${{ github.sha }} + cache-from: type=gha,scope=docker-${{ matrix.platform }} + cache-to: type=gha,mode=max,scope=docker-${{ matrix.platform }} + + merge-docker-manifests: + name: Merge Docker Manifests + runs-on: ubuntu-latest + needs: build-docker-platform + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + packages: write + + steps: + - name: Checkout code + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + with: + fetch-depth: 0 + + - name: Extract version from tag + id: version + env: + TAG: ${{ github.ref }} + run: | + VERSION=${TAG#refs/tags/v} + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + + - name: Log in to GitHub Container Registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf5ca # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@b5ca514318bd6ebba01cdb9b2d9a7ac3b0c11b09 # v3 + + - name: Merge Docker manifests + env: + APP_NAME: squawk-dns-client + VERSION: ${{ steps.version.outputs.VERSION }} + run: | + docker buildx imagetools create \ + -t ghcr.io/penguintechinc/$APP_NAME:$VERSION \ + ghcr.io/penguintechinc/$APP_NAME:$VERSION-amd64 \ + ghcr.io/penguintechinc/$APP_NAME:$VERSION-arm64 + + docker buildx imagetools create \ + -t ghcr.io/penguintechinc/$APP_NAME:latest \ + ghcr.io/penguintechinc/$APP_NAME:latest-amd64 \ + ghcr.io/penguintechinc/$APP_NAME:latest-arm64 + + package-release: + name: Package Release Assets + runs-on: ubuntu-latest + needs: build-platform + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + + steps: + - name: Checkout code + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + with: + fetch-depth: 0 + + - name: Extract version from tag + id: version + env: + TAG: ${{ github.ref }} + run: | + VERSION=${TAG#refs/tags/v} + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + echo "BINARY_NAME=squawk" >> $GITHUB_OUTPUT + + - name: Download all binary artifacts + uses: actions/download-artifact@v4 + + - name: Create Release Packages + env: + VERSION: ${{ steps.version.outputs.VERSION }} + BINARY_NAME: ${{ steps.version.outputs.BINARY_NAME }} + run: | + mkdir -p release/packages + + if [ -f "binaries-amd64/amd64/$BINARY_NAME" ]; then + tar -czf release/packages/squawk-$VERSION-linux-amd64.tar.gz -C binaries-amd64/amd64 $BINARY_NAME + fi + + if [ -f "binaries-arm64/arm64/$BINARY_NAME" ]; then + tar -czf release/packages/squawk-$VERSION-linux-arm64.tar.gz -C binaries-arm64/arm64 $BINARY_NAME + fi + + cd release/packages + sha256sum * > SHA256SUMS + + - name: Upload Release Assets + uses: actions/upload-artifact@v4 + with: + name: release-packages + path: release/packages/ + + create-release: + name: Create GitHub Release + runs-on: ubuntu-latest + needs: [merge-docker-manifests, package-release] + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + + steps: + - name: Checkout code + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + with: + fetch-depth: 0 + + - name: Extract version from tag + id: version + env: + TAG: ${{ github.ref }} + run: | + VERSION=${TAG#refs/tags/v} + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + + - name: Download release packages + uses: actions/download-artifact@v4 + with: + name: release-packages - # Create GitHub Release - name: Extract Release Notes run: | chmod +x .github/scripts/extract-release-notes.sh GITHUB_REPOSITORY="${{ github.repository }}" \ GITHUB_SHA="${{ github.sha }}" \ .github/scripts/extract-release-notes.sh client "${{ steps.version.outputs.VERSION }}" release_body.md - + - name: Create Release uses: actions/create-release@0cb9c9b65d5d1901c1f53e5e66eaf4afd303e70e # v1 id: create_release @@ -222,18 +335,19 @@ jobs: prerelease: false body_path: release_body.md - # Upload release assets - name: Upload Release Assets if: steps.create_release.outputs.upload_url - working-directory: dns-client-go/build/packages + env: + UPLOAD_URL: ${{ steps.create_release.outputs.upload_url }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - for file in *.tar.gz *.zip SHA256SUMS; do + for file in squawk-*.tar.gz SHA256SUMS; do if [ -f "$file" ]; then echo "Uploading $file..." - curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ + curl -H "Authorization: token $GITHUB_TOKEN" \ -H "Content-Type: application/octet-stream" \ --data-binary @"$file" \ - "${{ steps.create_release.outputs.upload_url }}?name=$file" + "$UPLOAD_URL?name=$file" fi done @@ -241,13 +355,15 @@ jobs: notify: name: Build Summary runs-on: ubuntu-latest - needs: [test, build-and-release] + needs: [test, create-release] if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') steps: - name: Build Summary + env: + REF: ${{ github.ref }} run: | echo "✅ Squawk DNS Client (Go) Build Complete!" - echo "Version: ${{ github.ref }}" - echo "Platforms: Linux (amd64, arm64), macOS (amd64, arm64), Windows (amd64, arm64)" - echo "Docker: ghcr.io/penguintechinc/squawk-dns-client:${{ github.ref }}" + echo "Version: $REF" + echo "Platforms: Linux (amd64, arm64)" + echo "Docker: ghcr.io/penguintechinc/squawk-dns-client:$REF" echo "Registry: ghcr.io/penguintechinc" diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 255c0a15..d06e8d29 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -9,23 +9,11 @@ env: IMAGE: ghcr.io/penguintechinc/squawk jobs: - build-and-push: - name: Build and push Docker image + generate-tag: runs-on: ubuntu-latest - permissions: - packages: write - contents: read + outputs: + tag: ${{ steps.tag.outputs.tag }} steps: - - name: Check out the repo - uses: actions/checkout@v4 - - - name: Log in to Container registry - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Generate tag id: tag env: @@ -41,19 +29,91 @@ jobs: fi echo "tag=${TAG}" >> $GITHUB_OUTPUT - - name: Extract metadata (tags, labels) for Docker + build: + needs: generate-tag + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + strategy: + fail-fast: false + matrix: + platform: + - linux/amd64 + - linux/arm64 + steps: + - name: Check out the repo + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + + - name: Log in to Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata id: meta uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: - images: | - ${{ env.IMAGE }} - tags: | - type=raw,value=${{ steps.tag.outputs.tag }} + images: ${{ env.IMAGE }} - - name: Build and push Docker images + - name: Build and push by digest + id: build uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: context: . - push: true - tags: ${{ steps.meta.outputs.tags }} + platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + echo "PLATFORM_PAIR=$(echo '${{ matrix.platform }}' | tr '/' '-')" >> $GITHUB_ENV + + - name: Upload digest + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: digest-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + needs: [generate-tag, build] + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - name: Download digests + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + path: /tmp/digests + pattern: digest-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + + - name: Log in to Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest and push + working-directory: /tmp/digests + env: + TAG: ${{ needs.generate-tag.outputs.tag }} + run: | + docker buildx imagetools create \ + --tag "${IMAGE}:${TAG}" \ + $(printf "${IMAGE}@sha256:%s " *) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c8350c96..52b151ea 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,15 +8,23 @@ env: IMAGE: ghcr.io/penguintechinc/squawk jobs: - build-and-push: - name: Build and push Docker image + build: runs-on: ubuntu-latest permissions: packages: write contents: read + strategy: + fail-fast: false + matrix: + platform: + - linux/amd64 + - linux/arm64 steps: - name: Check out the repo - uses: actions/checkout@v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Log in to Container registry uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 @@ -25,21 +33,77 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata (tags, labels) for Docker + - name: Extract metadata id: meta uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 with: - images: | - ${{ env.IMAGE }} + images: ${{ env.IMAGE }} tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=ref,event=tag - - name: Build and push Docker images + - name: Build and push by digest + id: build uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: context: . - push: true - tags: ${{ steps.meta.outputs.tags }} + platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=${{ env.IMAGE }},push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + echo "PLATFORM_PAIR=$(echo '${{ matrix.platform }}' | tr '/' '-')" >> $GITHUB_ENV + + - name: Upload digest + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: digest-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + needs: build + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - name: Download digests + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 + with: + path: /tmp/digests + pattern: digest-* + merge-multiple: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 + + - name: Log in to Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.IMAGE }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=ref,event=tag + + - name: Create manifest and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create \ + $(jq -cr '.tags | map("--tag " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf "${IMAGE}@sha256:%s " *) diff --git a/.github/workflows/server-release.yml b/.github/workflows/server-release.yml index 7eae22ff..7db44275 100644 --- a/.github/workflows/server-release.yml +++ b/.github/workflows/server-release.yml @@ -16,13 +16,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Set up Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: ${{ env.PYTHON_VERSION }} + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libldap2-dev libsasl2-dev + - name: Install test dependencies run: | cd dns-server && pip install -r requirements.txt pytest pytest-cov @@ -35,7 +38,7 @@ jobs: --cov-fail-under=98 -v --tb=short || true - name: Upload coverage to Codecov - uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4 + uses: codecov/codecov-action@3f20e214133d0983f9a10f3d63b0faf9241a3daa # v6 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.xml @@ -65,20 +68,45 @@ jobs: docker run --rm -w /app/dns-server squawk-dns-server:release-test python3.13 -m flake8 bins/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics || true # Build and release job only runs when version tag created - build-and-release: - name: Build and Release DNS Server + build-platform: + name: Build ${{ matrix.service }} for ${{ matrix.platform }} runs-on: ubuntu-latest needs: test if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + strategy: + matrix: + include: + - service: dns-server + target: dns-server + - service: dns-server-prod + target: production + - service: dns-client-python + target: dns-client + - service: dns-testing + target: testing + platform: [linux/amd64, linux/arm64] permissions: contents: write packages: write steps: - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 + - name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9b11de45568b7b44d28e85c0b8e7 # v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@b5ca514318bd6ebba01cdb9b2d9a7ac3b0c11b09 # v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf5ca # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract version from tag id: version env: @@ -88,86 +116,121 @@ jobs: echo "VERSION=$VERSION" >> $GITHUB_OUTPUT echo "Version: $VERSION" - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - - - name: Log in to GitHub Container Registry - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract platform tag + id: platform_tag + run: | + PLATFORM_TAG=$(echo ${{ matrix.platform }} | sed 's/linux\///') + echo "tag=$PLATFORM_TAG" >> $GITHUB_OUTPUT - # Build and push DNS Server Docker images - - name: Build and push DNS Server Docker image - uses: docker/build-push-action@v5 + - name: Build and push ${{ matrix.service }} Docker image for ${{ matrix.platform }} + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . - target: dns-server - platforms: linux/amd64,linux/arm64 + target: ${{ matrix.target }} + platforms: ${{ matrix.platform }} push: true tags: | - ghcr.io/penguintechinc/squawk-dns-server:${{ steps.version.outputs.VERSION }} - ghcr.io/penguintechinc/squawk-dns-server:latest + ghcr.io/penguintechinc/squawk-${{ matrix.service }}:${{ steps.version.outputs.VERSION }}-${{ steps.platform_tag.outputs.tag }} + ghcr.io/penguintechinc/squawk-${{ matrix.service }}:latest-${{ steps.platform_tag.outputs.tag }} labels: | - org.opencontainers.image.title=Squawk DNS Server - org.opencontainers.image.description=DNS-over-HTTPS server with web console and authentication + org.opencontainers.image.title=Squawk ${{ matrix.service }} org.opencontainers.image.version=${{ steps.version.outputs.VERSION }} org.opencontainers.image.source=https://github.com/${{ github.repository }} org.opencontainers.image.revision=${{ github.sha }} + cache-from: type=gha,scope=${{ matrix.service }}-${{ matrix.platform }} + cache-to: type=gha,mode=max,scope=${{ matrix.service }}-${{ matrix.platform }} - - name: Build and push DNS Server Production Docker image - uses: docker/build-push-action@v5 + merge-manifests: + name: Merge Docker manifests + runs-on: ubuntu-latest + needs: build-platform + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + packages: write + steps: + - name: Checkout code + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: - context: . - target: production - platforms: linux/amd64,linux/arm64 - push: true - tags: | - ghcr.io/penguintechinc/squawk-dns-server-prod:${{ steps.version.outputs.VERSION }} - ghcr.io/penguintechinc/squawk-dns-server-prod:latest - labels: | - org.opencontainers.image.title=Squawk DNS Server (Production) - org.opencontainers.image.description=Production-optimized DNS-over-HTTPS server - org.opencontainers.image.version=${{ steps.version.outputs.VERSION }} - org.opencontainers.image.source=https://github.com/${{ github.repository }} - org.opencontainers.image.revision=${{ github.sha }} + fetch-depth: 0 - - name: Build and push DNS Client Python Docker image - uses: docker/build-push-action@v5 + - name: Log in to GitHub Container Registry + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf5ca # v3 with: - context: . - target: dns-client - platforms: linux/amd64,linux/arm64 - push: true - tags: | - ghcr.io/penguintechinc/squawk-dns-client-python:${{ steps.version.outputs.VERSION }} - ghcr.io/penguintechinc/squawk-dns-client-python:latest - labels: | - org.opencontainers.image.title=Squawk DNS Client (Python) - org.opencontainers.image.description=Python DNS-over-HTTPS client with local forwarding - org.opencontainers.image.version=${{ steps.version.outputs.VERSION }} - org.opencontainers.image.source=https://github.com/${{ github.repository }} - org.opencontainers.image.revision=${{ github.sha }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@b5ca514318bd6ebba01cdb9b2d9a7ac3b0c11b09 # v3 + + - name: Extract version from tag + id: version + env: + TAG: ${{ github.ref }} + run: | + VERSION=${TAG#refs/tags/v} + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - - name: Build and push Testing Docker image - uses: docker/build-push-action@v5 + - name: Merge DNS Server manifests + run: | + docker buildx imagetools create -t ghcr.io/penguintechinc/squawk-dns-server:${{ steps.version.outputs.VERSION }} \ + ghcr.io/penguintechinc/squawk-dns-server:${{ steps.version.outputs.VERSION }}-amd64 \ + ghcr.io/penguintechinc/squawk-dns-server:${{ steps.version.outputs.VERSION }}-arm64 + docker buildx imagetools create -t ghcr.io/penguintechinc/squawk-dns-server:latest \ + ghcr.io/penguintechinc/squawk-dns-server:latest-amd64 \ + ghcr.io/penguintechinc/squawk-dns-server:latest-arm64 + + - name: Merge DNS Server Production manifests + run: | + docker buildx imagetools create -t ghcr.io/penguintechinc/squawk-dns-server-prod:${{ steps.version.outputs.VERSION }} \ + ghcr.io/penguintechinc/squawk-dns-server-prod:${{ steps.version.outputs.VERSION }}-amd64 \ + ghcr.io/penguintechinc/squawk-dns-server-prod:${{ steps.version.outputs.VERSION }}-arm64 + docker buildx imagetools create -t ghcr.io/penguintechinc/squawk-dns-server-prod:latest \ + ghcr.io/penguintechinc/squawk-dns-server-prod:latest-amd64 \ + ghcr.io/penguintechinc/squawk-dns-server-prod:latest-arm64 + + - name: Merge DNS Client Python manifests + run: | + docker buildx imagetools create -t ghcr.io/penguintechinc/squawk-dns-client-python:${{ steps.version.outputs.VERSION }} \ + ghcr.io/penguintechinc/squawk-dns-client-python:${{ steps.version.outputs.VERSION }}-amd64 \ + ghcr.io/penguintechinc/squawk-dns-client-python:${{ steps.version.outputs.VERSION }}-arm64 + docker buildx imagetools create -t ghcr.io/penguintechinc/squawk-dns-client-python:latest \ + ghcr.io/penguintechinc/squawk-dns-client-python:latest-amd64 \ + ghcr.io/penguintechinc/squawk-dns-client-python:latest-arm64 + + - name: Merge DNS Testing manifests + run: | + docker buildx imagetools create -t ghcr.io/penguintechinc/squawk-dns-testing:${{ steps.version.outputs.VERSION }} \ + ghcr.io/penguintechinc/squawk-dns-testing:${{ steps.version.outputs.VERSION }}-amd64 \ + ghcr.io/penguintechinc/squawk-dns-testing:${{ steps.version.outputs.VERSION }}-arm64 + docker buildx imagetools create -t ghcr.io/penguintechinc/squawk-dns-testing:latest \ + ghcr.io/penguintechinc/squawk-dns-testing:latest-amd64 \ + ghcr.io/penguintechinc/squawk-dns-testing:latest-arm64 + + # Extract release notes and create release + release: + name: Create Release + runs-on: ubuntu-latest + needs: merge-manifests + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + steps: + - name: Checkout code + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: - context: . - target: testing - platforms: linux/amd64,linux/arm64 - push: true - tags: | - ghcr.io/penguintechinc/squawk-dns-testing:${{ steps.version.outputs.VERSION }} - ghcr.io/penguintechinc/squawk-dns-testing:latest - labels: | - org.opencontainers.image.title=Squawk DNS Testing - org.opencontainers.image.description=Testing environment with comprehensive test suite - org.opencontainers.image.version=${{ steps.version.outputs.VERSION }} - org.opencontainers.image.source=https://github.com/${{ github.repository }} - org.opencontainers.image.revision=${{ github.sha }} + fetch-depth: 0 + + - name: Extract version from tag + id: version + env: + TAG: ${{ github.ref }} + run: | + VERSION=${TAG#refs/tags/v} + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + echo "Version: $VERSION" - # Extract release notes from RELEASE_NOTES.md - name: Extract Release Notes run: | chmod +x .github/scripts/extract-release-notes.sh @@ -175,7 +238,6 @@ jobs: GITHUB_SHA="${{ github.sha }}" \ .github/scripts/extract-release-notes.sh server "${{ steps.version.outputs.VERSION }}" release_body.md - # Create GitHub Release for server - name: Create Server Release uses: actions/create-release@0cb9c9b65d5d1901c1f53e5e66eaf4afd303e70e # v1 id: create_release @@ -192,7 +254,7 @@ jobs: notify: name: Notify Server Release runs-on: ubuntu-latest - needs: [test, build-and-release] + needs: [test, merge-manifests, release] if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') steps: - name: Server Release Summary diff --git a/.github/workflows/version-monitor.yml b/.github/workflows/version-monitor.yml index 382670d5..78fd4b90 100644 --- a/.github/workflows/version-monitor.yml +++ b/.github/workflows/version-monitor.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 2 @@ -65,7 +65,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Verify DNS Server version support run: | @@ -101,10 +101,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: Set up Python for bandit - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: ${{ env.PYTHON_VERSION }} diff --git a/Dockerfile b/Dockerfile index a6f02db1..a64f46c2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,5 @@ # Unified Multi-stage Dockerfile for Squawk DNS System -# Ubuntu 24.04 LTS with Python 3.13 - Standardized Build Environment -FROM debian:bookworm-slim@sha256:f06537653ac770703bc45b4b113475bd402f451e85223f0f2837acbf89ab020a AS base +FROM python:3.13-slim-bookworm@sha256:061b6e52a07ab675f0e4a9428c5a8ee6bed996983427f4691f6bebf29c56d9dc AS base LABEL company="Penguin Tech Group LLC" LABEL org.opencontainers.image.authors="info@penguintech.group" @@ -15,26 +14,17 @@ ENV PYTHONUNBUFFERED=1 \ DEBIAN_FRONTEND=noninteractive \ TZ=UTC -# Install Python 3.13 and basic build dependencies -RUN apt-get update && apt-get install -y \ - python3.13 \ - python3.13-dev \ - python3.13-venv \ +# Install build and LDAP/XML dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ gcc \ g++ \ libc6-dev \ libffi-dev \ libssl-dev \ pkg-config \ - build-essential \ curl \ ca-certificates \ - && ln -sf /usr/bin/python3.13 /usr/bin/python3 \ - && curl -sS https://bootstrap.pypa.io/get-pip.py | python3.13 \ - && rm -rf /var/lib/apt/lists/* - -# Install LDAP and XML dependencies -RUN apt-get update && apt-get install -y \ libxml2-dev \ libxslt1-dev \ libldap-dev \ diff --git a/dns-server/Dockerfile b/dns-server/Dockerfile index a2ad777a..35d9ff81 100644 --- a/dns-server/Dockerfile +++ b/dns-server/Dockerfile @@ -1,5 +1,5 @@ # DNS Server Dockerfile with Python 3.13 -FROM debian:bookworm-slim@sha256:01f42367a0a94ad4bc17111776fd66e3500c1d87c15bbd6055b7371d39c124fb +FROM python:3.13-slim-bookworm@sha256:061b6e52a07ab675f0e4a9428c5a8ee6bed996983427f4691f6bebf29c56d9dc LABEL company="Penguin Tech Group LLC" LABEL org.opencontainers.image.authors="info@penguintech.io" @@ -15,11 +15,8 @@ ENV PYTHONUNBUFFERED=1 \ TZ=UTC \ SQUAWK_ENV=${SQUAWK_ENV:-production} -# Install Python 3.13 and basic build dependencies -RUN apt-get update && apt-get install -y \ - python3.13 \ - python3.13-dev \ - python3.13-venv \ +# Install build dependencies and LDAP/XML enterprise libraries +RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ gcc \ g++ \ @@ -29,11 +26,7 @@ RUN apt-get update && apt-get install -y \ curl \ wget \ ca-certificates \ - git && \ - curl -sS https://bootstrap.pypa.io/get-pip.py | python3.13 - -# Install LDAP, XML and enterprise dependencies -RUN apt-get update && apt-get install -y \ + git \ libxml2-dev \ libxslt1-dev \ libldap-dev \ @@ -76,7 +69,6 @@ RUN python3.13 -m venv /app/venv && \ # Make virtual environment the default ENV PATH="/app/venv/bin:$PATH" - # Copy application code COPY . /app/dns-server/ @@ -103,4 +95,4 @@ CMD if [ "$SQUAWK_ENV" = "test" ]; then \ else \ echo "Starting DNS server..." && \ python3 /app/dns-server/bins/server_premium_integrated.py -p ${PORT:-8080} -n; \ - fi \ No newline at end of file + fi diff --git a/dns-server/Dockerfile.api b/dns-server/Dockerfile.api index b1d83ab6..5698e132 100644 --- a/dns-server/Dockerfile.api +++ b/dns-server/Dockerfile.api @@ -1,5 +1,5 @@ # Squawk DNS API-Only Flask Container -FROM python:3.13-slim-bookworm@sha256:01f42367a0a94ad4bc17111776fd66e3500c1d87c15bbd6055b7371d39c124fb +FROM python:3.13-slim-bookworm@sha256:061b6e52a07ab675f0e4a9428c5a8ee6bed996983427f4691f6bebf29c56d9dc LABEL company="Penguin Tech Group LLC" LABEL org.opencontainers.image.authors="info@penguintech.io" diff --git a/dns-server/Dockerfile.dns-server b/dns-server/Dockerfile.dns-server index 24b450fe..a7b4dc63 100644 --- a/dns-server/Dockerfile.dns-server +++ b/dns-server/Dockerfile.dns-server @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim@sha256:01f42367a0a94ad4bc17111776fd66e3500c1d87c15bbd6055b7371d39c124fb AS base +FROM debian:bookworm-slim@sha256:4724b8cc51e33e398f0e2e15e18d5ec2851ff0c2280647e1310bc1642182655d AS base RUN apt-get update && apt-get install -y software-properties-common && \ add-apt-repository ppa:deadsnakes/ppa && \ diff --git a/dns-server/flask_app/app.py b/dns-server/flask_app/app.py index 43ed6cb3..05d7b9ef 100644 --- a/dns-server/flask_app/app.py +++ b/dns-server/flask_app/app.py @@ -12,7 +12,8 @@ from flask_cors import CORS from flask_jwt_extended import JWTManager from flask_login import LoginManager -from penguin_limiter import FlaskRateLimiter, MemoryStorage, RateLimitConfig +from flask_limiter import Limiter +from flask_limiter.util import get_remote_address from werkzeug.security import generate_password_hash # Add current directory to path @@ -51,9 +52,10 @@ } }) -limiter = FlaskRateLimiter( - config=RateLimitConfig.from_string("200/minute"), - storage=MemoryStorage(), +limiter = Limiter( + get_remote_address, + default_limits=["200/minute"], + storage_uri="memory://", ) limiter.init_app(app) diff --git a/dns-server/requirements.txt b/dns-server/requirements.txt index 0c864733..e95b86f4 100644 --- a/dns-server/requirements.txt +++ b/dns-server/requirements.txt @@ -12,7 +12,7 @@ penguin-utils==0.1.0 penguin-licensing==0.1.0 penguin-sal==0.1.0 penguin-aaa==0.1.0 -penguin-limiter @ git+https://github.com/penguintechinc/penguin-libs.git#subdirectory=packages/python-limiter +flask-limiter>=4.1.1 alembic>=1.13.0 dnspython>=2.7.0 requests>=2.32.3