diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5712451..c03c95f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -96,17 +96,19 @@ jobs: phishingclub \ phishingclub.sig - - name: Build and push production Docker image + - 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 }}:${{ steps.get_version.outputs.VERSION }} ghcr.io/${{ github.repository }}:latest + ghcr.io/${{ github.repository }}:${{ steps.get_version.outputs.VERSION }} labels: | - org.opencontainers.image.title=PhishingClub + 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 }} diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 885771e..4923f0e 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 }} 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"] 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: 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