Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions .docker/app/Dockerfile.35
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
ARG NEXTCLOUD_BASE_IMAGE=nextcloud:34-fpm

ARG NEXTCLOUD_BASE_IMAGE
FROM ${NEXTCLOUD_BASE_IMAGE}

Check warning on line 2 in .docker/app/Dockerfile.35

View workflow job for this annotation

GitHub Actions / Build and scan stable35

Default value for global ARG results in an empty or invalid base image name

InvalidDefaultArgInFrom: Default value for ARG ${NEXTCLOUD_BASE_IMAGE} results in empty or invalid base image name More info: https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/

Check warning on line 2 in .docker/app/Dockerfile.35

View workflow job for this annotation

GitHub Actions / Build and scan stable35

Default value for global ARG results in an empty or invalid base image name

InvalidDefaultArgInFrom: Default value for ARG ${NEXTCLOUD_BASE_IMAGE} results in empty or invalid base image name More info: https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/

Check warning on line 2 in .docker/app/Dockerfile.35

View workflow job for this annotation

GitHub Actions / Build and scan main

Default value for global ARG results in an empty or invalid base image name

InvalidDefaultArgInFrom: Default value for ARG ${NEXTCLOUD_BASE_IMAGE} results in empty or invalid base image name More info: https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/

Check warning on line 2 in .docker/app/Dockerfile.35

View workflow job for this annotation

GitHub Actions / Build and scan main

Default value for global ARG results in an empty or invalid base image name

InvalidDefaultArgInFrom: Default value for ARG ${NEXTCLOUD_BASE_IMAGE} results in empty or invalid base image name More info: https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/

ARG NEXTCLOUD_DAILY_URL=https://download.nextcloud.com/server/daily/latest-master.tar.bz2
ARG NEXTCLOUD_DAILY_URL
ARG EXPECTED_NEXTCLOUD_MAJOR=
ARG PHP_EXTENSION_INSTALLER_VERSION=2.12.0
ARG PHP_EXTENSION_INSTALLER_SHA256=3f49c71fa66c79b8b2b96bc0ce92885dafd7946f3b5a46f545b390d6f1617e2c

RUN set -eux; \
curl -fsSL "${NEXTCLOUD_DAILY_URL}" -o /tmp/nextcloud.tar.bz2; \
curl -fsSL "${NEXTCLOUD_DAILY_URL}.sha512" -o /tmp/nextcloud.tar.bz2.sha512; \
archive_name="$(basename "${NEXTCLOUD_DAILY_URL}")"; \
curl -fsSL "${NEXTCLOUD_DAILY_URL}" -o "/tmp/${archive_name}"; \
curl -fsSL "${NEXTCLOUD_DAILY_URL}.sha512" -o "/tmp/${archive_name}.sha512"; \
cd /tmp; \
expected_sha512="$(awk '$2 == "latest-master.tar.bz2" { print $1 }' nextcloud.tar.bz2.sha512)"; \
expected_sha512="$(awk -v archive="${archive_name}" '$2 == archive { print $1 }' "${archive_name}.sha512")"; \
test -n "${expected_sha512}"; \
echo "${expected_sha512} nextcloud.tar.bz2" | sha512sum -c -; \
echo "${expected_sha512} ${archive_name}" | sha512sum -c -; \
rm -rf /usr/src/nextcloud; \
tar -xjf nextcloud.tar.bz2 -C /usr/src/; \
tar -xjf "${archive_name}" -C /usr/src/; \
nextcloud_major="$(php -r 'require "/usr/src/nextcloud/version.php"; echo $OC_Version[0];')"; \
test "${nextcloud_major}" = 35; \
rm -f /tmp/nextcloud.tar.bz2 /tmp/nextcloud.tar.bz2.sha512; \
if [ -n "${EXPECTED_NEXTCLOUD_MAJOR}" ]; then test "${nextcloud_major}" = "${EXPECTED_NEXTCLOUD_MAJOR}"; fi; \
rm -f "/tmp/${archive_name}" "/tmp/${archive_name}.sha512"; \
rm -rf /usr/src/nextcloud/updater; \
mkdir -p /usr/src/nextcloud/data /usr/src/nextcloud/custom_apps; \
chmod +x /usr/src/nextcloud/occ
Expand All @@ -33,8 +36,12 @@
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod uga+x /usr/local/bin/install-php-extensions && sync \
&& install-php-extensions bz2 imagick
RUN set -eux; \
curl -fsSL \
"https://github.com/mlocati/docker-php-extension-installer/releases/download/${PHP_EXTENSION_INSTALLER_VERSION}/install-php-extensions" \
-o /usr/local/bin/install-php-extensions; \
echo "${PHP_EXTENSION_INSTALLER_SHA256} /usr/local/bin/install-php-extensions" | sha256sum -c -; \
chmod uga+x /usr/local/bin/install-php-extensions; \
install-php-extensions bz2 imagick

