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
6 changes: 3 additions & 3 deletions .github/actions/determine-composer-version/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ runs:
steps:
- name: "Determine composer version from Dockerfile"
run: |
echo "COMPOSER_VERSION_MAJOR=$(grep -oP 'ENV COMPOSER_VERSION=\K\d+\.\d+\.\d+' Dockerfile | cut -d '.' -f 1)" >> $GITHUB_ENV
echo "COMPOSER_VERSION_MAJOR_MINOR=$(grep -oP 'ENV COMPOSER_VERSION=\K\d+\.\d+\.\d+' Dockerfile | cut -d '.' -f 1,2)" >> $GITHUB_ENV
echo "COMPOSER_VERSION_MAJOR_MINOR_PATCH=$(grep -oP 'ENV COMPOSER_VERSION=\K\d+\.\d+\.\d+' Dockerfile)" >> $GITHUB_ENV
echo "COMPOSER_VERSION_MAJOR=$(grep -oP 'ENV COMPOSER_VERSION=\K\d+\.\d+\.\d+(-RC\d+)?' Dockerfile | cut -d '.' -f 1)" >> $GITHUB_ENV
echo "COMPOSER_VERSION_MAJOR_MINOR=$(grep -oP 'ENV COMPOSER_VERSION=\K\d+\.\d+\.\d+(-RC\d+)?' Dockerfile | cut -d '.' -f 1,2)" >> $GITHUB_ENV
echo "COMPOSER_VERSION_MAJOR_MINOR_PATCH=$(grep -oP 'ENV COMPOSER_VERSION=\K\d+\.\d+\.\d+(-RC\d+)?' Dockerfile)" >> $GITHUB_ENV
shell: "bash"
working-directory: "${{ inputs.working-directory }}"
251 changes: 251 additions & 0 deletions .github/workflows/2.9.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
name: 2.9 (Release Candidate)

