Skip to content

Commit bed143e

Browse files
authored
Merge pull request #25 from specsnl/sync-php85-pr94-97
Synced php85 changes: merged builder_nodejs into builder and updated Node.js to 26
2 parents f933dc7 + dbbbf3b commit bed143e

9 files changed

Lines changed: 204 additions & 234 deletions

File tree

‎.github/rulesets/Main.json‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,13 @@
5252
"context": "merge (ghcr.io/specsnl/php74) / builder / Merge Images (builder)",
5353
"integration_id": 15368
5454
},
55-
{
56-
"context": "merge (ghcr.io/specsnl/php74) / builder_nodejs / Merge Images (builder_nodejs)",
57-
"integration_id": 15368
58-
},
5955
{
6056
"context": "merge (ghcr.io/specsnl/php74/apache) / runtime / Merge Images (runtime)",
6157
"integration_id": 15368
6258
},
6359
{
6460
"context": "merge (ghcr.io/specsnl/php74/apache) / builder / Merge Images (builder)",
6561
"integration_id": 15368
66-
},
67-
{
68-
"context": "merge (ghcr.io/specsnl/php74/apache) / builder_nodejs / Merge Images (builder_nodejs)",
69-
"integration_id": 15368
7062
}
7163
]
7264
}

‎.github/workflows/main.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ concurrency:
1515

1616
jobs:
1717
build:
18-
uses: specsnl/github-actions/.github/workflows/build-php.yml@2.4.4
18+
uses: specsnl/github-actions/.github/workflows/build-php.yml@3.0.0
1919
strategy:
2020
fail-fast: false
2121
matrix:
@@ -36,7 +36,7 @@ jobs:
3636
dockerfile: ${{ matrix.docker.dockerfile }}
3737

3838
merge:
39-
uses: specsnl/github-actions/.github/workflows/merge-php.yml@2.4.4
39+
uses: specsnl/github-actions/.github/workflows/merge-php.yml@3.0.0
4040
needs: build
4141
strategy:
4242
matrix:

‎.github/workflows/pr.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434

3535
build:
3636
needs: check
37-
uses: specsnl/github-actions/.github/workflows/build-php.yml@2.4.4
37+
uses: specsnl/github-actions/.github/workflows/build-php.yml@3.0.0
3838
strategy:
3939
fail-fast: false
4040
matrix:
@@ -55,7 +55,7 @@ jobs:
5555
dockerfile: ${{ matrix.docker.dockerfile }}
5656

5757
merge:
58-
uses: specsnl/github-actions/.github/workflows/merge-php.yml@2.4.4
58+
uses: specsnl/github-actions/.github/workflows/merge-php.yml@3.0.0
5959
needs: build
6060
strategy:
6161
matrix:

‎.github/workflows/tag.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ concurrency:
1515

1616
jobs:
1717
build:
18-
uses: specsnl/github-actions/.github/workflows/build-php.yml@2.4.4
18+
uses: specsnl/github-actions/.github/workflows/build-php.yml@3.0.0
1919
strategy:
2020
fail-fast: false
2121
matrix:
@@ -36,7 +36,7 @@ jobs:
3636
dockerfile: ${{ matrix.docker.dockerfile }}
3737

3838
merge:
39-
uses: specsnl/github-actions/.github/workflows/merge-php.yml@2.4.4
39+
uses: specsnl/github-actions/.github/workflows/merge-php.yml@3.0.0
4040
needs: build
4141
strategy:
4242
matrix:

‎Dockerfile.tmpl‎

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ FROM {{ getenv "BASE_IMAGE" }} AS runtime
99

1010
ARG DEBIAN_FRONTEND=noninteractive
1111

12+
ENV LANG=C.UTF-8
13+
1214
ARG XDG_CONFIG_HOME=/config
13-
ENV XDG_CONFIG_HOME=$XDG_CONFIG_HOME
15+
ENV XDG_CONFIG_HOME="$XDG_CONFIG_HOME"
1416

1517
ARG XDG_DATA_HOME=/data
16-
ENV XDG_DATA_HOME=$XDG_DATA_HOME
18+
ENV XDG_DATA_HOME="$XDG_DATA_HOME"
1719

1820
ARG XDG_CACHE_HOME=/cache
19-
ENV XDG_CACHE_HOME=$XDG_CACHE_HOME
21+
ENV XDG_CACHE_HOME="$XDG_CACHE_HOME"
2022

2123
# Latest version of event-extension: https://pecl.php.net/package/event
2224
ARG PHP_EVENT_VERSION=3.1.6
@@ -27,14 +29,12 @@ ARG PHP_REDIS_VERSION=6.3.0
2729
# Latest version of amqp-extension: https://pecl.php.net/package/amqp
2830
ARG PHP_AMQP_VERSION=2.2.0
2931

