diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..958b26c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +node_modules +.git +.gitignore +*.md +dist \ No newline at end of file diff --git a/.github/workflows/docker-build-push.yaml b/.github/workflows/docker-build-push.yaml new file mode 100644 index 0000000..d7e1458 --- /dev/null +++ b/.github/workflows/docker-build-push.yaml @@ -0,0 +1,99 @@ +name: Docker Build and Push + +on: + push: + tags: + - "*" + +env: + REGISTRY_IMAGE: mxmlndml/cloudflare-dynamic-dns + +jobs: + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + platform: + - linux/amd64 + - linux/arm/v7 + - linux/arm64 + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY_IMAGE }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push by digest + id: build + uses: docker/build-push-action@v4 + with: + context: . + platforms: ${{ matrix.platform }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=${{ env.REGISTRY_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:}" + + - name: Upload digest + uses: actions/upload-artifact@v3 + with: + name: digests + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + needs: + - build + + steps: + - name: Download digests + uses: actions/download-artifact@v3 + with: + name: digests + path: /tmp/digests + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v4 + with: + images: ${{ env.REGISTRY_IMAGE }} + + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} diff --git a/Dockerfile b/Dockerfile index bd6569a..0377f05 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,18 @@ -FROM node:alpine AS base -# add pnpm +FROM node:slim AS base +ENV PNPM_HOME="/pnpm" +ENV PATH="${PNPM_HOME}:${PATH}" RUN corepack enable -RUN corepack prepare pnpm@latest --activate - - -FROM base as deps +COPY . /app WORKDIR /app -# install dependencies with pnpm -COPY package.json pnpm-lock.yaml* ./ -RUN pnpm i --frozen-lockfile +FROM base as prod-deps +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile -FROM base as builder -WORKDIR /app -COPY --from=deps /app/node_modules ./node_modules -COPY . . -RUN pnpm build +FROM base AS build +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile +RUN pnpm run build - -FROM base as runner -WORKDIR /app -COPY --from=builder /app/dist ./dist -COPY --from=builder /app/node_modules ./node_modules - -USER node - -CMD ["node", "./dist/index.js"] \ No newline at end of file +FROM base +COPY --from=prod-deps /app/node_modules /app/node_modules +COPY --from=build /app/dist /app/dist +CMD [ "pnpm", "start" ] \ No newline at end of file diff --git a/README.md b/README.md index 2480016..9d46599 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ -# cloudflare-ddns -This Docker container provides a simple and efficient solution for dynamic DNS updates using Cloudflare DNS. It allows you to automatically update your DNS records in Cloudflare at specified intervals, ensuring that your services are always accessible through a domain name. +# Cloudflare Dynamic DNS + +This Docker container provides a simple and efficient solution for dynamic DNS +updates using Cloudflare DNS. It allows you to automatically update your DNS +records in Cloudflare at specified intervals, ensuring that your services are +always accessible through a domain name. diff --git a/docker-compose.yml b/docker-compose.yml index 7b27bd7..801f795 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,10 @@ services: - cloudflare-ddns: - image: cloudflare-ddns + cloudflare-dynamic-dns: + image: mxmlndml/cloudflare-dynamic-dns:latest restart: always environment: - - API_KEY=123 - - ZONE_ID=023e105f4ecef8ad9ca31a8372d0c353 - - DOMAIN_NAME=dyndns.example.com - - INTERVAL=5 - - LOG_LEVEL=INFO \ No newline at end of file + - API_KEY=123 + - ZONE_ID=023e105f4ecef8ad9ca31a8372d0c353 + - DOMAIN_NAME=dyndns.example.com + - INTERVAL=5 + - LOG_LEVEL=INFO diff --git a/package.json b/package.json index 4fde72a..03097dc 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "cloudflare-ddns", + "name": "cloudflare-dynamic-dns", "version": "1.0.0", "description": "", "main": "dist/index.js",