Skip to content
Merged
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
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.gitignore
.github
140 changes: 72 additions & 68 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ env:
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}
# Set SSP_VERSION from tag if present, else fetch latest
SSP_VERSION: ${{ github.ref_type == 'tag' && github.ref_name || '' }}
# Set VERSION from tag if present, else fetch latest
VERSION: ${{ github.ref_type == 'tag' && github.ref_name || '' }}


jobs:
Expand All @@ -29,19 +29,21 @@ jobs:
permissions:
contents: read
outputs:
SSP_VERSION: ${{ steps.determine_ssp_version.outputs.SSP_VERSION }}
VERSION: ${{ steps.determine_version.outputs.VERSION }}
steps:
- name: Determine SimpleSAMLphp version
id: determine_ssp_version
- name: Determine Moodle version
id: determine_version
run: |
if [ -z "${SSP_VERSION}" ]; then
LATEST=$(curl -s https://api.github.com/repos/simplesamlphp/simplesamlphp/releases/latest | jq -r .tag_name | sed 's/^v//')
echo "SSP_VERSION=$LATEST" >> $GITHUB_OUTPUT
if [ -z "${VERSION}" ]; then
# Fetch all tags, filter for stable releases, sort, and pick the highest
TAGS=$(curl -s "https://api.github.com/repos/moodle/moodle/tags?per_page=1000" | jq -r '.[].name' | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | sed 's/^v//')
LATEST=$(echo "$TAGS" | sort -V | tail -n1)
echo "VERSION=$LATEST" >> $GITHUB_OUTPUT
else
echo "SSP_VERSION=${SSP_VERSION#v}" >> $GITHUB_OUTPUT
echo "VERSION=${VERSION#v}" >> $GITHUB_OUTPUT
fi
env:
SSP_VERSION: ${{ env.SSP_VERSION }}
VERSION: ${{ env.VERSION }}

docker:
needs: prepare
Expand All @@ -59,7 +61,7 @@ jobs:
# with sigstore/fulcio when running outside of PRs.
id-token: write
env:
SSP_VERSION: ${{ needs.prepare.outputs.SSP_VERSION }}
VERSION: ${{ needs.prepare.outputs.VERSION }}

steps:
- name: Set platform pair
Expand All @@ -85,44 +87,41 @@ jobs:
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3

- name: Ensure COMPOSER_HOME exists
run: mkdir -p "$HOME/.composer"

- name: Install composer/semver
run: composer global require composer/semver
env:
COMPOSER_HOME: $HOME/.composer

- name: Download SimpleSAMLphp release
run: |
curl -L https://github.com/simplesamlphp/simplesamlphp/releases/download/v${{ env.SSP_VERSION }}/simplesamlphp-${{ env.SSP_VERSION }}-full.tar.gz --output simplesamlphp-version-full.tar.gz
working-directory: ${{ github.workspace }}
- name: Extract composer.json
- name: Parse Moodle major and minor version
id: parse_version
run: |
tar -xzf simplesamlphp-version-full.tar.gz simplesamlphp-${{ env.SSP_VERSION }}/composer.json --strip-components=1
working-directory: ${{ github.workspace }}
- name: Determine latest supported PHP version
VERSION="${{ env.VERSION }}"
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
MINOR_PADDED=$(printf "%02d" "$MINOR")
echo "MAJOR=$MAJOR" >> $GITHUB_OUTPUT
echo "MINOR=$MINOR_PADDED" >> $GITHUB_OUTPUT
- name: Checkout Moodle repository
uses: actions/checkout@v3
with:
repository: moodle/moodle
ref: MOODLE_${{ steps.parse_version.outputs.MAJOR }}${{ steps.parse_version.outputs.MINOR }}_STABLE
path: moodle-src
- name: Determine required PHP version
id: php_version
run: |
export PATH="$PATH:$HOME/.composer/vendor/bin"
PHP_CONSTRAINT=$(jq -r '.require.php' composer.json)
# Get all PHP tags from Docker Hub (paginated, up to 1000 tags)
TAGS=$(curl -s 'https://registry.hub.docker.com/v2/repositories/library/php/tags?page_size=1000' | jq -r '.results[].name')
# Filter for fpm-alpine tags and extract version numbers
VERSIONS=$(echo "$TAGS" | grep -E '^[0-9]+\.[0-9]+(\.[0-9]+)?-fpm-alpine$' | sed 's/-fpm-alpine//' | sort -V)
# Use composer/semver to find the highest matching version
MATCH=$(echo "$VERSIONS" | xargs -I{} semver "$PHP_CONSTRAINT" {} | tail -n1)
if [ -z "$MATCH" ]; then
# fallback to highest version if no match
PHP_VERSION=$(echo "$VERSIONS" | tail -n1)
else
PHP_VERSION=$MATCH
# Parse minimum PHP version from moodle-src/lib/phpminimumversionlib.php
MIN_PHP=$(grep "minimumversion" moodle-src/lib/phpminimumversionlib.php | head -1 | sed -E \
-e "s/.*'(.*)'.*/\1/")
echo "Minimum required PHP version: $MIN_PHP"
# Extract the major.minor part
PHP_SERIES=$(echo "$MIN_PHP" | awk -F. '{print $1 "." $2}')
# Fetch all PHP versions from Docker Hub
PHP_TAGS=$(curl -s 'https://registry.hub.docker.com/v2/repositories/library/php/tags?page_size=1000' | jq -r '.results[].name' | grep -E "^$PHP_SERIES\\.[0-9]+-fpm-alpine$" | sed 's/-fpm-alpine//')
# Select the highest bugfix version in the required series
SELECTED_PHP=$(echo "$PHP_TAGS" | sort -V | tail -n1)
if [ -z "$SELECTED_PHP" ]; then
# Fallback: use the minimum required
SELECTED_PHP="$MIN_PHP"
fi
echo "PHP_VERSION=$PHP_VERSION" >> $GITHUB_ENV
echo "php_version=$PHP_VERSION" >> $GITHUB_OUTPUT
working-directory: ${{ github.workspace }}
env:
COMPOSER_HOME: $HOME/.composer
echo "Selected PHP version: $SELECTED_PHP"
echo "PHP_VERSION=$SELECTED_PHP" >> $GITHUB_OUTPUT
echo "PHP_VERSION=$SELECTED_PHP" >> $GITHUB_ENV

# Login against a Docker registry except on PR
# https://github.com/docker/login-action
Expand All @@ -146,6 +145,9 @@ jobs:
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx

- name: Remove .git folder
run: rm -rf moodle-src/.git

# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
Expand All @@ -157,7 +159,7 @@ jobs:
platforms: ${{ matrix.platform }}
target: php
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.SSP_VERSION }}-${{ steps.set_platform_pair.outputs.platform_pair }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.VERSION }}-${{ steps.set_platform_pair.outputs.platform_pair }}
labels: ${{ steps.meta-php.outputs.labels }}
outputs: type=image,push=${{ github.event_name != 'pull_request' }}
file: ./Dockerfile
Expand All @@ -171,7 +173,7 @@ jobs:
platforms: ${{ matrix.platform }}
target: nginx
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.SSP_VERSION }}-${{ steps.set_platform_pair.outputs.platform_pair }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.VERSION }}-${{ steps.set_platform_pair.outputs.platform_pair }}
labels: ${{ steps.meta-nginx.outputs.labels }}
outputs: type=image,push=${{ github.event_name != 'pull_request' }}
file: ./Dockerfile
Expand Down Expand Up @@ -204,7 +206,7 @@ jobs:
contents: read
packages: write
env:
SSP_VERSION: ${{ needs.prepare.outputs.SSP_VERSION }}
VERSION: ${{ needs.prepare.outputs.VERSION }}
steps:
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
Expand All @@ -216,54 +218,56 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Determine if this is the latest release
- name: Determine if this is the latest version
id: is_latest
run: |
LATEST=$(curl -s https://api.github.com/repos/simplesamlphp/simplesamlphp/releases/latest | jq -r .tag_name | sed 's/^v//')
if [ "$LATEST" = "${SSP_VERSION}" ]; then
VERSION="${{ env.VERSION }}"
TAGS=$(curl -s "https://api.github.com/repos/moodle/moodle/tags?per_page=1000" | jq -r '.[].name' | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | sed 's/^v//')
LATEST=$(echo "$TAGS" | sort -V | tail -n1)
if [ "$LATEST" = "$VERSION" ]; then
echo "is_latest=true" >> $GITHUB_OUTPUT
else
echo "is_latest=false" >> $GITHUB_OUTPUT
fi
env:
SSP_VERSION: ${{ env.SSP_VERSION }}
VERSION: ${{ env.VERSION }}
- name: Create manifest list and push (php)
run: |
docker buildx imagetools create \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.SSP_VERSION }} \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.SSP_VERSION }}-linux-amd64 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.SSP_VERSION }}-linux-arm64
-t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.VERSION }} \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.VERSION }}-linux-amd64 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.VERSION }}-linux-arm64
env:
SSP_VERSION: ${{ env.SSP_VERSION }}
VERSION: ${{ env.VERSION }}
- name: Tag PHP image as latest
if: steps.is_latest.outputs.is_latest == 'true'
run: |
docker buildx imagetools create \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:latest \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.SSP_VERSION }}-linux-amd64 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.SSP_VERSION }}-linux-arm64
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.VERSION }}-linux-amd64 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.VERSION }}-linux-arm64
env:
SSP_VERSION: ${{ env.SSP_VERSION }}
VERSION: ${{ env.VERSION }}
- name: Inspect PHP image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.SSP_VERSION }}
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-php:v${{ env.VERSION }}
- name: Create manifest list and push (nginx)
run: |
docker buildx imagetools create \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.SSP_VERSION }} \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.SSP_VERSION }}-linux-amd64 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.SSP_VERSION }}-linux-arm64
-t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.VERSION }} \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.VERSION }}-linux-amd64 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.VERSION }}-linux-arm64
env:
SSP_VERSION: ${{ env.SSP_VERSION }}
VERSION: ${{ env.VERSION }}
- name: Tag nginx image as latest
if: steps.is_latest.outputs.is_latest == 'true'
run: |
docker buildx imagetools create \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:latest \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.SSP_VERSION }}-linux-amd64 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.SSP_VERSION }}-linux-arm64
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.VERSION }}-linux-amd64 \
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.VERSION }}-linux-arm64
env:
SSP_VERSION: ${{ env.SSP_VERSION }}
VERSION: ${{ env.VERSION }}
- name: Inspect nginx image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.SSP_VERSION }}
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-nginx:v${{ env.VERSION }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vscode
16 changes: 2 additions & 14 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
ARG PHP_VERSION
FROM php:${PHP_VERSION}-cli-alpine AS builder
COPY --from=composer/composer:latest-bin /composer /usr/bin/composer
RUN apk add --no-cache jq icu-dev libldap openldap-dev samba-dev gmp-dev
RUN docker-php-ext-install intl ldap gmp
ADD simplesamlphp-version-full.tar.gz /var/www
WORKDIR /var/www
RUN rm -rf html && mv simplesamlphp-* html
WORKDIR /var/www/html
RUN jq '.repositories += {"repo-name": {"type":"vcs","url":"https://github.com/smeetsee/simplesamlphp-module-openidprovider"}}' composer.json > composer.tmp.json && \
mv composer.tmp.json composer.json
RUN composer require 'cirrusidentity/simplesamlphp-module-authoauth2:^4.1' 'simplesamlphp/simplesamlphp-module-openidprovider:dev-master'

FROM php:${PHP_VERSION}-fpm-alpine AS php

Check warning on line 2 in Dockerfile

View workflow job for this annotation

GitHub Actions / docker (linux/arm64)

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

InvalidDefaultArgInFrom: Default value for ARG php:${PHP_VERSION}-fpm-alpine 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 Dockerfile

View workflow job for this annotation

GitHub Actions / docker (linux/arm64)

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

InvalidDefaultArgInFrom: Default value for ARG php:${PHP_VERSION}-fpm-alpine 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 Dockerfile

View workflow job for this annotation

GitHub Actions / docker (linux/amd64)

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

InvalidDefaultArgInFrom: Default value for ARG php:${PHP_VERSION}-fpm-alpine 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 Dockerfile

View workflow job for this annotation

GitHub Actions / docker (linux/amd64)

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

InvalidDefaultArgInFrom: Default value for ARG php:${PHP_VERSION}-fpm-alpine 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 Dockerfile

View workflow job for this annotation

GitHub Actions / docker (linux/amd64)

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

InvalidDefaultArgInFrom: Default value for ARG php:${PHP_VERSION}-fpm-alpine results in empty or invalid base image name More info: https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/
RUN apk add --no-cache icu-dev libldap openldap-dev samba-dev gmp-dev
RUN docker-php-ext-install intl ldap gmp
COPY --from=builder /var/www/html /var/www/html
COPY moodle-src /var/www/html
EXPOSE 9000

FROM nginx:alpine AS nginx
COPY nginx.conf.template /nginx.conf.template
COPY --from=builder /var/www/html /var/www/html
COPY moodle-src /var/www/html
CMD ["/bin/sh" , "-c" , "envsubst '${SERVER_NAME}' < /nginx.conf.template > /etc/nginx/nginx.conf && exec nginx -g 'daemon off;'"]
EXPOSE 8080
57 changes: 28 additions & 29 deletions nginx.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,35 @@ http {
keepalive_timeout 65;

#gzip on;

server {
listen 8080 default;
server_name ${SERVER_NAME};

index index.php;

# See https://hstspreload.org/ before uncommenting the line below.
# add_header Strict-Transport-Security "max-age=15768000; preload;";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Frame-Options DENY;

location = / {
return 301 https://$server_name/module.php/openidProvider/user.php;
}

location ^~ {
alias /var/www/html/public;

location ~ \.php(/|$) {
fastcgi_pass phpfpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
fastcgi_param HTTP_X_FORWARDED_PROTO https;
include fastcgi_params;
listen 8080 default;
server_name ${SERVER_NAME};

root /var/www/html;
index index.php;

# allow larger file uploads and longer script runtimes
client_max_body_size 100m;
client_body_timeout 120s;

sendfile off;

# See https://hstspreload.org/ before uncommenting the line below.
# add_header Strict-Transport-Security "max-age=15768000; preload;";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Frame-Options DENY;
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass phpfpm:9000;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
fastcgi_param HTTP_X_FORWARDED_PROTO https;
}
}
}
}
Loading