From 8f02be6218a5315374818329eb844c7c83d88178 Mon Sep 17 00:00:00 2001 From: Ronni Skansing Date: Sun, 26 Oct 2025 10:45:08 +0100 Subject: [PATCH 1/5] add release Signed-off-by: Ronni Skansing --- .github/workflows/release.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6e42bce..c03c95f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -96,6 +96,25 @@ jobs: phishingclub \ phishingclub.sig + - name: Build and push release Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.release + push: true + platforms: linux/amd64 + tags: | + ghcr.io/${{ github.repository }}:latest + ghcr.io/${{ github.repository }}:${{ steps.get_version.outputs.VERSION }} + labels: | + org.opencontainers.image.title=PhishingClub ${{ steps.get_version.outputs.VERSION }} + org.opencontainers.image.description=PhishingClub production release image (linux/amd64). Built from tag ${{ steps.get_version.outputs.TAG }}. + org.opencontainers.image.url=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} + org.opencontainers.image.version=${{ steps.get_version.outputs.VERSION }} + org.opencontainers.image.created=${{ github.event.head_commit.timestamp }} + org.opencontainers.image.revision=${{ github.sha }} + - name: Extract release notes from RELEASE.md id: get_release_notes run: | From f6545dc2ccaa0339f801231981a7fbd0c14abb09 Mon Sep 17 00:00:00 2001 From: Ronni Skansing Date: Sun, 26 Oct 2025 10:45:35 +0100 Subject: [PATCH 2/5] add build Signed-off-by: Ronni Skansing --- .github/workflows/test-build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 9551c8b..add79dd 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -116,11 +116,12 @@ jobs: context: . file: ./Dockerfile.release push: true + platforms: linux/amd64 tags: | - ghcr.io/${{ github.repository }}:test-${{ steps.get_version.outputs.HASH }} ghcr.io/${{ github.repository }}:test-latest labels: | - org.opencontainers.image.title=PhishingClub-Test + org.opencontainers.image.title=PhishingClub-Test ${{ steps.get_version.outputs.VERSION }} + org.opencontainers.image.description=PhishingClub test build image (linux/amd64). Not for production deployment. org.opencontainers.image.url=${{ github.server_url }}/${{ github.repository }} org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} org.opencontainers.image.version=${{ steps.get_version.outputs.VERSION }} From 433994cb2889c6e77330e939190b6e189f0b6850 Mon Sep 17 00:00:00 2001 From: Ronni Skansing Date: Sun, 26 Oct 2025 10:46:20 +0100 Subject: [PATCH 3/5] update docker compose prod Signed-off-by: Ronni Skansing --- docker-compose.production.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.production.yml b/docker-compose.production.yml index 6da179c..2c35bbd 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -1,4 +1,3 @@ -# PhishingClub Production Docker Compose version: "3.8" services: From 4550e24866ef378b70ff00cd29e79f2266f7b514 Mon Sep 17 00:00:00 2001 From: Ronni Skansing Date: Sun, 26 Oct 2025 10:46:53 +0100 Subject: [PATCH 4/5] update docker release Signed-off-by: Ronni Skansing --- Dockerfile.release | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/Dockerfile.release b/Dockerfile.release index 5bdf9dd..70936d9 100644 --- a/Dockerfile.release +++ b/Dockerfile.release @@ -1,4 +1,3 @@ -# production dockerfile for release builds FROM debian:12-slim # install ca-certificates for https requests @@ -10,48 +9,21 @@ RUN apt-get update && \ RUN groupadd -g 1000 appuser && \ useradd -r -u 1000 -g appuser appuser -# create app and data directories +# set working directory WORKDIR /app -RUN mkdir -p /app/data && \ - mkdir -p /app/config # copy the binary from build context COPY build/phishingclub /app/phishingclub -# copy docker-friendly config -COPY config.docker.json /app/config.docker.json - -# create entrypoint script -RUN cat > /app/entrypoint.sh << 'EOF' -#!/bin/sh - -# check if config exists, if not use docker-friendly default -if [ ! -f /app/config/config.json ]; then - echo "🔧 No config found, using Docker-friendly default (non-privileged ports)..." - cp /app/config.docker.json /app/config/config.json - echo "✅ Docker config copied to /app/config/config.json" - echo "💡 You can mount your own config at /app/config/config.json to override" -fi - -# start the application -exec /app/phishingclub --config /app/config/config.json --files /app/data "$@" -EOF - -# make scripts executable +# make binary executable and set ownership RUN chmod +x /app/phishingclub && \ - chmod +x /app/entrypoint.sh + chown appuser:appuser /app/phishingclub -# change ownership to appuser -RUN chown -R appuser:appuser /app - -# switch to non-root user -USER appuser +# copy entrypoint script +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh # expose ports (using non-privileged ports by default) EXPOSE 8080 8443 8000 -# create volumes for config and data -VOLUME ["/app/config", "/app/data"] - -# use entrypoint script -ENTRYPOINT ["/app/entrypoint.sh"] +ENTRYPOINT ["/entrypoint.sh"] From bb33d64196e4759f0c36a222ddae1f005b0771d7 Mon Sep 17 00:00:00 2001 From: Ronni Skansing Date: Sun, 26 Oct 2025 10:48:04 +0100 Subject: [PATCH 5/5] add entrypoint Signed-off-by: Ronni Skansing --- entrypoint.sh | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 entrypoint.sh diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..4f17829 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# entrypoint for production docker compose + +# get appuser uid/gid dynamically, fallback to 1000 if not found +APP_UID=$(id -u appuser 2>/dev/null || echo 1000) +APP_GID=$(id -g appuser 2>/dev/null || echo 1000) + +# create default config.json with correct paths if missing +if [ ! -f /app/config/config.json ]; then + cat < /app/config/config.json +{ + "acme": { "email": "" }, + "administration": { + "tls_host": "localhost", + "tls_auto": false, + "tls_cert_path": "/app/config/certs/admin/public.pem", + "tls_key_path": "/app/config/certs/admin/private.pem", + "address": "0.0.0.0:8000", + "ip_allow_list": [] + }, + "phishing": { + "http": "0.0.0.0:8080", + "https": "0.0.0.0:8443" + }, + "database": { + "engine": "sqlite3", + "dsn": "file:/app/data/db.sqlite3" + }, + "log": { + "path": "", + "errorPath": "" + }, + "ip_security": { + "admin_allowed": [], + "trusted_proxies": [], + "trusted_ip_header": "" + } +} +EOF +fi + +# if running as root, fix permissions and switch to appuser +if [ "$(id -u)" = "0" ]; then + chown -R "$APP_UID:$APP_GID" /app/config /app/data 2>/dev/null || true + exec su appuser -c "/app/phishingclub --config /app/config/config.json" +else + exec /app/phishingclub --config /app/config/config.json +fi