From f0543e67b7200c5daafc86b58064ce5a022ec3c4 Mon Sep 17 00:00:00 2001 From: Peter Dedene Date: Tue, 3 Oct 2023 12:51:33 +0200 Subject: [PATCH] Initial commit --- .dockerignore | 2 + .github/auto-merge.yml | 4 + .github/dependabot.yml | 13 ++ .github/workflows/auto-merge.yml | 14 +++ .github/workflows/build.yml | 199 +++++++++++++++++++++++++++++++ .github/workflows/readme.yml | 29 +++++ .github/workflows/trivy.yml | 103 ++++++++++++++++ .gitignore | 73 ++++++++++++ Dockerfile | 10 ++ LICENSE | 161 +++++++++++++++++++++++++ README.md | 54 +++++++++ 11 files changed, 662 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/auto-merge.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/auto-merge.yml create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/readme.yml create mode 100644 .github/workflows/trivy.yml create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ea32980 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +# Ignore everything +* diff --git a/.github/auto-merge.yml b/.github/auto-merge.yml new file mode 100644 index 0000000..6ebeb1d --- /dev/null +++ b/.github/auto-merge.yml @@ -0,0 +1,4 @@ +# Run on autopilot +- match: + dependency_type: all + update_type: all diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2f2d15a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'daily' + + # Maintain dependencies within Dockerfiles + - package-ecosystem: 'docker' + directory: '/' + schedule: + interval: 'daily' diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml new file mode 100644 index 0000000..a76cd7b --- /dev/null +++ b/.github/workflows/auto-merge.yml @@ -0,0 +1,14 @@ +name: Auto-Merge Dependabot PRs + +on: + pull_request: + +jobs: + auto-merge: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ahmadnassri/action-dependabot-auto-merge@v2 + with: + target: minor + github-token: ${{ secrets.GH_TOKEN }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..ec4e640 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,199 @@ +name: Build and push container images + +on: + workflow_dispatch: + push: + branches: [main] + paths: + - Dockerfile + pull_request: + branches: [main] + paths: + - Dockerfile + +env: + DOCKER_BUILDKIT: 1 + COSIGN_EXPERIMENTAL: 1 + +jobs: + metadata: + name: Get image and repo details + runs-on: ubuntu-latest + + outputs: + name: ${{ steps.name.outputs.name }} + title: ${{ steps.title.outputs.title }} + version: ${{ steps.version.outputs.version }} + branch: ${{ steps.branch.outputs.branch }} + labels: ${{ steps.metadata.outputs.labels }} + tags: ${{ steps.metadata.outputs.tags }} + platforms: linux/amd64,linux/arm64,linux/arm/v7 + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Generate docker-compliant image name + id: name + run: echo "name=$(echo ${GITHUB_REPOSITORY,,} | sed 's/docker-//')" | tee -a $GITHUB_OUTPUT + + - name: Generate OCI image title + id: title + run: + echo "title=$(echo ${GITHUB_REPOSITORY#*/} | sed 's/docker-//')" | tee -a $GITHUB_OUTPUT + + - name: Parse Caddy version + id: version + run: + echo "version=$(grep -Eo 'caddy:[0-9]+\.[0-9]+\.[0-9]+$' Dockerfile | cut -d ':' -f2)" | + tee -a $GITHUB_OUTPUT + + - name: Generate build tag from head + id: branch + run: | + export GIT_REF=${GITHUB_HEAD_REF:-$GITHUB_REF_NAME} + echo "branch=$(echo ${GIT_REF,,} | sed 's/[^a-zA-Z0-9]/-/g')" | tee -a $GITHUB_OUTPUT + + - name: Generate Docker metadata with Caddy version + uses: docker/metadata-action@v4 + id: metadata + with: + images: | + docker.io/${{ steps.name.outputs.name }} + ghcr.io/${{ steps.name.outputs.name }} + tags: | + type=semver,pattern={{version}},value=v${{ steps.version.outputs.version }} + type=semver,pattern={{major}}.{{minor}},value=v${{ steps.version.outputs.version }} + type=semver,pattern={{major}},value=v${{ steps.version.outputs.version }} + labels: | + org.opencontainers.image.title=${{ steps.title.outputs.title }} + + build: + name: Build container image + runs-on: ubuntu-latest + needs: [metadata] + + permissions: + id-token: write # keyless Cosign signatures + pull-requests: write # PR comments + + outputs: + digest: ${{ steps.build.outputs.digest }} + image-ref: ttl.sh/${{ needs.metadata.outputs.name }}:${{ github.sha }} + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Install Cosign + uses: sigstore/cosign-installer@v3.1.2 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + uses: docker/build-push-action@v4 + id: build + with: + context: . + push: true # to ttl.sh + tags: ttl.sh/${{ needs.metadata.outputs.name }}:${{ github.sha }} + labels: ${{ needs.metadata.outputs.labels }} + platforms: ${{ needs.metadata.outputs.platforms }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Sign container images + run: | + cosign sign --yes --recursive \ + "ttl.sh/$IMAGE_NAME@$IMAGE_DIGEST" + env: + IMAGE_NAME: ${{ needs.metadata.outputs.name }} + IMAGE_DIGEST: ${{ steps.build.outputs.digest }} + + trivy: + name: Run Trivy scanner + needs: [build] + uses: ./.github/workflows/trivy.yml + with: + image-ref: ${{ needs.build.outputs.image-ref }} + + publish: + name: Publish container image + needs: [metadata, build, trivy] + runs-on: ubuntu-latest + + permissions: + id-token: write # keyless Cosign signatures + packages: write # GHCR + contents: write # git tags + + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Install Cosign + uses: sigstore/cosign-installer@v3.1.2 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USER }} + password: ${{ secrets.DOCKER_HUB_PASSWORD }} + + - name: Login to GitHub Container Repository + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Verify container images + run: | + cosign verify \ + --certificate-oidc-issuer https://token.actions.githubusercontent.com \ + --certificate-identity-regexp https://github.com/$GITHUB_REPOSITORY/.github/workflows/ \ + ${{ needs.build.outputs.image-ref }} + + - name: Publish container image + uses: docker/build-push-action@v4 + id: publish + with: + context: . + push: true + tags: ${{ needs.metadata.outputs.tags }} + labels: ${{ needs.metadata.outputs.labels }} + platforms: ${{ needs.metadata.outputs.platforms }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Sign container images + run: | + cosign sign --yes --recursive "docker.io/$IMAGE_NAME@$IMAGE_DIGEST" + cosign sign --yes --recursive "ghcr.io/$IMAGE_NAME@$IMAGE_DIGEST" + env: + IMAGE_NAME: ${{ needs.metadata.outputs.name }} + IMAGE_DIGEST: ${{ steps.publish.outputs.digest }} + + - name: Push version tags + run: | + MAJOR=$(echo $CADDY_VERSION | cut -d . -f 1) + MINOR=$(echo $CADDY_VERSION | cut -d . -f 2) + git tag -f "v$MAJOR" + git tag -f "v$MAJOR.$MINOR" + git tag -f "v$CADDY_VERSION" + git push -f -u origin "v$MAJOR" + git push -f -u origin "v$MAJOR.$MINOR" + git push -f -u origin "v$CADDY_VERSION" + env: + CADDY_VERSION: ${{ needs.metadata.outputs.version }} diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml new file mode 100644 index 0000000..d783bc4 --- /dev/null +++ b/.github/workflows/readme.yml @@ -0,0 +1,29 @@ +name: Sync GitHub README with Docker Hub + +on: + workflow_dispatch: + push: + branches: [main] + paths: + - README.md + +jobs: + github-docker: + name: Sync GitHub README with Docker Hub + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Generate docker-compliant image name + run: + echo "IMAGE_NAME=$(echo ${GITHUB_REPOSITORY,,} | sed 's/docker-//')" | tee -a $GITHUB_ENV + + - name: Update Docker Hub description + uses: peter-evans/dockerhub-description@v3 + with: + username: ${{ secrets.DOCKER_HUB_USER }} + password: ${{ secrets.DOCKER_HUB_PASSWORD }} + repository: ${{ env.IMAGE_NAME }} + short-description: ${{ github.event.repository.description }} diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml new file mode 100644 index 0000000..7f71b2a --- /dev/null +++ b/.github/workflows/trivy.yml @@ -0,0 +1,103 @@ +name: Trivy Security Scan + +on: + workflow_dispatch: + schedule: + - cron: 0 0 * * * # daily at midnight + workflow_call: + inputs: + image-ref: + type: string + required: false + description: Container Ref to be scanned by Trivy + +env: + DOCKER_BUILDKIT: 1 + COSIGN_EXPERIMENTAL: 1 + +jobs: + trivy-repo: + name: Scan repository + runs-on: ubuntu-latest + + permissions: + security-events: write # upload security results + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get main branch SHA + run: | + git pull origin main:main + echo "BASE_SHA=$(git merge-base --fork-point main)" | tee -a $GITHUB_ENV + + - name: Scan repo filesystem + uses: aquasecurity/trivy-action@0.12.0 + with: + scan-type: fs + format: sarif + output: trivy-results.sarif + + - name: Upload scan results to GitHub Security + uses: github/codeql-action/upload-sarif@v2 + if: always() + with: + sarif_file: trivy-results.sarif + ref: refs/heads/main + sha: ${{ env.BASE_SHA }} + + trivy-docker: + name: Scan container image + runs-on: ubuntu-latest + + permissions: + security-events: write # upload security results + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get main branch SHA + run: | + git pull origin main:main + echo "BASE_SHA=$(git merge-base --fork-point main)" | tee -a $GITHUB_ENV + + - name: Install Cosign + uses: sigstore/cosign-installer@v3.1.2 + + - name: Generate docker-compliant image name + run: | + if [[ -z "$IMAGE_REF" ]]; then + echo "IMAGE_REF=$(echo ${GITHUB_REPOSITORY,,} | sed 's/docker-//'):latest" | tee -a $GITHUB_ENV + else + echo "IMAGE_REF=$IMAGE_REF" | tee -a $GITHUB_ENV + fi + env: + IMAGE_REF: ${{ inputs.image-ref }} + + - name: Verify container images + run: | + cosign verify \ + --certificate-oidc-issuer https://token.actions.githubusercontent.com \ + --certificate-identity-regexp https://github.com/$GITHUB_REPOSITORY/.github/workflows/ \ + $IMAGE_REF + + - name: Scan container image + uses: aquasecurity/trivy-action@0.12.0 + with: + image-ref: ${{ env.IMAGE_REF }} + format: sarif + output: trivy-results.sarif + + - name: Upload scan results to GitHub Security + uses: github/codeql-action/upload-sarif@v2 + if: always() + with: + sarif_file: trivy-results.sarif + ref: refs/heads/main + sha: ${{ env.BASE_SHA }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1a9d87f --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c9c6f33 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM caddy:2.7.4-builder AS builder +RUN xcaddy build \ + --with github.com/caddy-dns/cloudflare \ + --with github.com/lucaslorentz/caddy-docker-proxy/v2 + +FROM caddy:2.7.4-alpine +COPY --from=builder /usr/bin/caddy /usr/bin/caddy +RUN apk update && apk upgrade + +CMD ["caddy", "docker-proxy"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f681027 --- /dev/null +++ b/LICENSE @@ -0,0 +1,161 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and distribution as defined + by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is + granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other entities that control, + are controlled by, or are under common control with that entity. For the purposes of this + definition, "control" means (i) the power, direct or indirect, to cause the direction or + management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by + this License. + + "Source" form shall mean the preferred form for making modifications, including but not limited + to software source code, documentation source, and configuration files. + + "Object" form shall mean any form resulting from mechanical transformation or translation of a + Source form, including but not limited to compiled object code, generated documentation, and + conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, made available under + the License, as indicated by a copyright notice that is included in or attached to the work (an + example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or + derived from) the Work and for which the editorial revisions, annotations, elaborations, or + other modifications represent, as a whole, an original work of authorship. For the purposes of + this License, Derivative Works shall not include works that remain separable from, or merely + link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including the original version of the Work and + any modifications or additions to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or + Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this + definition, "submitted" means any form of electronic, verbal, or written communication sent to + the Licensor or its representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that are managed by, or + on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding + communication that is conspicuously marked or otherwise designated in writing by the copyright + owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a + Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each + Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, + irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor + hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to those patent claims + licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or + by combination of their Contribution(s) with the Work to which such Contribution(s) was + submitted. If You institute patent litigation against any entity (including a cross-claim or + counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work + constitutes direct or contributory patent infringement, then any patent licenses granted to You + under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof + in any medium, with or without modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; + and + + (b) You must cause any modified files to carry prominent notices stating that You changed the + files; and + + (c) You must retain, in the Source form of any Derivative Works that You distribute, all + copyright, patent, trademark, and attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative + Works that You distribute must include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not pertain to any part of the + Derivative Works, in at least one of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or documentation, if provided along with + the Derivative Works; or, within a display generated by the Derivative Works, if and wherever + such third-party notices normally appear. The contents of the NOTICE file are for informational + purposes only and do not modify the License. You may add Your own attribution notices within + Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the + Work, provided that such additional attribution notices cannot be construed as modifying the + License. + + You may add Your own copyright statement to Your modifications and may provide additional or + different license terms and conditions for use, reproduction, or distribution of Your + modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution + intentionally submitted for inclusion in the Work by You to the Licensor shall be under the + terms and conditions of this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate + license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service + marks, or product names of the Licensor, except as required for reasonable and customary use in + describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor + provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, + any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or + redistributing the Work and assume any risks associated with Your exercise of permissions under + this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including + negligence), contract, or otherwise, unless required by applicable law (such as deliberate and + grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for + damages, including any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability to use the Work + (including but not limited to damages for loss of goodwill, work stoppage, computer failure or + malfunction, or any and all other commercial damages or losses), even if such Contributor has + been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works + thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, + indemnity, or other liability obligations and/or rights consistent with this License. However, + in accepting such obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability incurred by, or claims asserted + against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is +distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing permissions and limitations under the +License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..94070c7 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# Caddy-Cloudflare-proxy + +[![Docker Hub](https://img.shields.io/badge/Docker%20Hub-zenjoy%2Fcaddy--cloudflare--s3-lightgrey?style=flat)](https://hub.docker.com/r/zenjoy/caddy-cloudflare-proxy) +[![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/zenjoy/docker-caddy-cloudflare-proxy?label=version)](https://github.com/zenjoy/docker-caddy-cloudflare-proxy/tags) +[![License](https://img.shields.io/github/license/zenjoy/docker-caddy-cloudflare-proxy)](https://github.com/zenjoy/docker-caddy-cloudflare-proxy/blob/main/LICENSE) + +The official [Caddy](https://hub.docker.com/_/caddy) Docker image with following modules added: + +- [caddy-dns/cloudflare](https://github.com/caddy-dns/cloudflare) allows DNS-01 ACME validation +- [lucaslorentz/caddy-docker-proxy](https://github.com/lucaslorentz/caddy-docker-proxy) enables + Caddy to be used as a reverse proxy for Docker containers via labels + +Available on Docker Hub or GitHub Container Registry (GHCR) for AMD64, ARM64, and ARMv7. + +```sh +# Docker Hub +docker pull zenjoy/caddy-cloudflare-proxy:latest + +# GHCR +docker pull ghcr.io/zenjoy/caddy-cloudflare-proxy:latest +``` + +## Building + +You can easily build the Docker image locally by doing + +```sh +docker build -t caddy-cloudflare-proxy . +``` + +## Container signatures + +All images are automatically signed via [Cosign](https://docs.sigstore.dev/cosign/overview/) using +[keyless signatures](https://docs.sigstore.dev/cosign/keyless/). You verify the integrity of these +images as follows: + +```sh +cosign verify \ + --certificate-oidc-issuer https://token.actions.githubusercontent.com \ + --certificate-identity-regexp https://github.com/zenjoy/docker-caddy-cloudflare-proxy/.github/workflows/ \ + zenjoy/caddy-cloudflare-proxy:latest +``` + +## Contributing + +Feel free to contribute and make things better by opening an +[Issue](https://github.com/zenjoy/docker-caddy-cloudflare-proxy/issues) or +[Pull Request](https://github.com/zenjoy/docker-caddy-cloudflare-proxy/pulls). + +## License + +View +[license information](https://github.com/zenjoy/docker-caddy-cloudflare-proxy/blob/main/LICENSE) for +the software contained in this image.