From a1cb24ae00df54fde7a13ca68bed3a1d08a729b5 Mon Sep 17 00:00:00 2001 From: Vylyne <94922829+Vylyne@users.noreply.github.com> Date: Sat, 27 Sep 2025 10:18:04 -0400 Subject: [PATCH 1/7] rename original entrypoint to run-imapfilter.sh --- entrypoint.sh => run-imapfilter.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename entrypoint.sh => run-imapfilter.sh (100%) diff --git a/entrypoint.sh b/run-imapfilter.sh similarity index 100% rename from entrypoint.sh rename to run-imapfilter.sh From b6b1e3076f41c29a96d60f90b9ceec8ca019938b Mon Sep 17 00:00:00 2001 From: Vylyne <94922829+Vylyne@users.noreply.github.com> Date: Sat, 27 Sep 2025 10:18:37 -0400 Subject: [PATCH 2/7] Remove UserAdd from Dockerfile, and remove extra run - Remove: UserAdd function from Dockerfile - Remove: extra run directive - Add: shadow packge to runtime for adduser, addgroup, and su --- Dockerfile | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 39de286..d7daa3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,19 +16,21 @@ RUN apk --no-cache add lua openssl pcre git \ FROM alpine@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1 -# create an empty config.lua to prevent an error when running imapfilter directly -RUN adduser -D -u 1001 imapfilter \ - && mkdir -p /home/imapfilter/.imapfilter && touch /home/imapfilter/.imapfilter/config.lua \ +# Install runtime dependencies for imapfilter and the required tools for user management (shadow for 'su'). +RUN apk --no-cache add lua lua-dev openssl pcre git shadow \ && mkdir -p /opt/imapfilter/config \ - && chown imapfilter: /opt/imapfilter + && mkdir -p /home/imapfilter/.imapfilter && touch /home/imapfilter/.imapfilter/config.lua COPY --from=builder /usr/local/bin/imapfilter /usr/local/bin/imapfilter COPY --from=builder /usr/local/share/imapfilter /usr/local/share/imapfilter COPY --from=builder /usr/local/man /usr/local/man -RUN apk --no-cache add lua lua-dev openssl pcre git +# Copy the application logic script +COPY --chmod=a+x run-imapfilter.sh /run-imapfilter.sh +# Copy the entrypoint script +COPY --chmod=a+x entrypoint.sh /entrypoint.sh -COPY --chown=imapfilter: --chmod=a+x entrypoint.sh /entrypoint.sh - -USER imapfilter -ENTRYPOINT ["/entrypoint.sh"] +# Set the USER to root so we can execute the user setup and then switch users. +USER root +# The primary ENTRYPOINT is the user setup script. +ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file From 4a352afd00146ecfa463d616e01a37795710fbf4 Mon Sep 17 00:00:00 2001 From: Vylyne <94922829+Vylyne@users.noreply.github.com> Date: Sat, 27 Sep 2025 10:24:12 -0400 Subject: [PATCH 3/7] updated Dockerfile for new docker-entrypoint.sh name --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d7daa3f..76b0989 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,4 +33,4 @@ COPY --chmod=a+x entrypoint.sh /entrypoint.sh # Set the USER to root so we can execute the user setup and then switch users. USER root # The primary ENTRYPOINT is the user setup script. -ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file +ENTRYPOINT ["/docker-entrypoint.sh"] \ No newline at end of file From 8d74b96339c32fd2ab6acdbc4b6885ea8e8333e4 Mon Sep 17 00:00:00 2001 From: Vylyne <94922829+Vylyne@users.noreply.github.com> Date: Sat, 27 Sep 2025 10:24:27 -0400 Subject: [PATCH 4/7] New entrypoint handles PUID and PGID Variables - Accepts PUID and PGID Environment Variables. - Default PUID and PGID to 1001 to maintain backwards compatability and make variables optional - Checks for existing group and ID, then creates/recreates if it does not exist or match PGID - Checks for existing user, id, and default group id, then creates/recreates as necessary - Changes ownership of /opt/imapfilter/config and /home/imapfilter --- docker-entrypoint.sh | 63 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docker-entrypoint.sh diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..8802c14 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env sh +set -e + +# --- 1. Set PUID/PGID with defaults --- +# Default to 1001 if PUID or PGID environment variables aren't set. +PUID=${PUID:-1001} +PGID=${PGID:-1001} +# Username for imapfilter user. +USER_NAME="imapfilter" + +printf ">>> Setting up user with PUID/PGID: %s/%s\n" "$PUID" "$PGID" + +# --- 2. Create/Recreate Group based on PGID --- +# check if group exists. +if getent group "$USER_NAME" >/dev/null; then + # Get the current GID of the 'imapfilter' group + CURRENT_GID=$(getent group "$USER_NAME" | cut -d: -f3) + + if [ "$CURRENT_GID" != "$PGID" ]; then + # Group exists but with the wrong GID, so we delete and re-create it + printf "Group '%s' exists (GID %s) but doesn't match target PGID %s. Re-creating.\n" "$USER_NAME" "$CURRENT_GID" "$PGID" + delgroup "$USER_NAME" + addgroup -g "$PGID" "$USER_NAME" + else + printf "Group '%s' already has the target GID %s, skipping creation.\n" "$USER_NAME" "$PGID" + fi +else + # Group doesn't exist, so create it + printf "Creating group '%s' with GID %s.\n" "$USER_NAME" "$PGID" + addgroup -g "$PGID" "$USER_NAME" +fi + +# --- 3. Create/Recreate User based on PUID and the (now-corrected) Group --- +# Check if the user exists +if getent passwd "$USER_NAME" >/dev/null; then + # User exists, now check its ID and its primary GID + CURRENT_UID=$(getent passwd "$USER_NAME" | cut -d: -f3) + CURRENT_USER_GID=$(getent passwd "$USER_NAME" | cut -d: -f4) # New: Get the user's primary GID + + if [ "$CURRENT_UID" != "$PUID" ] || [ "$CURRENT_USER_GID" != "$PGID" ]; then + # User exists but either the UID or the primary GID is wrong, so we delete and re-create it + printf "User '%s' needs update (UID/GID: %s/%s vs target %s/%s). Re-creating.\n" "$USER_NAME" "$CURRENT_UID" "$CURRENT_USER_GID" "$PUID" "$PGID" + deluser "$USER_NAME" + adduser -D -u "$PUID" -G "$USER_NAME" "$USER_NAME" # Re-create with the guaranteed-correct group name + else + printf "User '%s' already has the target UID %s and GID %s, skipping creation.\n" "$USER_NAME" "$PUID" "$PGID" + fi +else + # User doesn't exist, so create it + printf "Creating user '%s' with UID %s and GID %s.\n" "$USER_NAME" "$PUID" "$PGID" + adduser -D -u "$PUID" -G "$USER_NAME" "$USER_NAME" +fi + +# --- 4. Fix Permissions --- +# Change ownership of key directories to the new user/group +printf "Changing ownership of /opt/imapfilter/config and /home/%s\n" "$USER_NAME" +# Use the numeric IDs to ensure correctness even if a name conflict occurred +chown -R "$PUID":"$PGID" /opt/imapfilter/config /home/"$USER_NAME" + +# --- 5. Execute Original Application Runner --- +# Switch to the new non-root user and execute the application runner script. +printf "Switching user to '%s' and executing /run-imapfilter.sh\n" "$USER_NAME" +exec su "$USER_NAME" -c /run-imapfilter.sh "$@" \ No newline at end of file From 8e980b8208641e0c61b60a00e917a331831ca236 Mon Sep 17 00:00:00 2001 From: Vylyne <94922829+Vylyne@users.noreply.github.com> Date: Sat, 27 Sep 2025 10:41:32 -0400 Subject: [PATCH 5/7] Updated readme to include PUID and PGID environment variables. Updated readme to include PUID and PGID environment variables. Signed-off-by: Vylyne <94922829+Vylyne@users.noreply.github.com> --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2f68f90..6f9cc2f 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ Both `docker-stack` and `k8s` expect the configuration from | Environment variable | Type | Description | | --- | --- | --- | +| `PUID` | string | Process User ID, UID that imapfilter runs as | +| `PGID` | string | Process Group ID, GID that imapfilter runs as | | `GIT_USER` | string | Username for git | | `GIT_TOKEN` | string | Path to the file containing the secret for the `GIT_USER` | | `GIT_TOKEN_RAW` | string | The raw `GIT_TOKEN` to use | From cd64714a1072f9bd0eb60776d5c7121b9c7195ff Mon Sep 17 00:00:00 2001 From: Vylyne <94922829+Vylyne@users.noreply.github.com> Date: Sat, 27 Sep 2025 12:14:00 -0400 Subject: [PATCH 6/7] Update docker-compose.yaml added PUID and PGID to docker-compose.yaml example. Signed-off-by: Vylyne <94922829+Vylyne@users.noreply.github.com> --- examples/docker-stack/docker-compose.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/docker-stack/docker-compose.yaml b/examples/docker-stack/docker-compose.yaml index a0b05c9..7f0f8ca 100644 --- a/examples/docker-stack/docker-compose.yaml +++ b/examples/docker-stack/docker-compose.yaml @@ -12,6 +12,8 @@ services: : image: ntnn/imapfilter environment: + PUID: 1001 + PGID: 1001 GIT_TARGET: IMAPFILTER_CONFIG: entry_.lua IMAPFILTER_DAEMON: 'yes' From 79e1d280c199e81794b5880ad947ac82842caa8a Mon Sep 17 00:00:00 2001 From: Vylyne <94922829+Vylyne@users.noreply.github.com> Date: Sat, 27 Sep 2025 12:17:30 -0400 Subject: [PATCH 7/7] Removed Upstream .github folder. DO NOT MERGE, OR PUSH TO UPSTREAM --- .github/dependabot.yml | 14 --- .github/renovate.json | 6 -- .github/workflows/image-build.yml | 99 ------------------- .github/workflows/wait-for-status-checks.yaml | 22 ----- 4 files changed, 141 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/renovate.json delete mode 100644 .github/workflows/image-build.yml delete mode 100644 .github/workflows/wait-for-status-checks.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index e52aed4..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -version: 2 - -updates: - - - package-ecosystem: github-actions - directory: / - schedule: - interval: weekly - - - package-ecosystem: docker - directory: / - schedule: - interval: "weekly" diff --git a/.github/renovate.json b/.github/renovate.json deleted file mode 100644 index 8327081..0000000 --- a/.github/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "local>ntnn/renovate-config" - ] -} diff --git a/.github/workflows/image-build.yml b/.github/workflows/image-build.yml deleted file mode 100644 index 5120273..0000000 --- a/.github/workflows/image-build.yml +++ /dev/null @@ -1,99 +0,0 @@ ---- -name: build - -on: - push: - branches: - - main - pull_request: - branches: - - main - schedule: - - cron: '0 3 * * *' - workflow_dispatch: - -jobs: - - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 - - uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0 - with: - dockerfile: Dockerfile - - grab-imapfilter-latest: - needs: lint - runs-on: ubuntu-latest - steps: - - id: imapfilter-latest-tag - run: | - # Can't find an endpoint that returns the latest tag - only - # the latest release. And since lefcha doesn't use GitHub's - # release feature the tags must be used. - tag="$(curl --location --silent https://api.github.com/repos/lefcha/imapfilter/tags | jq -r '.[].name' | head -1)" - echo "tag=$tag" >> "$GITHUB_OUTPUT" - outputs: - tag: ${{ steps.imapfilter-latest-tag.outputs.tag }} - - build: - needs: grab-imapfilter-latest - runs-on: ubuntu-latest - - strategy: - matrix: - include: - - flavor: | - latest=false - suffix= - args: - imapfilter_spec=master - - flavor: | - latest=false - suffix=-tag - args: | - imapfilter_spec=${{ needs.grab-imapfilter-latest.outputs.tag }} - - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 - - uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3 - with: - # Spurious segfaults when compiling - # https://github.com/docker/setup-qemu-action/issues/188 - image: tonistiigi/binfmt:qemu-v8.1.5 - - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3 - - - uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5 - id: meta - with: - flavor: ${{ matrix.flavor }} - images: | - name=ntnn/imapfilter,enable=${{ github.repository == 'ntnn/docker-imapfilter' && github.ref == 'refs/heads/main' }} - name=ghcr.io/${{ github.repository }},enable=true - tags: | - type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }} - type=raw,value=main,enable=${{ github.ref == 'refs/heads/main' }} - type=ref,event=branch - type=ref,event=pr - type=sha - - - name: Login to GitHub Container Registry - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Login to Docker Hub - uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3 - if: ${{ github.repository == 'ntnn/docker-imapfilter' && github.ref == 'refs/heads/main' }} - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_TOKEN }} - - - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6 - with: - tags: ${{ steps.meta.outputs.tags }} - push: true - platforms: linux/amd64,linux/arm64,linux/arm/v7 - build-args: ${{ matrix.args }} diff --git a/.github/workflows/wait-for-status-checks.yaml b/.github/workflows/wait-for-status-checks.yaml deleted file mode 100644 index 14fdf97..0000000 --- a/.github/workflows/wait-for-status-checks.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: wait-for-status-checks - -on: - pull_request: {} - -permissions: {} - -jobs: - # Branch protection rules can enforce that status checks must pass - # before merging - however it requires to name each check explicitly - # in the configuration. It is no longer possible to require all - # checks. - # This job waits for all checks to complete, so it can be set as - # _the_ required check in the branch protection rules. - wait-for-status-checks: - runs-on: ubuntu-latest - permissions: - checks: read - steps: - - uses: poseidon/wait-for-status-checks@899c768d191b56eef585c18f8558da19e1f3e707 # v0.6.0 - with: - token: ${{ secrets.GITHUB_TOKEN }}