Skip to content

Commit 393cb3d

Browse files
turegjorupclaude
andcommitted
Simplify API Dockerfile, align stage names and section style
Cleanup pass on the API image based on the canonical reference Dockerfile (itk-dev/os2display-api-service@0b2cc18) raised in PR review: - Renamed `client_app_builder` → `assets_builder` to match canonical. - Adopted canonical's section-divider comment block. - Dropped APP_CLIENT_PATH and APP_API_PATH env indirections; literal paths read better and match the FPM convention (/var/www/html). - Dropped the dead APP_RELEASE_TIMESTAMP arg in the assets stage. - Expanded inline comments to document motivation (two-pass composer install, vite manifest ordering, release.json purpose, runtime composer for entrypoint dump-env, Prometheus exporter, ENTRYPOINT vs CMD) — short lines, one fact each. Behaviour unchanged. Smoke build via `sh infrastructure/build.sh` loads working images; resulting API image still ships the PHP_OPCACHE_*/PHP_PM_* tuning and the public/build vite manifest + public/release.json that downstream consumers expect. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 934c8ab commit 393cb3d

1 file changed

Lines changed: 47 additions & 39 deletions

File tree

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,85 @@
1-
######## Clients [Screen|Admin] build ########
2-
FROM node:24-alpine AS client_app_builder
1+
################################
2+
# Assets build
3+
################################
4+
FROM node:24-alpine AS assets_builder
35
LABEL maintainer="ITK Dev <itkdev@ba.aarhus.dk>"
46

57
ARG APP_VERSION="develop"
6-
ARG APP_RELEASE_TIMESTAMP=0
78

8-
ENV APP_CLIENT_PATH=/app
9-
WORKDIR ${APP_CLIENT_PATH}
9+
WORKDIR /app
1010

11-
# Copy only necessary files for npm install
11+
# Lockfile + vite config first so the npm install layer caches across
12+
# unrelated source edits.
1213
COPY --from=repository-root package.json package-lock.json vite.config.js ./
13-
14-
# Install dependencies
1514
RUN npm ci --no-audit --no-fund
1615

17-
# Copy source files needed for build
16+
# Source for `npm run build`. Vite emits to /app/public/build, which the
17+
# api_app_builder stage copies out.
1818
COPY --from=repository-root assets/ ./assets/
1919
COPY --from=repository-root public/client/ ./public/client/
20-
21-
# Build the application with version info
2220
RUN npm run build
2321

2422

25-
######### API backend build ########
23+
################################
24+
# API backend build
25+
################################
26+
# itkdev/php8.4-fpm publishes two parallel series: `2.x.y` (Ubuntu),
27+
# tracked by `:latest`, and `alpine-1.4.x` (Alpine), tracked by
28+
# `:alpine`. `:alpine` is therefore a moving alias to the newest
29+
# `alpine-1.4.x` — convenient, but not reproducible across time.
30+
# TODO: pin to a specific `alpine-1.4.x` tag (or a digest) once we
31+
# settle on a baseline. Same caveat applies to the final stage below.
2632
FROM itkdev/php8.4-fpm:alpine AS api_app_builder
2733
LABEL maintainer="ITK Dev <itkdev@ba.aarhus.dk>"
2834

2935
ARG APP_VERSION="develop"
3036
ARG APP_RELEASE_TIMESTAMP=0
3137
ARG APP_RELEASE_TIME=""
32-
ENV APP_CLIENT_PATH=/app \
33-
APP_API_PATH=/var/www/html
3438

3539
USER root
3640

37-
# Add composer in from the official composer image (also alpine).
41+
# Pinned via the official composer image so the build doesn't depend on
42+
# whatever composer happens to ship in the FPM base.
3843
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
3944

40-
WORKDIR ${APP_API_PATH}
45+
WORKDIR /var/www/html
4146

4247
USER deploy
4348

44-
# Copy only composer files first for better layer caching
45-
COPY --chown=deploy:deploy --from=repository-root composer.json composer.lock symfony.lock ${APP_API_PATH}/
46-
47-
# Pre-install composer packages first (better image layer caching) - application code not present so have to be re-run
49+
# Two-pass composer install:
50+
# 1. Lockfile + composer.json only with --no-scripts. The vendor/ layer
51+
# then survives unrelated source-code edits.
52+
# 2. After the full source COPY, re-run with scripts to finalise the
53+
# autoloader and trigger Symfony's cache:clear hook.
54+
COPY --chown=deploy:deploy --from=repository-root composer.json composer.lock symfony.lock ./
4855
RUN APP_ENV=prod composer install --no-dev -o --classmap-authoritative --no-scripts
4956

