A handful of habits separate a Dockerfile a real production team would accept from one that would get flagged in review:
RUN addgroup -S app && adduser -S app -G app
USER app
latest — node:latest today and node:latest in three months can be completely different images, silently changing your build's behavior (and its vulnerabilities) with no code change on your side. Even better, pin by digest (node:20-alpine@sha256:...) for a build that's byte-for-byte reproducible.ENV or written to a file and later "deleted" is still recoverable from the image's layer history (see the layers section). Use runtime environment injection, a secrets manager, or Docker's --secret build mount instead.