diff --git a/.dockerignore b/.dockerignore index 70ed745..6c0c85f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -28,7 +28,5 @@ Thumbs.db # Misc (exclude all markdown except healthcheck.sh) *.md -!entrypoint.sh -!README.md .env .env.* diff --git a/.github/workflows/docker-hub-push.yml b/.github/workflows/docker-hub-push.yml index a845378..5c0eb5c 100644 --- a/.github/workflows/docker-hub-push.yml +++ b/.github/workflows/docker-hub-push.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 @@ -28,6 +28,13 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build date + id: date + run: | + BUILD_DATE=$(date +%Y%m%d) + echo "BUILD_DATE=$BUILD_DATE" >> $GITHUB_ENV + echo "Build date: $BUILD_DATE" + - name: Detect Gupax version from upstream id: version run: | @@ -40,29 +47,33 @@ jobs: SAFE_REF=$(echo "${{ github.ref_name }}" | tr '/' '-') # Tag strategy: # :latest / :2.0.1 / :v2.0.1 — moving, always latest build - # :v2.0.1-20260518 — date-stamped, immutable + # :v2.0.1-YYYYMMDD — date-stamped, immutable # : — commit-pinned, immutable if [ "${{ github.ref_name }}" = "main" ]; then - TAGS="${{ env.IMAGE_NAME }}:latest"$'\n'"${{ env.IMAGE_NAME }}:$VERSION_STRIPPED"$'\n'"${{ env.IMAGE_NAME }}:$VERSION"$'\n'"${{ env.IMAGE_NAME }}:${VERSION}-20260518"$'\n'"${{ env.IMAGE_NAME }}:${{ github.sha }}" + TAGS="${{ env.IMAGE_NAME }}:latest"$'\n'"${{ env.IMAGE_NAME }}:$VERSION_STRIPPED"$'\n'"${{ env.IMAGE_NAME }}:$VERSION"$'\n'"${{ env.IMAGE_NAME }}:${VERSION}-$BUILD_DATE"$'\n'"${{ env.IMAGE_NAME }}:${{ github.sha }}" else TAGS="${{ env.IMAGE_NAME }}:${SAFE_REF}"$'\n'"${{ env.IMAGE_NAME }}:${SAFE_REF}-${{ github.sha }}" fi echo "Tags: $TAGS" echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "BUILD_DATE=$BUILD_DATE" >> $GITHUB_ENV echo "TAGS<> $GITHUB_ENV - name: Build and push to Docker Hub uses: docker/build-push-action@v7 env: GUPAX_VERSION: ${{ env.VERSION }} + BUILD_DATE: ${{ env.BUILD_DATE }} with: context: . file: ./Dockerfile push: true platforms: linux/amd64 tags: ${{ env.TAGS }} - build-args: GUPAX_VERSION + build-args: | + GUPAX_VERSION + BUILD_DATE cache-from: type=gha cache-to: type=gha,mode=max provenance: mode=max - sbom: true + sbom: true \ No newline at end of file diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index c114cbe..79e9e6a 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set up QEMU uses: docker/setup-qemu-action@v4 @@ -33,39 +33,50 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build date + id: date + run: | + BUILD_DATE=$(date +%Y%m%d) + echo "BUILD_DATE=$BUILD_DATE" >> $GITHUB_ENV + echo "Build date: $BUILD_DATE" + - name: Detect Gupax version for tagging id: version run: | - VERSION=$(curl -s https://api.github.com/repos/gupax-io/gupax/releases/latest | python3 -c "import json,sys; print(json.load(sys.stdin)['tag_name'])") + VERSION=$(curl -s https://api.github.com/repos/gupax-io/gupax/releases/latest | python3 -c "import json,sys; print(json.load(sys.stdin)['tag_name'])" ) VERSION_STRIPPED="${VERSION#v}" echo "Detected Gupax version: $VERSION (tag: $VERSION_STRIPPED)" # Branch-aware tagging. Slashes -> hyphens (invalid in Docker tags). SAFE_REF=$(echo "${{ github.ref_name }}" | tr '/' '-') # Tag strategy: # :latest / :2.0.1 / :v2.0.1 — moving, always latest build - # :v2.0.1-20260518 — date-stamped, immutable + # :v2.0.1-YYYYMMDD — date-stamped, immutable # : — commit-pinned, immutable if [ "${{ github.ref_name }}" = "main" ]; then - TAGS="${{ env.IMAGE_NAME }}:latest"$'\n'"${{ env.IMAGE_NAME }}:$VERSION_STRIPPED"$'\n'"${{ env.IMAGE_NAME }}:$VERSION"$'\n'"${{ env.IMAGE_NAME }}:${VERSION}-20260518"$'\n'"${{ env.IMAGE_NAME }}:${{ github.sha }}" + TAGS="${{ env.IMAGE_NAME }}:latest"$'\n'"${{ env.IMAGE_NAME }}:$VERSION_STRIPPED"$'\n'"${{ env.IMAGE_NAME }}:$VERSION"$'\n'"${{ env.IMAGE_NAME }}:${VERSION}-$BUILD_DATE"$'\n'"${{ env.IMAGE_NAME }}:${{ github.sha }}" else TAGS="${{ env.IMAGE_NAME }}:${SAFE_REF}"$'\n'"${{ env.IMAGE_NAME }}:${SAFE_REF}-${{ github.sha }}" fi echo "Tags: $TAGS" echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "BUILD_DATE=$BUILD_DATE" >> $GITHUB_ENV echo "TAGS<> $GITHUB_ENV - name: Build and push Docker image uses: docker/build-push-action@v7 env: GUPAX_VERSION: ${{ env.VERSION }} + BUILD_DATE: ${{ env.BUILD_DATE }} with: context: . file: ./Dockerfile push: true platforms: linux/amd64 tags: ${{ env.TAGS }} - build-args: GUPAX_VERSION + build-args: | + GUPAX_VERSION + BUILD_DATE cache-from: type=gha cache-to: type=gha,mode=max provenance: mode=max - sbom: true + sbom: true \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a42b848..9487cd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). Versions follow the scheme `v{upstream-gupax}-{build-date}`. The base version tracks which Gupax release is bundled; the date suffix differentiates container -builds. `v2.0.1` and `v2.0.1+YYYYMMDD` tags are Docker image tags — the +builds. `v2.0.1` and `v2.0.1-YYYYMMDD` tags are Docker image tags — the `v`-prefixed tag is a moving tag that always points to the latest build of that upstream release. diff --git a/Dockerfile b/Dockerfile index b518245..54a2e95 100644 --- a/Dockerfile +++ b/Dockerfile @@ -87,7 +87,7 @@ RUN printf '#!/bin/sh\nexec sudo "$@"\n' > /usr/local/bin/pkexec \ # Install standalone Gupax (Gupax GUI only — binaries downloaded at runtime) # Gupax downloads P2Pool, XMRig, monerod, and xmrig-proxy internally. # Downloaded binaries are persisted in /home/miner/.local/share/gupax -# via a named volume (gupax-share) so they survive container restarts. +# via a named volume (gupax-data) so they survive container restarts. # ============================================================================= WORKDIR /tmp/install @@ -97,6 +97,7 @@ WORKDIR /tmp/install # For reproducibility, the SHA256 is fetched from upstream SHA256SUMS # at build time — the image build fails if verification fails. ARG GUPAX_VERSION=v2.0.1 +ARG BUILD_DATE=unknown RUN TARBALL="gupax-${GUPAX_VERSION}-linux-x64.tar.gz" \ && echo "[*] Downloading Gupax ${GUPAX_VERSION}..." \ && curl -fsSL "https://github.com/gupax-io/gupax/releases/download/${GUPAX_VERSION}/${TARBALL}" -o "${TARBALL}" \ @@ -111,12 +112,17 @@ RUN TARBALL="gupax-${GUPAX_VERSION}-linux-x64.tar.gz" \ && rm -rf "${TARBALL}" "${TARBALL}.sha256" SHA256SUMS "gupax-${GUPAX_VERSION}-linux-x64" /tmp/install # Labels -LABEL maintainer="libre-7" \ - description="Gupax — GUI for P2Pool + XMRig Monero mining in Docker (noVNC enabled, standalone binaries + optional Tor)" \ +LABEL org.opencontainers.image.title="gupax-docker" \ + org.opencontainers.image.description="noVNC-enabled Docker image for Gupax — GUI for P2Pool + XMRig Monero mining with optional Tor" \ + org.opencontainers.image.vendor="libre-7" \ + org.opencontainers.image.url="https://github.com/libre-7/gupax-docker" \ org.opencontainers.image.source="https://github.com/libre-7/gupax-docker" \ - org.opencontainers.image.icon="https://raw.githubusercontent.com/gupax-io/gupax/main/assets/images/icons/icon.png" \ - org.opencontainers.image.version="${GUPAX_VERSION}-20260518" \ + org.opencontainers.image.documentation="https://github.com/libre-7/gupax-docker" \ + org.opencontainers.image.version="${GUPAX_VERSION}-${BUILD_DATE}" \ org.opencontainers.image.licenses="GPL-3.0" \ + org.opencontainers.image.icon="https://raw.githubusercontent.com/gupax-io/gupax/main/assets/images/icons/icon.png" \ + maintainer="libre-7" \ + description="Gupax — GUI for P2Pool + XMRig Monero mining in Docker (noVNC enabled, standalone binaries + optional Tor)" \ gupax.version="${GUPAX_VERSION}" diff --git a/README.md b/README.md index 817f19f..8e3e50e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Docker Hub](https://img.shields.io/docker/pulls/libre7/gupax-docker?style=flat-square&color=blue&logo=docker)](https://hub.docker.com/r/libre7/gupax-docker) [![Image Size](https://img.shields.io/docker/image-size/libre7/gupax-docker/latest?style=flat-square&logo=docker&color=blueviolet)](https://hub.docker.com/r/libre7/gupax-docker) -> Docker packaging for [Gupax](https://github.com/hinto-janai/gupax) — the GUI that unites [P2Pool](https://github.com/SChernykh/p2pool) and [XMRig](https://github.com/xmrig/xmrig) for easy, decentralized Monero mining. Optional built-in **🧅 Tor hidden service** for private transaction relay. +> Docker packaging for [Gupax](https://github.com/gupax-io/gupax) — the GUI that unites [P2Pool](https://github.com/SChernykh/p2pool) and [XMRig](https://github.com/xmrig/xmrig) for easy, decentralized Monero mining. Optional built-in **🧅 Tor hidden service** for private transaction relay. **Self-contained with noVNC** — access the Gupax GUI directly from your web browser. No X11 server or additional setup needed. @@ -280,7 +280,7 @@ If you have an existing Monero blockchain on your Unraid server: | `MONERO_DATA_PATH` | No | `gupax-monero` | Path (volume name or host path) for Monero blockchain data | | `SCREEN_RESOLUTION` | No | `1920x1080x24` | Resolution for the virtual X display (WxHxD format) | -> **Note:** `GUPAX_VERSION` and `GUPAX_SHA256` are managed automatically by the CI workflow — no manual configuration needed. The Docker image is always built with the latest detected upstream Gupax version. +> **Note:** `GUPAX_VERSION` is managed automatically by the CI workflow — no manual configuration needed. The Docker image is always built with the latest detected upstream Gupax version. ### Ports @@ -468,7 +468,7 @@ P2Pool get_info RPC request to host 127.0.0.1:RPC 18081:ZMQ 18083 failed: Error ## 🔗 Official Resources -- [Gupax](https://github.com/hinto-janai/gupax) — The GUI unifying P2Pool & XMRig +- [Gupax](https://github.com/gupax-io/gupax) — The GUI unifying P2Pool & XMRig - [P2Pool](https://github.com/SChernykh/p2pool) — Decentralized Monero mining pool - [XMRig](https://github.com/xmrig/xmrig) — High-performance Monero miner - [Monero](https://www.getmonero.org/) — Private, decentralized cryptocurrency diff --git a/TODO.md b/TODO.md index 890276f..4be9489 100644 --- a/TODO.md +++ b/TODO.md @@ -13,7 +13,8 @@ - [x] **Blockchain volume** — Mount existing Monero blockchain at `/home/miner/.bitmonero` - [x] **PR test pipeline** — Lint (shellcheck + hadolint + yamllint) + smoke test on PRs - [x] **GHCR + Docker Hub CI** — Image builds pushed to both registries on merge to main -- [ ] **Multi-arch builds** — Support `linux/arm64` if Gupax provides arm64 binary +- [x] **Multi-arch builds** — Support `linux/arm64` if Gupax provides arm64 binary +- [x] **CONTRIBUTING.md** — How to submit PRs and report issues - [ ] **X11 troubleshooting docs** — Expand troubleshooting for common noVNC issues - [ ] **GitHub Releases** — Tagged releases with release notes @@ -30,7 +31,7 @@ - [x] **README.md** — Quick Start, noVNC setup, configuration, troubleshooting - [x] **CHANGELOG.md** — Track changes per release -- [ ] **CONTRIBUTING.md** — How to submit PRs and report issues + - [ ] **GitHub Issues templates** — Bug report and feature request templates ## 🧪 Testing & Validation