Running as a non-root user in the image

A container defaults to root, and root in the container is root on the host for anything mounted — so a build script that deletes a directory can delete the host’s copy of it.

RUN groupadd -g 1000 app && useradd -u 1000 -g app -m app

COPY --chown=app:app . /app
WORKDIR /app
USER app

CMD ["php-fpm", "-F"]

The --chown flag on COPY avoids a second layer doing a recursive chown, which on a large tree doubles the image size because the layer records every changed file. Switching user before CMD rather than at the top means the package installation earlier in the file still works. Anything binding to a port below 1024 needs to stay root or use a capability, which is one reason nginx images do the switch after the listen directive is already configured.