30-
ARG DEBIAN_SECURITY_SNAPSHOT=20260901T000000Z
31-
3232
WORKDIR /var/www
3333

3434
RUN --mount=type=bind,from=php_extension_installer,source=/usr/bin/install-php-extensions,target=/usr/local/bin/install-php-extensions \
3535
# Bullseye is EOL:
36-
sed -i -E "s|^deb http://deb.debian.org/debian-security (.*)|deb [check-valid-until=no] http://snapshot.debian.org/archive/debian-security/$DEBIAN_SECURITY_SNAPSHOT \1|" /etc/apt/sources.list \
37-
&& grep -q snapshot.debian.org /etc/apt/sources.list \
36+
sed -i -E "s|^deb http://deb.debian.org/debian-security (.*)|deb http://archive.debian.org/debian-security \1|" /etc/apt/sources.list \
37+
&& grep -q archive.debian.org /etc/apt/sources.list \
3838
&& apt-get update \
3939
&& apt-get install --assume-yes --no-install-recommends \
4040
apt-transport-https \
@@ -58,9 +58,9 @@ RUN --mount=type=bind,from=php_extension_installer,source=/usr/bin/install-php-e
5858
"amqp-$PHP_AMQP_VERSION" \
5959
&& cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
6060
&& mkdir -p \
61-
$XDG_CONFIG_HOME \
62-
$XDG_DATA_HOME \
63-
$XDG_CACHE_HOME \
61+
"$XDG_CONFIG_HOME" \
62+
"$XDG_DATA_HOME" \
63+
"$XDG_CACHE_HOME" \
6464
&& rm -rf /var/www/* \
6565
# Cleanup
6666
&& apt-get autoremove --assume-yes \
@@ -73,6 +73,9 @@ COPY files/general /
7373
# Latest version of Composer: https://hub.docker.com/r/composer/composer/tags
7474
FROM {{ getenv "COMPOSER_IMAGE" }} AS composer
7575
76+
# Latest version of node: https://hub.docker.com/_/node/tags
77+
FROM {{ getenv "NODE_IMAGE" }} AS node
78+
7679
FROM runtime AS builder
7780
7881
ARG TARGETARCH
@@ -83,6 +86,16 @@ ARG XDEBUG_VERSION=3.1.6
8386
# Latest version of pcov: https://pecl.php.net/package/pcov
8487
ARG PCOV_VERSION=1.0.12
8588
89+
# Latest version of fixuid: https://github.com/boxboat/fixuid/releases/latest
90+
ARG FIXUID_VERSION=0.6.0
91+
92+
ARG USER=code
93+
ARG GROUP=code
94+
ARG USER_UID=1000
95+
ARG USER_GID=1000
96+
97+
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
98+
8699
RUN --mount=type=bind,from=php_extension_installer,source=/usr/bin/install-php-extensions,target=/usr/local/bin/install-php-extensions \
87100
apt-get update \
88101
&& apt-get install --assume-yes --no-install-recommends \
@@ -93,6 +106,9 @@ RUN --mount=type=bind,from=php_extension_installer,source=/usr/bin/install-php-e
93106
p7zip-full \
94107
unzip \
95108
curl \
109+
gcc \
110+
g++ \
111+
make \
96112
# Download Composer keys
97113
&& mkdir -p "$XDG_CONFIG_HOME/composer" \
98114
&& curl -fsSLo "$XDG_CONFIG_HOME/composer/keys.dev.pub" https://composer.github.io/snapshots.pub \
@@ -103,23 +119,8 @@ RUN --mount=type=bind,from=php_extension_installer,source=/usr/bin/install-php-e
103119
"xdebug-$XDEBUG_VERSION" \
104120
"pcov-$PCOV_VERSION" \
105121
&& cp "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" \
106-
# Cleanup
107-
&& apt-get autoremove --assume-yes \
108-
&& apt-get clean --assume-yes \
109-
&& rm -rf /var/lib/apt/lists/* \
110-
&& rm -rf /tmp/*
111-
112-
# Latest version of fixuid: https://github.com/boxboat/fixuid/releases/latest
113-
ARG FIXUID_VERSION=0.6.0
114-
115-
ARG USER=code
116-
ARG GROUP=code
117-
ARG USER_UID=1000
118-
ARG USER_GID=1000
119-
120-
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
121-
122-
RUN curl -fsSLo /tmp/fixuid.tar.gz "https://github.com/boxboat/fixuid/releases/download/v$FIXUID_VERSION/fixuid-${FIXUID_VERSION}-linux-${TARGETARCH}.tar.gz" \
122+
# Install fixuid
123+
&& curl -fsSLo /tmp/fixuid.tar.gz "https://github.com/boxboat/fixuid/releases/download/v$FIXUID_VERSION/fixuid-${FIXUID_VERSION}-linux-${TARGETARCH}.tar.gz" \
123124
&& tar -xf /tmp/fixuid.tar.gz -C /usr/local/bin fixuid \
124125
&& chown root:root /usr/local/bin/fixuid \
125126
&& chmod 4755 /usr/local/bin/fixuid \
@@ -133,51 +134,53 @@ RUN curl -fsSLo /tmp/fixuid.tar.gz "https://github.com/boxboat/fixuid/releases/d
133134
&& useradd --uid "$USER_UID" --gid "$USER_GID" --create-home "$USER" --shell /bin/bash \
134135
&& mkdir -p \
135136
/etc/fixuid \
136-
"/data" \
137-
"/config" \
138-
"/cache/npm" \
139-
"/cache/node" \
137+
"$XDG_CACHE_HOME/npm" \
138+
"$XDG_CACHE_HOME/node" \
139+
"$XDG_CACHE_HOME/yarn" \
140+
"$XDG_DATA_HOME/pnpm/store" \
141+
"$XDG_DATA_HOME/yarn/berry" \
140142
&& chown -R "$USER_UID":"$USER_GID" \
141-
"/data" \
142-
"/config" \
143-
"/cache" \
143+
"$XDG_DATA_HOME" \
144+
"$XDG_CONFIG_HOME" \
145+
"$XDG_CACHE_HOME" \
146+
# Cleanup
147+
&& apt-get autoremove --assume-yes \
148+
&& apt-get clean --assume-yes \
149+
&& rm -rf /var/lib/apt/lists/* \
150+
&& rm -rf /tmp/* \
144151
&& cat <<EOF > /etc/fixuid/config.yml
145152
user: $USER
146153
group: $existing_group
147154
paths:
148155
- /var/www
149-
- /home/$USER
150-
- /data
151-
- /config
152-
- /cache
156+
- "/home/$USER"
157+
- "$XDG_DATA_HOME"
158+
- "$XDG_CONFIG_HOME"
159+
- "$XDG_CACHE_HOME"
153160
154161
EOF
155162
156-
COPY --from=composer /composer /usr/bin/composer
157-
158-
# Latest version of node: https://hub.docker.com/_/node/tags
159-
FROM {{ getenv "NODE_IMAGE" }} AS node
160-
161-
FROM builder AS builder_nodejs
162-
163-
ARG DEBIAN_FRONTEND=noninteractive
164-
165163
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
166164
ENV npm_config_cache="$XDG_CACHE_HOME/npm"
165+
ENV PNPM_CONFIG_STORE_DIR="$XDG_DATA_HOME/pnpm/store"
167166
168167
COPY --from=node /usr/local/bin/node /usr/local/bin/node
169168
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules
170169
171-
RUN apt-get update \
172-
&& apt-get install --assume-yes --no-install-recommends \
173-
gcc \
174-
g++ \
175-
make \
176-
&& ln -s ../lib/node_modules/corepack/dist/corepack.js /usr/local/bin/corepack \
177-
&& corepack install --global npm@11.x yarn@4.x pnpm@10.x \
170+
# Latest version of corepack: https://www.npmjs.com/package/corepack
171+
ARG COREPACK_VERSION=0.36.0
172+
173+
# Node.js 25+ no longer bundles corepack. npm's bin links are not copied from the node stage, and its cache goes to /tmp
174+
# so no root-owned files end up in npm_config_cache.
175+
RUN node /usr/local/lib/node_modules/npm/bin/npm-cli.js install --global \
176+
--cache /tmp/npm-cache --no-update-notifier --no-audit --no-fund \
177+
"corepack@$COREPACK_VERSION" \
178+
&& corepack install --global npm@12.x yarn@4.x pnpm@12.x \
178179
&& corepack enable npm yarn pnpm \
180+
# pnpm downloads its platform-specific binary on first run
181+
&& pnpm --version \
182+
&& chown -R --reference="$XDG_CACHE_HOME" "$XDG_CACHE_HOME/node" \
179183
# Cleanup
180-
&& apt-get autoremove --assume-yes \
181-
&& apt-get clean --assume-yes \
182-
&& rm -rf /var/lib/apt/lists/* \
183184
&& rm -rf /tmp/*
185+
186+
COPY --from=composer /composer /usr/local/bin/composer

‎README.md‎

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,28 @@ A PHP 7.4 (FPM and Apache) based Docker base image.
1010
# FPM
1111
docker pull ghcr.io/specsnl/php74:latest
1212
docker pull ghcr.io/specsnl/php74/builder:latest
13-
docker pull ghcr.io/specsnl/php74/builder_nodejs:latest
1413
1514
# Apache
1615
docker pull ghcr.io/specsnl/php74/apache:latest
1716
docker pull ghcr.io/specsnl/php74/apache/builder:latest
18-
docker pull ghcr.io/specsnl/php74/apache/builder_nodejs:latest
1917
```
2018

2119
The image name scheme: `ghcr.io/specsnl/php74[/{VARIANT}][/{TARGET}]:{VERSION}`
2220

2321
- **{VARIANT}**: omitted for FPM, otherwise `apache`
24-
- **{TARGET}**: omitted for `runtime`, otherwise `builder` or `builder_nodejs` (also published as `node`)
22+
- **{TARGET}**: omitted for `runtime`, otherwise `builder`
2523
- **{VERSION}**: `latest`, a release tag (i.e. `0.5.5`), `main` or `pr-<number>`
2624

25+
The `builder` image is also published under its old names, `builder_nodejs` and `node`, from the time Node.js had its own
26+
target. These names are deprecated and will be removed ([specsnl/github-actions#76](https://github.com/specsnl/github-actions/issues/76));
27+
use `builder` instead.
28+
2729
## Building the docker image(s)
2830

2931
There are multiple targets:
3032

3133
- **runtime**: this is for *production*. It does not contain any development tools like Composer and Xdebug.
32-
- **builder**: this is for *development*. This is based on the runtime-target and it adds Composer, Xdebug etc.
33-
- **builder_nodejs**: this is for *development*. This is based on the builder-target and it adds NodeJS.
34+
- **builder**: this is for *development*. This is based on the runtime-target and it adds Composer, Xdebug, Node.js etc.
3435

3536
Building `runtime`-target:
3637

@@ -44,37 +45,16 @@ Building `builder`-target:
4445
docker build --tag ghcr.io/specsnl/php74/builder:latest --file fpm/Dockerfile --target builder .
4546
```
4647

47-
Building `builder_nodejs`-target:
48-
49-
```
50-
docker build --tag ghcr.io/specsnl/php74/builder_nodejs:latest --file fpm/Dockerfile --target builder_nodejs .
51-
```
52-
53-
## Debian bullseye is EOL (`DEBIAN_SECURITY_SNAPSHOT`)
48+
## Debian bullseye is EOL
5449

5550
PHP 7.4 images are only published for Debian 11 (bullseye), which is past end-of-life. Its security
56-
suite has stopped being maintained, and the mirrors have moved on in a way that breaks `apt-get`:
57-
58-
- `deb.debian.org` still serves the `bullseye-security` package index, but the `.deb` pool behind it
59-
has been purged — every package download returns a 404.
60-
- `archive.debian.org`, where EOL suites normally end up, does not have `bullseye-security` yet. As
61-
of this writing it only goes up to `buster`.
62-
- The final `Release` file (published 2026-08-31) carries a 7-day `Valid-Until` that has long since
63-
lapsed, so `apt` rejects the repository as expired even where it is reachable.
64-
65-
To still get the last published security updates, the runtime stage rewrites the `bullseye-security`
66-
entry in `/etc/apt/sources.list` to point at [snapshot.debian.org](https://snapshot.debian.org),
67-
which keeps every historical mirror state permanently. The build arg pins which state is used:
68-
69-
```
70-
ARG DEBIAN_SECURITY_SNAPSHOT=20260901T000000Z
71-
```
51+
suite has stopped being maintained, and `deb.debian.org` still serves the `bullseye-security` package
52+
index while the `.deb` pool behind it has been purged — every package download returns a 404.
7253

73-
That timestamp sits just after the final security publish, so the image gets the complete, final set
74-
of bullseye security updates. Because the snapshot is immutable, this does not break when Debian
75-
finishes moving bullseye to `archive.debian.org`. The rewrite also disables `apt`'s freshness check
76-
for that one repository — signatures are still verified, only the "is this recent?" assertion is
77-
skipped, which is unavoidable for a deliberately frozen suite.
54+
To still get the final published security updates, the runtime stage rewrites the `bullseye-security`
55+
entry in `/etc/apt/sources.list` to point at `archive.debian.org`, where Debian keeps EOL suites
56+
permanently. The archived `Release` file carries no `Valid-Until`, so no `apt` freshness override is
57+
needed.
7858

7959
A `grep` guard follows the rewrite so the build fails loudly if the base image ever changes its
8060
`sources.list` format, rather than silently falling back to building without security updates.

0 commit comments

Comments
 (0)