diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b41e08c..12f186f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,8 +24,15 @@ jobs: docker-build-args: | VERSION=${{ matrix.release.version }} REVISION=${{ github.sha }} + docker-cache-from: type=gha + docker-cache-to: type=gha,mode=max trivy-ignore-files: .trivyignore,${{ matrix.release.dir }}/.trivyignore docker-extra-tags: ${{ matrix.release.extra-tags }} + smoke-test-port: "9200" + smoke-test-url: "https://localhost:9200/status.php" + smoke-test-entrypoint-cmd: "ocis init || true; exec ocis server" + smoke-test-env: "OCIS_INSECURE=true" + smoke-test-version-jq: ".productversion" push: false secrets: docker-hub-password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -33,11 +40,6 @@ jobs: strategy: matrix: release: - - version: "7.3.2" - dir: "v7" - extra-tags: | - 7.3 - 7 - version: "8.0.1" dir: "v8" extra-tags: | diff --git a/.gitignore b/.gitignore index 482e34b..e01c188 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .DS_Store *.swp *.swo +.claude/ +docs/ diff --git a/README.md b/README.md index e285cbb..40de170 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,6 @@ docker run --rm \ | Tag | oCIS Version | |-----|-------------| | `8.0.1` | 8.0.1 | -| `7.3.2` | 7.3.2 | ## Volumes @@ -37,8 +36,40 @@ docker run --rm \ | ARG | Default | Purpose | |-----|---------|---------| -| `VERSION` | version-specific | oCIS release to embed | +| `VERSION` | version-specific | oCIS git tag to clone and build (without `v` prefix, e.g. `8.0.1`) | | `REVISION` | `""` | Git SHA embedded in OCI labels | +| `TARGETARCH` | set by buildx | Target architecture (`amd64`, `arm64`) | + +## Building + +The image is built entirely from source via a three-stage Dockerfile: + +**`node-builder`** — clones the oCIS git repository at `v${VERSION}`, builds the IDP React frontend (`pnpm build`) and downloads the web frontend assets (`make pull-assets`). Both are required at compile time because `services/idp` and `services/web` use `//go:embed`. + +**`go-builder`** — compiles the oCIS binary with CGO and libvips enabled using the upstream Makefile target `release-linux-docker-${TARGETARCH}`. Outputs to `dist/binaries/ocis-linux-${TARGETARCH}`. + +**Runtime** — minimal Alpine image with the binary copied from `go-builder`. + +To build locally: + +```bash +docker buildx build \ + --build-arg VERSION=8.0.1 \ + --build-arg REVISION=$(git rev-parse HEAD) \ + --platform linux/amd64 \ + -f v8/Dockerfile.multiarch v8/ +``` + +## CI + +The GitHub Actions workflow (`.github/workflows/main.yml`) builds and validates the image on every push, pull request, and weekly schedule. + +**Steps per release matrix entry:** + +1. **Build** — multi-arch image (`linux/amd64`, `linux/arm64`) pushed to an ephemeral local registry using BuildKit with GHA layer cache. +2. **Trivy scan** — scans for HIGH/CRITICAL CVEs; unfixable upstream CVEs are listed in `v8/.trivyignore`. +3. **Smoke test** — starts the container, polls `https://localhost:9200/status.php` every 2s for up to 62s, and verifies the `.productversion` field in the JSON response matches the built tag. Uses `OCIS_INSECURE=true` to allow self-signed TLS on the test runner. +4. **Publish** — pushes to Docker Hub with floating major/minor tags (on `master` only). ## License diff --git a/v7/.trivyignore b/v7/.trivyignore deleted file mode 100644 index 80ce25d..0000000 --- a/v7/.trivyignore +++ /dev/null @@ -1,35 +0,0 @@ -# CVEs in the oCIS 7.3.2 binary (Go dependencies). Unfixable by this repo — requires upstream owncloud/ocis release. - -# github.com/go-acme/lego/v4 v4.25.2 -CVE-2026-40611 exp:2026-10-22 - -# github.com/go-jose/go-jose/v3 v3.0.4 -CVE-2026-34986 exp:2026-10-22 - -# github.com/nats-io/nats-server/v2 v2.12.0 -CVE-2026-27889 exp:2026-10-22 -CVE-2026-29785 exp:2026-10-22 -CVE-2026-33216 exp:2026-10-22 -CVE-2026-33217 exp:2026-10-22 -CVE-2026-33218 exp:2026-10-22 -CVE-2026-33247 exp:2026-10-22 - -# github.com/russellhaering/goxmldsig v1.5.0 -CVE-2026-33487 exp:2026-10-22 - -# go.opentelemetry.io/otel/sdk v1.38.0 -CVE-2026-24051 exp:2026-10-22 -CVE-2026-39883 exp:2026-10-22 - -# google.golang.org/grpc v1.75.1 -CVE-2026-33186 exp:2026-10-22 - -# stdlib v1.24.10 -CVE-2025-68121 exp:2026-10-22 -CVE-2025-61726 exp:2026-10-22 -CVE-2025-61728 exp:2026-10-22 -CVE-2025-61729 exp:2026-10-22 -CVE-2026-25679 exp:2026-10-22 -CVE-2026-32280 exp:2026-10-22 -CVE-2026-32281 exp:2026-10-22 -CVE-2026-32283 exp:2026-10-22 diff --git a/v7/Dockerfile.multiarch b/v7/Dockerfile.multiarch deleted file mode 100644 index 5ddd9d4..0000000 --- a/v7/Dockerfile.multiarch +++ /dev/null @@ -1,57 +0,0 @@ -FROM docker.io/alpine:3.23.4@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 AS downloader - -ARG VERSION="7.3.2" -ARG TARGETARCH - -RUN apk add --no-cache curl - -RUN BASE_URL="https://github.com/owncloud/ocis/releases/download/v${VERSION}" && \ - curl -fsSL "${BASE_URL}/ocis-${VERSION}-linux-${TARGETARCH}" -o /usr/bin/ocis && \ - curl -fsSL "${BASE_URL}/ocis-${VERSION}-linux-${TARGETARCH}.sha256" -o /tmp/ocis.sha256 && \ - EXPECTED=$(awk '{print $1}' /tmp/ocis.sha256) && \ - echo "${EXPECTED} /usr/bin/ocis" | sha256sum -c - && \ - chmod +x /usr/bin/ocis - -FROM docker.io/alpine:3.23.4@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 - -ARG VERSION="" -ARG REVISION="" - -LABEL maintainer="ownCloud GmbH " \ - org.opencontainers.image.title="ownCloud Infinite Scale" \ - org.opencontainers.image.vendor="ownCloud GmbH" \ - org.opencontainers.image.authors="ownCloud GmbH" \ - org.opencontainers.image.description="oCIS - ownCloud Infinite Scale is a modern file-sync and share platform" \ - org.opencontainers.image.licenses="Apache-2.0" \ - org.opencontainers.image.documentation="https://github.com/owncloud/ocis" \ - org.opencontainers.image.url="https://hub.docker.com/r/owncloud/ocis" \ - org.opencontainers.image.source="https://github.com/owncloud/ocis" \ - org.opencontainers.image.version="${VERSION}" \ - org.opencontainers.image.revision="${REVISION}" - -RUN apk add --no-cache attr bash ca-certificates curl inotify-tools libc6-compat mailcap tree vips patch && \ - echo 'hosts: files dns' >| /etc/nsswitch.conf - -RUN addgroup -g 1000 -S ocis-group && \ - adduser -S --ingroup ocis-group --uid 1000 ocis-user --home /var/lib/ocis - -RUN mkdir -p /var/lib/ocis && \ - chown -R ocis-user:ocis-group /var/lib/ocis && \ - chmod -R 751 /var/lib/ocis && \ - mkdir -p /etc/ocis && \ - chown -R ocis-user:ocis-group /etc/ocis && \ - chmod -R 751 /etc/ocis - -COPY --from=downloader /usr/bin/ocis /usr/bin/ocis - -VOLUME [ "/var/lib/ocis", "/etc/ocis" ] - -WORKDIR /var/lib/ocis - -USER 1000 - -EXPOSE 9200/tcp - -ENTRYPOINT ["/usr/bin/ocis"] - -CMD ["server"] diff --git a/v8/.trivyignore b/v8/.trivyignore index 0b6db4c..88b0be4 100644 --- a/v8/.trivyignore +++ b/v8/.trivyignore @@ -19,6 +19,7 @@ CVE-2026-33487 exp:2026-10-22 # go.opentelemetry.io/otel/sdk v1.39.0 CVE-2026-24051 exp:2026-10-22 +CVE-2026-29181 exp:2026-10-22 CVE-2026-39883 exp:2026-10-22 # google.golang.org/grpc v1.78.0 diff --git a/v8/Dockerfile.multiarch b/v8/Dockerfile.multiarch index 979ea63..0d63b8d 100644 --- a/v8/Dockerfile.multiarch +++ b/v8/Dockerfile.multiarch @@ -1,21 +1,43 @@ -FROM docker.io/alpine:3.23.4@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 AS downloader +FROM docker.io/alpine:3.23.4@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 AS node-builder + +ARG VERSION="8.0.1" + +RUN apk add --no-cache bash nodejs npm curl git make + +RUN npm install -g pnpm@10.28.1 + +RUN git clone --depth 1 --branch "v${VERSION}" https://github.com/owncloud/ocis.git /build + +WORKDIR /build/services/idp +RUN pnpm install --frozen-lockfile +RUN pnpm build +RUN curl -fsSL https://raw.githubusercontent.com/owncloud/assets/main/favicon.ico \ + -o assets/identifier/static/favicon.ico + +WORKDIR /build/services/web +RUN make pull-assets + + +FROM docker.io/alpine:3.23.4@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 AS go-builder ARG VERSION="8.0.1" ARG TARGETARCH -RUN apk add --no-cache curl +RUN apk add --no-cache bash go gcc musl-dev vips-dev curl-dev make git + +COPY --from=node-builder /build /build + +WORKDIR /build/ocis + +RUN CGO_ENABLED=1 ENABLE_VIPS=true \ + make release-linux-docker-${TARGETARCH} VERSION=${VERSION} -RUN BASE_URL="https://github.com/owncloud/ocis/releases/download/v${VERSION}" && \ - curl -fsSL "${BASE_URL}/ocis-${VERSION}-linux-${TARGETARCH}" -o /usr/bin/ocis && \ - curl -fsSL "${BASE_URL}/ocis-${VERSION}-linux-${TARGETARCH}.sha256" -o /tmp/ocis.sha256 && \ - EXPECTED=$(awk '{print $1}' /tmp/ocis.sha256) && \ - echo "${EXPECTED} /usr/bin/ocis" | sha256sum -c - && \ - chmod +x /usr/bin/ocis FROM docker.io/alpine:3.23.4@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11 ARG VERSION="" ARG REVISION="" +ARG TARGETARCH LABEL maintainer="ownCloud GmbH " \ org.opencontainers.image.title="ownCloud Infinite Scale" \ @@ -42,7 +64,7 @@ RUN mkdir -p /var/lib/ocis && \ chown -R ocis-user:ocis-group /etc/ocis && \ chmod -R 751 /etc/ocis -COPY --from=downloader /usr/bin/ocis /usr/bin/ocis +COPY --from=go-builder /build/ocis/dist/binaries/ocis-linux-${TARGETARCH} /usr/bin/ocis VOLUME [ "/var/lib/ocis", "/etc/ocis" ]