diff --git a/.github/workflows/default.yaml b/.github/workflows/default.yaml
index 45a9191..552b3fd 100644
--- a/.github/workflows/default.yaml
+++ b/.github/workflows/default.yaml
@@ -23,56 +23,42 @@ env:
jobs:
build:
name: "Build: ${{ matrix.version }}/${{ matrix.arch }}"
- runs-on: ubuntu-20.04
+ runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false # Don't cancel other jobs if one fails
matrix:
include:
-
+ platform: linux/amd64
arch: amd64
version: "2.4"
+ runner: ubuntu-24.04
-
+ platform: linux/arm64
arch: arm64
version: "2.4"
+ runner: ubuntu-24.04-arm
env:
ARCH: ${{ matrix.arch }}
VERSION_PREFIX: ""
VERSION: ${{ matrix.version }}
- UPSTREAM_IMAGE: httpd:${{ matrix.version }}-alpine
BUILD_DIR: "."
steps:
-
name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v6
-
name: Environment variables
run: |
# Export variables for further steps
echo GIT_SHA7="${GITHUB_SHA:0:7}" | tee -a ${GITHUB_ENV}
echo BUILD_IMAGE_TAG="${IMAGE}:${VERSION_PREFIX}${VERSION}-build" | tee -a ${GITHUB_ENV}
- # Pull the host public SSH key at runtime instead of relying on a static value stored in secrets.
- echo ARM64_HOST_SSH_CERT="$(ssh-keyscan -t rsa ${{ secrets.ARM64_HOST }} 2>/dev/null)" | tee -a ${GITHUB_ENV}
-# -
-# # Switch docker context to a remote arm64 host
-# # Used for building heavy images that take too long to build using QEMU + for native arm64 testing.
-# name: Switch to arm64 builder host
-# if: ${{ env.ARCH == 'arm64' }}
-# uses: arwynfr/actions-docker-context@v2
-# with:
-# docker_host: "ssh://ubuntu@${{ secrets.ARM64_HOST }}"
-# context_name: arm64-host
-# ssh_key: "${{ secrets.ARM64_HOST_SSH_KEY }}"
-# ssh_cert: "${{ env.ARM64_HOST_SSH_CERT }}"
-# use_context: true
- -
- name: Set up QEMU
- uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v1
+ uses: docker/setup-buildx-action@v4
-
name: Check Docker
run: |
@@ -80,31 +66,39 @@ jobs:
docker info
-
name: Login to Docker Hub
- uses: docker/login-action@v1
+ uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
# Build and cache image in the registry
name: Build image
- uses: docker/build-push-action@v2
+ uses: docker/build-push-action@v7
with:
context: ${{ env.BUILD_DIR }}
file: ${{ env.BUILD_DIR }}/Dockerfile
build-args: |
- UPSTREAM_IMAGE=${{ env.UPSTREAM_IMAGE }}
VERSION=${{ env.VERSION }}
platforms: linux/${{ env.ARCH }}
# Push intermediate arch-specific build tag to repo
tags: ${{ env.BUILD_IMAGE_TAG }}-${{ env.GIT_SHA7 }}-${{ env.ARCH }}
push: ${{ github.event_name != 'pull_request' }} # Don't push for PRs
+ # Disable automatic image attestations
+ # With image attestations enabled, the image tag pushed to the registry is a manifest list.
+ # That makes it impossible to stitch different platform images together in a manifest list, since you
+ # cannot have a manifest list of manifest lists.
+ # See https://docs.docker.com/build/attestations/attestation-storage/
+ # TODO: Refactor to allow for image attestations
+ provenance: false
+ sbom: false
# BUILD_IMAGE_TAG - persistent multi-arch tag, updated at the end of the build (success or failure)
- cache-from: type=registry,ref=${{ env.BUILD_IMAGE_TAG }}
- cache-to: type=inline # Write the cache metadata into the image configuration
+ # Use registry cache with max mode to cache all image layers in the registry
+ cache-from: type=registry,ref=${{ env.BUILD_IMAGE_TAG }}-cache-${{ env.ARCH }}
+ cache-to: type=registry,ref=${{ env.BUILD_IMAGE_TAG }}-cache-${{ env.ARCH }},mode=max
test:
name: "Test: ${{ matrix.version }}/${{ matrix.arch }}"
- runs-on: ubuntu-20.04
+ runs-on: ${{ matrix.runner }}
needs: build
strategy:
@@ -112,14 +106,15 @@ jobs:
matrix:
include:
-
+ platform: linux/amd64
arch: amd64
version: "2.4"
- # Disabled arm64 tests.
- # TODO: Refactor tests to be compatible with a remote host test runner.
- # TODO: Remember to re-enabled the test results check in "push".
- #-
- # arch: arm64
- # version: 2.4
+ runner: ubuntu-24.04
+ -
+ platform: linux/arm64
+ arch: arm64
+ version: "2.4"
+ runner: ubuntu-24.04-arm
env:
ARCH: ${{ matrix.arch }}
@@ -129,47 +124,21 @@ jobs:
steps:
-
name: Setup Bats
- uses: mig4/setup-bats@v1
- with:
- bats-version: "1.3.0"
+ uses: bats-core/bats-action@4.0.0
-
name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v6
-
name: Environment variables
run: |
# Export variables for further steps
echo GIT_SHA7="${GITHUB_SHA:0:7}" | tee -a ${GITHUB_ENV}
echo BUILD_IMAGE_TAG="${IMAGE}:${VERSION_PREFIX}${VERSION}-build" | tee -a ${GITHUB_ENV}
- # Pull the host public SSH key at runtime instead of relying on a static value stored in secrets.
- echo ARM64_HOST_SSH_CERT="$(ssh-keyscan -t rsa ${{ secrets.ARM64_HOST }} 2>/dev/null)" | tee -a ${GITHUB_ENV}
- -
- # Switch docker context to a remote arm64 host
- # Used for building heavy images that take too long to build using QEMU + for native arm64 testing.
- name: Switch to arm64 builder host
- if: ${{ env.ARCH == 'arm64' }}
- uses: arwynfr/actions-docker-context@v2
- with:
- docker_host: "ssh://ubuntu@${{ secrets.ARM64_HOST }}"
- context_name: arm64-host
- ssh_key: "${{ secrets.ARM64_HOST_SSH_KEY }}"
- ssh_cert: "${{ env.ARM64_HOST_SSH_CERT }}"
- use_context: true
-
name: Check Docker
run: |
docker version
docker info
-# -
-# name: Test preparations
-# working-directory: ${{ env.BUILD_CONTEXT }}
-# env:
-# BUILD_IMAGE_TAG: ${{ env.BUILD_IMAGE_TAG }}-${{ env.GIT_SHA7 }}-${{ env.ARCH }}
-# run: |
-# # Install Docksal using the passed DOCKSAL_VERSION value
-# curl -sSL http://get.docksal.io | bash
-# # Start the service using the build image tag
-# make start
-
# Run tests
name: Test
@@ -186,14 +155,16 @@ jobs:
# Dynamic variable names cannot be used when mapping step outputs to job outputs.
# Step outputs cannot be accessed directly from other jobs. Dead end.
- name: Store test results
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v7
with:
- name: test-results
+ name: test-results-${{ env.GIT_SHA7 }}-${{ env.VERSION_PREFIX }}${{ env.VERSION }}-${{ env.ARCH }}
path: ${{ github.workspace }}/test-results-*.txt
+ if-no-files-found: error
+ overwrite: true
push:
name: "Push: ${{ matrix.version }}/multi"
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
# Wait for test to either succeed or fail
needs: test
@@ -211,38 +182,35 @@ jobs:
steps:
-
name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v6
-
name: Environment variables
run: |
# Export variables for further steps
echo GIT_SHA7="${GITHUB_SHA:0:7}" | tee -a ${GITHUB_ENV}
echo BUILD_IMAGE_TAG="${IMAGE}:${VERSION_PREFIX}${VERSION}-build" | tee -a ${GITHUB_ENV}
- # Pull the host public SSH key at runtime instead of relying on a static value stored in secrets.
- echo ARM64_HOST_SSH_CERT="$(ssh-keyscan -t rsa ${{ secrets.ARM64_HOST }} 2>/dev/null)" | tee -a ${GITHUB_ENV}
-
# Login to Docker Hub
name: Login to Docker Hub
- uses: docker/login-action@v1
+ uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Retrieve test results
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v8
with:
- name: test-results
+ pattern: test-results-${{ env.GIT_SHA7 }}-*
+ merge-multiple: true
-
# Generate persistent tags (edge, stable, release)
name: Docker image tags
id: docker_tags
# Don't push broken builds to persistent tags (both amd64 and arm64 tests must pass)
- # TODO: re-enable the arm64 test results check once those tests are re-enabled
run: |
amd64_tests=$(cat test-results-${VERSION_PREFIX}${VERSION}-amd64.txt)
- #arm64_tests=$(cat test-results-${VERSION_PREFIX}${VERSION}-arm64.txt)
- # && [[ "${arm64_tests}" == "pass" ]]
- if [[ "${amd64_tests}" == "pass" ]]; then
+ arm64_tests=$(cat test-results-${VERSION_PREFIX}${VERSION}-arm64.txt)
+ if [[ "${amd64_tests}" == "pass" ]] && [[ "${arm64_tests}" == "pass" ]]; then
.github/scripts/docker-tags.sh
fi
-
@@ -268,5 +236,6 @@ jobs:
docker manifest push ${tag}
done
# Clean up intermediate arch-specific image tags (DockerHub only)
- .github/scripts/docker-tag-delete.sh ${{ env.BUILD_IMAGE_TAG }}-${{ env.GIT_SHA7 }}-amd64
- .github/scripts/docker-tag-delete.sh ${{ env.BUILD_IMAGE_TAG }}-${{ env.GIT_SHA7 }}-arm64
+ # TODO: DISABLED. DOES NOT WORK RELIABLY.
+ # .github/scripts/docker-tag-delete.sh "${{ env.BUILD_IMAGE_TAG }}-${{ env.GIT_SHA7 }}-amd64"
+ # .github/scripts/docker-tag-delete.sh "${{ env.BUILD_IMAGE_TAG }}-${{ env.GIT_SHA7 }}-arm64"
diff --git a/Dockerfile b/Dockerfile
index 5151abf..633cc7c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-ARG UPSTREAM_IMAGE
+ARG UPSTREAM_IMAGE=httpd:2.4.67-alpine
FROM ${UPSTREAM_IMAGE}
# TODO: Drop this? HTTPS termination should happen at the reverse proxy and this is not used anyway.
diff --git a/Makefile b/Makefile
index d66900f..f224eda 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ DOCKER_BUILDKIT=1
IMAGE ?= docksal/apache
VERSION ?= 2.4
-UPSTREAM_IMAGE ?= httpd:2.4.52-alpine
+UPSTREAM_IMAGE ?= httpd:2.4.67-alpine
BUILD_IMAGE_TAG ?= $(IMAGE):$(VERSION)-build
NAME = docksal-apache-$(VERSION)
diff --git a/README.md b/README.md
index e8fc72f..3b3a6fe 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ This image(s) is part of the [Docksal](http://docksal.io) image library.
## Versions
-- apache2.4 (based on http:2.4-alpine)
+- apache2.4 (based on httpd:2.4.67-alpine)
## Features
diff --git a/conf/extra/httpd-vhosts.conf b/conf/extra/httpd-vhosts.conf
index 3d1221d..d128390 100644
--- a/conf/extra/httpd-vhosts.conf
+++ b/conf/extra/httpd-vhosts.conf
@@ -2,33 +2,33 @@ ServerName ${APACHE_SERVERNAME}
# HTTP (default virtual host)
- # Allow virtual-host config overrides (overrides go first, as Apache picks the first instance of a directive)
- # Using a glob pattern in the file name to avoid creating an empty config by default
- IncludeOptional conf/custom/httpd-vhost-overrides.con[f]
# Standard virtual-host configuration
Include conf/extra/includes/host.conf
+ # Allow virtual-host config overrides (overrides go last, as Apache uses the last instance of a directive)
+ # Using a glob pattern in the file name to avoid creating an empty config by default
+ IncludeOptional conf/custom/httpd-vhost-overrides.con[f]
# HTTPS (default virtual host)
Listen 443
- # Restrict mod_ssl to use only TLSv1.2 ciphers
+ # Restrict mod_ssl to strong ciphers (TLSv1.3 ciphers are configured separately)
SSLCipherSuite HIGH:MEDIUM:!SSLv3:!kRSA
SSLProxyCipherSuite HIGH:MEDIUM:!SSLv3:!kRSA
SSLHonorCipherOrder on
- # Only allow the TLSv1.2 protocol
- SSLProtocol TLSv1.2
- SSLProxyProtocol TLSv1.2
+ # Allow TLSv1.2 and TLSv1.3
+ SSLProtocol -all +TLSv1.2 +TLSv1.3
+ SSLProxyProtocol -all +TLSv1.2 +TLSv1.3
# Other SSL settings
SSLSessionCache "shmcb:/usr/local/apache2/logs/ssl_scache(512000)"
SSLSessionCacheTimeout 300
- # Allow virtual-host config overrides (overrides go first, as Apache picks the first instance of a directive)
- # Using a glob pattern in the file name to avoid creating an empty config by default
- IncludeOptional conf/custom/httpd-vhost-overrides.con[f]
# Standard virtual-host configuration
Include conf/extra/includes/host.conf
+ # Allow virtual-host config overrides (overrides go last, as Apache uses the last instance of a directive)
+ # Using a glob pattern in the file name to avoid creating an empty config by default
+ IncludeOptional conf/custom/httpd-vhost-overrides.con[f]
SSLEngine on
SSLCertificateFile /usr/local/apache2/conf/server.crt
diff --git a/tests/config-directory-override/httpd-vhost-overrides.conf b/tests/config-directory-override/httpd-vhost-overrides.conf
new file mode 100644
index 0000000..d452e34
--- /dev/null
+++ b/tests/config-directory-override/httpd-vhost-overrides.conf
@@ -0,0 +1,5 @@
+# Override the block from host.conf to deny access
+# This tests that overrides at the same scope (container directive) take effect
+
+ Require all denied
+
diff --git a/tests/config/httpd-vhost-overrides.conf b/tests/config/httpd-vhost-overrides.conf
index c99d9c9..c0cd5ef 100644
--- a/tests/config/httpd-vhost-overrides.conf
+++ b/tests/config/httpd-vhost-overrides.conf
@@ -1 +1,4 @@
-DirectoryIndex index2.html
+# Test that a override takes precedence over VirtualHost-level directives
+
+ DirectoryIndex index2.html
+
diff --git a/tests/test.bats b/tests/test.bats
index 2febc75..b9ef541 100755
--- a/tests/test.bats
+++ b/tests/test.bats
@@ -200,3 +200,32 @@ _healthcheck_wait ()
### Cleanup ###
make clean
}
+
+@test "Configuration overrides - Directory block" {
+ [[ $SKIP == 1 ]] && skip
+
+ ### Setup ###
+ VOLUMES=" \
+ -v $(pwd)/tests/docroot:/var/www/docroot \
+ -v $(pwd)/tests/config-directory-override:/var/www/.docksal/etc/apache" \
+ make start
+
+ run _healthcheck_wait
+ unset output
+
+ ### Tests ###
+
+ # Test that a override takes precedence over host.conf's block
+ # This verifies the include order fix (overrides must load after the standard config)
+ run curl -sSk -m 1 -I http://localhost:2580
+ [[ "$output" =~ "HTTP/1.1 403 Forbidden" ]]
+ unset output
+
+ # HTTPS should also be overridden
+ run curl -sSk -m 1 -I https://localhost:25443
+ [[ "$output" =~ "HTTP/1.1 403 Forbidden" ]]
+ unset output
+
+ ### Cleanup ###
+ make clean
+}