COPY config/php.ini /usr/local/etc/php/conf.d/
175 changes: 155 additions & 20 deletions .github/workflows/nextcloud-35-development.yml
Original file line number Diff line number Diff line change
@@ -1,52 +1,187 @@
name: Build Nextcloud 35 Development Image
name: Build Nextcloud Development Images

on:
workflow_dispatch:
schedule:
- cron: '17 3 * * *'
pull_request:
branches:
- main
paths:
- '.docker/app/Dockerfile.35'
- '.docker/app/config/**'
- '.github/workflows/nextcloud-35-development.yml'
- 'scripts/scan-images.sh'
- 'trivy.yaml'
push:
branches:
- main
paths:
- .docker/app/Dockerfile.35
- .docker/app/config/**
- .github/workflows/nextcloud-35-development.yml
- '.docker/app/Dockerfile.35'
- '.docker/app/config/**'
- '.github/workflows/nextcloud-35-development.yml'
- 'scripts/scan-images.sh'
- 'trivy.yaml'

concurrency:
group: nextcloud-35-development
group: nextcloud-development-${{ github.event_name }}-${{ github.ref }}
cancel-in-progress: true

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}-app

jobs:
build:
name: Build and push app:35
name: Build and scan ${{ matrix.channel }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

strategy:
fail-fast: false
matrix:
include:
- channel: stable35
base_tag: 35-fpm
daily_url: https://download.nextcloud.com/server/daily/latest-stable35.tar.bz2
expected_major: '35'
primary_tag: '35'
alias_tag: stable35
- channel: main
base_tag: stable-fpm
daily_url: https://download.nextcloud.com/server/daily/latest-master.tar.bz2
expected_major: ''
primary_tag: main
alias_tag: ''

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Set up QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3

- name: Resolve upstream base image digest
id: base
shell: bash
env:
BASE_TAG: ${{ matrix.base_tag }}
run: |
set -euo pipefail
token="$(curl -fsSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/nextcloud:pull" | jq -r '.token')"
test -n "${token}"

headers="$(mktemp)"
curl -fsSLI \
-H "Authorization: Bearer ${token}" \
-H 'Accept: application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json' \
-D "${headers}" \
-o /dev/null \
"https://registry-1.docker.io/v2/library/nextcloud/manifests/${BASE_TAG}"

digest="$(awk 'BEGIN { IGNORECASE=1 } /^docker-content-digest:/ { gsub("\r", "", $2); print $2; exit }' "${headers}")"
if [[ ! "${digest}" =~ ^sha256:[0-9a-f]{64}$ ]]; then
echo "Could not resolve immutable digest for nextcloud:${BASE_TAG}" >&2
exit 1
fi

echo "image=nextcloud@${digest}" >> "${GITHUB_OUTPUT}"
echo "Resolved nextcloud:${BASE_TAG} to ${digest}"

- name: Build development app image (linux/amd64)
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .docker/app
file: .docker/app/Dockerfile.35
platforms: linux/amd64
load: true
build-args: |
NEXTCLOUD_BASE_IMAGE=${{ steps.base.outputs.image }}
NEXTCLOUD_DAILY_URL=${{ matrix.daily_url }}
EXPECTED_NEXTCLOUD_MAJOR=${{ matrix.expected_major }}
tags: scan/development-${{ matrix.channel }}:amd64
cache-from: type=gha,scope=development-${{ matrix.channel }}-amd64
cache-to: type=gha,mode=max,scope=development-${{ matrix.channel }}-amd64

- name: Build development app image (linux/arm64)
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .docker/app
file: .docker/app/Dockerfile.35
platforms: linux/arm64
load: true
build-args: |
NEXTCLOUD_BASE_IMAGE=${{ steps.base.outputs.image }}
NEXTCLOUD_DAILY_URL=${{ matrix.daily_url }}
EXPECTED_NEXTCLOUD_MAJOR=${{ matrix.expected_major }}
tags: scan/development-${{ matrix.channel }}:arm64
cache-from: type=gha,scope=development-${{ matrix.channel }}-arm64
cache-to: type=gha,mode=max,scope=development-${{ matrix.channel }}-arm64

- name: Install Trivy
uses: aquasecurity/setup-trivy@81e514348e19b6112ce2a7e3ecbafe19c1e1f567 # v0.3.1
with:
version: v0.74.0
cache: true

- name: Scan development images
shell: bash
env:
CHANNEL: ${{ matrix.channel }}
run: |
set -euo pipefail
TRIVY_REPORT_DIR="trivy-results/${CHANNEL}" bash scripts/scan-images.sh "app@linux/amd64=scan/development-${CHANNEL}:amd64" "app@linux/arm64=scan/development-${CHANNEL}:arm64"

- name: Normalize repository name
if: github.event_name != 'pull_request'
id: repo_name
shell: bash
run: echo "value=${GITHUB_REPOSITORY,,}" >> "${GITHUB_OUTPUT}"

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
if: github.event_name != 'pull_request'
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Nextcloud 35 development image
uses: docker/build-push-action@v6
with:
context: .docker/app
file: .docker/app/Dockerfile.35
platforms: linux/amd64
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:35
cache-from: type=gha,scope=nextcloud-35-development
cache-to: type=gha,mode=max,scope=nextcloud-35-development
- name: Push scanned architecture images
if: github.event_name != 'pull_request'
shell: bash
env:
APP_IMAGE: ${{ env.REGISTRY }}/${{ steps.repo_name.outputs.value }}-app
CHANNEL: ${{ matrix.channel }}
run: |
set -euo pipefail
image_version="development-${CHANNEL}-${GITHUB_SHA}"

docker tag "scan/development-${CHANNEL}:amd64" "${APP_IMAGE}:${image_version}-amd64"
docker tag "scan/development-${CHANNEL}:arm64" "${APP_IMAGE}:${image_version}-arm64"

docker push "${APP_IMAGE}:${image_version}-amd64"
docker push "${APP_IMAGE}:${image_version}-arm64"

- name: Publish multi-platform development tags
if: github.event_name != 'pull_request'
shell: bash
env:
APP_IMAGE: ${{ env.REGISTRY }}/${{ steps.repo_name.outputs.value }}-app
CHANNEL: ${{ matrix.channel }}
PRIMARY_TAG: ${{ matrix.primary_tag }}
ALIAS_TAG: ${{ matrix.alias_tag }}
run: |
set -euo pipefail
image_version="development-${CHANNEL}-${GITHUB_SHA}"
tag_args=(--tag "${APP_IMAGE}:${PRIMARY_TAG}")
if [ -n "${ALIAS_TAG}" ]; then
tag_args+=(--tag "${APP_IMAGE}:${ALIAS_TAG}")
fi

docker buildx imagetools create "${tag_args[@]}" "${APP_IMAGE}:${image_version}-amd64" "${APP_IMAGE}:${image_version}-arm64"
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@ docker compose build --pull
docker compose up -d
```

## Development images

The development workflow maintains rolling app images for Nextcloud stable35 and the upstream main branch. It builds amd64 and arm64 images, runs the same Trivy policy used by this repository, and only publishes images after the scan succeeds.

The stable35 channel publishes tags `35` and `stable35`. The rolling upstream channel publishes `main`. These tags are separate from the normal runtime `latest` image.

## Vulnerability scanning

Published `app` and `web` images are scanned for vulnerabilities. Contributors
Expand All @@ -275,4 +281,4 @@ app_1 | 2020-04-28T19:49:38.577733913Z Upgrading nextcloud from 18.0.3.0 ..

## Talk

For setting up Nextcloud Talk with all services, see [here](https://github.com/LibreCodeCoop/nextcloud-docker-talk).
For setting up Nextcloud Talk with all services, see [here](https://github.com/LibreCodeCoop/nextcloud-docker-talk).
Loading