on:
workflow_dispatch:
pull_request:
paths:
- 2.9.yaml
- 2.9/**
push:
branches:
- main
paths:
- 2.9.yaml
- 2.9/**

env:
AWS_REGION: us-east-1
DOCKERHUB_SLUG: composer/composer
ECR_SLUG: public.ecr.aws/u0u1j5s3/composer
GHCR_SLUG: ghcr.io/composer/docker
DIRECTORY: '2.9'

jobs:

prepare:

runs-on: ubuntu-latest

outputs:
full-annotations: ${{ steps.meta-full.outputs.annotations }}
full-labels: ${{ steps.meta-full.outputs.labels }}
full-json: ${{ steps.meta-full.outputs.json }}
bin-annotations: ${{ steps.meta-bin.outputs.annotations }}
bin-labels: ${{ steps.meta-bin.outputs.labels }}
bin-json: ${{ steps.meta-bin.outputs.json }}

steps:

- name: Checkout
uses: actions/checkout@v5

- name: Determine Composer version from Dockerfile
uses: ./.github/actions/determine-composer-version
with:
working-directory: ${{ env.DIRECTORY }}

- name: Docker metadata (full image)
id: meta-full
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.ECR_SLUG }}
${{ env.GHCR_SLUG }}
flavor: |
latest=false
tags: |
type=semver,pattern={{version}},value=${{ env.COMPOSER_VERSION_MAJOR_MINOR_PATCH }}
type=semver,pattern={{major}}.{{minor}},value=${{ env.COMPOSER_VERSION_MAJOR_MINOR_PATCH }}
labels: |
org.opencontainers.image.vendor=Composer
org.opencontainers.image.title=Composer
org.opencontainers.image.description=PHP runtime image with Composer

- name: Docker metadata (binary-only image)
id: meta-bin
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_SLUG }}
${{ env.ECR_SLUG }}
${{ env.GHCR_SLUG }}
flavor: |
latest=false
suffix=-bin
tags: |
type=semver,pattern={{version}},value=${{ env.COMPOSER_VERSION_MAJOR_MINOR_PATCH }}
type=semver,pattern={{major}}.{{minor}},value=${{ env.COMPOSER_VERSION_MAJOR_MINOR_PATCH }}
labels: |
org.opencontainers.image.vendor=Composer
org.opencontainers.image.title=Composer
org.opencontainers.image.description=Image with Composer binary only

build:

runs-on: ubuntu-latest
timeout-minutes: 20

needs:
- prepare

strategy:
matrix:
platform:
- linux/amd64
- linux/arm/v6
- linux/arm/v7
- linux/arm64/v8
- linux/i386
- linux/ppc64le
- linux/riscv64
- linux/s390x

defaults:
run:
working-directory: ${{ env.DIRECTORY }}

steps:

- name: Checkout
uses: actions/checkout@v5

- name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_SLUG=${platform//\//-}" >> $GITHUB_ENV

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: ${{ matrix.platform }}

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

- name: Login to Docker Hub
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Login to Amazon Public ECR
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: public.ecr.aws
username: ${{ secrets.AWS_ECR_ACCESS_KEY }}
password: ${{ secrets.AWS_ECR_SECRET_KEY }}

- name: Login to Github Container Registry
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build full image
id: build-full
uses: docker/build-push-action@v6
with:
context: ${{ env.DIRECTORY }}
target: binary-with-runtime
annotations: ${{ needs.prepare.outputs.full-annotations }}
platforms: ${{ matrix.platform }}
outputs: type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.ECR_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}

- name: Build binary-only image
id: build-bin
uses: docker/build-push-action@v6
with:
context: ${{ env.DIRECTORY }}
target: standalone-binary
annotations: ${{ needs.prepare.outputs.bin-annotations }}
platforms: ${{ matrix.platform }}
outputs: type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.ECR_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.ref == 'refs/heads/main' && github.event_name != 'pull_request' }}

- name: Export digests
run: |
mkdir -p /tmp/digests/{full,bin}
digest="${{ steps.build-full.outputs.digest }}"
touch "/tmp/digests/full/${digest#sha256:}"
digest="${{ steps.build-bin.outputs.digest }}"
touch "/tmp/digests/bin/${digest#sha256:}"

- name: Upload digests
uses: actions/upload-artifact@v5
with:
name: digests-${{ env.PLATFORM_SLUG }}
path: |
/tmp/digests/full/*
/tmp/digests/bin/*
if-no-files-found: error
retention-days: 1

merge:

if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'

runs-on: ubuntu-latest

needs:
- prepare
- build

steps:

- name: Download digests
uses: actions/download-artifact@v6
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true

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

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Login to Amazon Public ECR
uses: docker/login-action@v3
with:
registry: public.ecr.aws
username: ${{ secrets.AWS_ECR_ACCESS_KEY }}
password: ${{ secrets.AWS_ECR_SECRET_KEY }}

- name: Login to Github Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Create manifest list for full image and push
working-directory: /tmp/digests/full
env:
JSON: ${{ needs.prepare.outputs.full-json }}
run: |
docker buildx imagetools create $(jq -cr '.tags | map(select(startswith("${{ env.DOCKERHUB_SLUG }}")) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf '${{ env.DOCKERHUB_SLUG }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map(select(startswith("${{ env.ECR_SLUG }}")) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf '${{ env.ECR_SLUG }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map(select(startswith("${{ env.GHCR_SLUG }}")) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf '${{ env.GHCR_SLUG }}@sha256:%s ' *)

- name: Create manifest list for binary-only image and push
working-directory: /tmp/digests/bin
env:
JSON: ${{ needs.prepare.outputs.bin-json }}
run: |
docker buildx imagetools create $(jq -cr '.tags | map(select(startswith("${{ env.DOCKERHUB_SLUG }}")) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf '${{ env.DOCKERHUB_SLUG }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map(select(startswith("${{ env.ECR_SLUG }}")) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf '${{ env.ECR_SLUG }}@sha256:%s ' *)
docker buildx imagetools create $(jq -cr '.tags | map(select(startswith("${{ env.GHCR_SLUG }}")) | "--tag " + .) | join(" ")' <<< "$JSON") \
$(printf '${{ env.GHCR_SLUG }}@sha256:%s ' *)
97 changes: 97 additions & 0 deletions 2.9/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
FROM php:8-alpine AS binary-with-runtime

RUN set -eux ; \
apk add --no-cache --virtual .composer-rundeps \
7zip \
bash \
coreutils \
git \
make \
mercurial \
openssh-client \
patch \
subversion \
tini \
unzip \
zip

RUN printf "# composer php cli ini settings\n\
date.timezone=UTC\n\
memory_limit=-1\n\
" > $PHP_INI_DIR/php-cli.ini

ENV COMPOSER_ALLOW_SUPERUSER=1
ENV COMPOSER_HOME=/tmp
ENV COMPOSER_VERSION=2.9.0-RC1

RUN set -eux ; \
# install https://github.com/mlocati/docker-php-extension-installer
curl \
--silent \
--fail \
--location \
--retry 3 \
--output /usr/local/bin/install-php-extensions \
--url https://github.com/mlocati/docker-php-extension-installer/releases/download/1.2.58/install-php-extensions \
; \
echo 182011b3dca5544a70fdeb587af44ed1760aa9a2ed37d787d0f280a99f92b008e638c37762360cd85583830a097665547849cb2293c4a0ee32c2a36ef7a349e2 /usr/local/bin/install-php-extensions | sha512sum --strict --check ; \
chmod +x /usr/local/bin/install-php-extensions ; \
# install necessary/useful extensions not included in base image
install-php-extensions \
bz2 \
zip \
; \
# install public keys for snapshot and tag validation, see https://composer.github.io/pubkeys.html
curl \
--silent \
--fail \
--location \
--retry 3 \
--output /tmp/keys.dev.pub \
--url https://raw.githubusercontent.com/composer/composer.github.io/e7f28b7200249f8e5bc912b42837d4598c74153a/snapshots.pub \
; \
echo 572b963c4b7512a7de3c71a788772440b1996d918b1d2b5354bf8ba2bb057fadec6f7ac4852f2f8a8c01ab94c18141ce0422aec3619354b057216e0597db5ac2 /tmp/keys.dev.pub | sha512sum --strict --check ; \
curl \
--silent \
--fail \
--location \
--retry 3 \
--output /tmp/keys.tags.pub \
--url https://raw.githubusercontent.com/composer/composer.github.io/e7f28b7200249f8e5bc912b42837d4598c74153a/releases.pub \
; \
echo 47f374b8840dcb0aa7b2327f13d24ab5f6ae9e58aa630af0d62b3d0ea114f4a315c5d97b21dcad3c7ffe2f0a95db2edec267adaba3f4f5a262abebe39aed3a28 /tmp/keys.tags.pub | sha512sum --strict --check ; \
# download installer.php, see https://getcomposer.org/download/
curl \
--silent \
--fail \
--location \
--retry 3 \
--output /tmp/installer.php \
--url https://raw.githubusercontent.com/composer/getcomposer.org/f24b8f860b95b52167f91bbd3e3a7bcafe043038/web/installer \
; \
echo 3137ad86bd990524ba1dedc2038309dfa6b63790d3ca52c28afea65dcc2eaead16fb33e9a72fd2a7a8240afaf26e065939a2d472f3b0eeaa575d1e8648f9bf19 /tmp/installer.php | sha512sum --strict --check ; \
# install composer phar binary
php /tmp/installer.php \
--no-ansi \
--install-dir=/usr/bin \
--filename=composer \
--version=${COMPOSER_VERSION} \
; \
composer --ansi --version --no-interaction ; \
rm -f /tmp/installer.php ; \
find /tmp -type d -exec chmod -v 1777 {} +

COPY docker-entrypoint.sh /docker-entrypoint.sh

WORKDIR /app

ENTRYPOINT ["/docker-entrypoint.sh"]

CMD ["composer"]

FROM scratch AS standalone-binary

COPY --from=binary-with-runtime /usr/bin/composer /composer

# This is defined as last target to be backward compatible with build without explicit --target option
FROM binary-with-runtime AS default
24 changes: 24 additions & 0 deletions 2.9/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/sh

isCommand() {
# Retain backwards compatibility with common CI providers,
# see: https://github.com/composer/docker/issues/107
if [ "$1" = "sh" ]; then
return 1
fi

composer help --no-interaction "$1" > /dev/null 2>&1
}

# check if the first argument passed in looks like a flag
if [ "${1#-}" != "$1" ]; then
set -- /sbin/tini -- composer "$@"
# check if the first argument passed in is composer
elif [ "$1" = 'composer' ]; then
set -- /sbin/tini -- "$@"
# check if the first argument passed in matches a known command
elif isCommand "$1"; then
set -- /sbin/tini -- composer "$@"
fi

exec "$@"