50-
# Copy application source (needed for build step)
51-
COPY --chown=deploy:deploy --from=repository-root ./ ${APP_API_PATH}/
57+
COPY --chown=deploy:deploy --from=repository-root ./ ./
5258

53-
# Copy javascript build files. This ensures that vite manifest files are availiable when "composer insatll"
54-
# triggers a "cache:clear" enabling the vite bundle to generate cache configuration files
59+
# Vite manifest must be in place before the second composer install
60+
# triggers cache:clear, otherwise the vite bundle can't generate its
61+
# cache config files.
5562
# @see https://symfony-vite.pentatrion.com/guide/performance.html#caching-configuration-files-%F0%9F%8F%83
56-
COPY --chown=deploy:deploy --from=client_app_builder ${APP_CLIENT_PATH}/public/build ./public/build
63+
COPY --chown=deploy:deploy --from=assets_builder /app/public/build ./public/build
5764

58-
# Re-run composer install after application code copied to image to complete install
5965
RUN APP_ENV=prod composer install --no-dev --optimize-autoloader --classmap-authoritative
6066

61-
# Write release.json into the public root so the client (assets/shared/release-loader.js)
62-
# can fetch it at /release.json. Shape matches docs/release-example.json.
67+
# The client polls /release.json to detect when a screen should refresh;
68+
# shape per docs/release-example.json.
6369
RUN printf '{"releaseTimestamp": %s, "releaseTime": "%s", "releaseVersion": "%s"}\n' \
6470
"${APP_RELEASE_TIMESTAMP}" \
6571
"${APP_RELEASE_TIME}" \
6672
"${APP_VERSION}" \
6773
> public/release.json
6874

6975

70-
######## PHP-FPM (API) production image ########
76+
################################
77+
# PHP-FPM (API) production image
78+
################################
7179
FROM itkdev/php8.4-fpm:alpine
7280
LABEL maintainer="ITK Dev <itkdev@ba.aarhus.dk>"
7381

74-
ENV APP_CLIENT_PATH=/app \
75-
APP_API_PATH=/var/www/html \
76-
APP_ENV=prod \
82+
ENV APP_ENV=prod \
7783
PHP_OPCACHE_ENABLED=1 \
7884
PHP_OPCACHE_VALIDATE_TIMESTAMPS=0 \
7985
PHP_OPCACHE_MAX_ACCELERATED_FILES=20000 \
@@ -87,23 +93,25 @@ ENV APP_CLIENT_PATH=/app \
8793

8894
USER root
8995

90-
# Add composer needed to run optimizations after config is loaded.
96+
# Needed at container start so the entrypoint can run
97+
# `composer dump-env prod` against the operator's runtime env.
9198
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
9299

93-
# Download Prometheus php-fpm export.
100+
# Prometheus exporter for php-fpm pool stats; scraped by ops monitoring.
94101
COPY --from=hipages/php-fpm_exporter:2.2.0 /php-fpm_exporter /usr/local/bin/php-fpm_exporter
95102

96103
COPY --chmod=0755 docker-entrypoint.sh /usr/local/bin/
97104

98105
USER deploy
99106

100-
WORKDIR ${APP_API_PATH}
107+
WORKDIR /var/www/html
101108

102-
# Install the api application.
103-
COPY --chown=deploy:deploy --from=api_app_builder ${APP_API_PATH} .
104-
RUN mkdir -p ./config/secrets
109+
COPY --chown=deploy:deploy --from=api_app_builder /var/www/html .
105110

106-
WORKDIR ${APP_API_PATH}
111+
# Mount point for the Symfony secrets vault.
112+
RUN mkdir -p ./config/secrets
107113

114+
# Entrypoint compiles env vars to .env.local.php and warms the Symfony
115+
# cache before exec'ing CMD; CMD stays overridable for ad-hoc commands.
108116
ENTRYPOINT ["docker-entrypoint.sh"]
109117
CMD ["php-fpm"]

0 commit comments

Comments
 (0)